Monday, January 19, 2015

Java ESL Client for Freeswitch

Here is a Freeswitch ESL Client.
The following jars are needed
  • hamcrest-all-1.1.jar
  • netty-3.6.3.Final.jar
  • org.freeswitch.esl.client-0.9.2.jar
Cepstral is required in the PATH (tested on Windows 7)
PATH=%PATH%:c:\program files\Cepstral\bin
In modules.conf.xml enable mod_cepstral
<load module="mod_cepstral"/>
 
conf/lang/en/en.xml has to be enabled for Cepstral
<include>
  <language name="en" say-module="en" sound-prefix="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
    <phrases>
      <macros>
   <macro name="speak">
     <input pattern="(.*)" />
       <match>
         <action data="$1" function="speak-text">
       </action></match>
     
   </macro>
        <x-pre-process cmd="include" data="demo/*.xml"> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
        <!-- voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
        <x-pre-process cmd="include" data="vm/sounds.xml"> <!-- vm/tts.xml if you want to use tts and have cepstral -->
        <x-pre-process cmd="include" data="dir/sounds.xml"> <!-- dir/tts.xml if you want to use tts and have cepstral -->
        <x-pre-process cmd="include" data="ivr/*.xml">  <!-- IVR and custom phrases go here -->
      </x-pre-process></x-pre-process></x-pre-process></x-pre-process></macros>
      <x-pre-process cmd="include" data="vm/voicemail_ivr.xml">
    </x-pre-process></phrases>
  </language>
</include>


package net.freeswitch;


/*
 * Copyright 2010 david varnes.
 *
 * Licensed under the Apache License, version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

import xxx.net.domain.AccountPending;
import xxx.net.util.HibernateUtil;

import org.apache.log4j.Logger;
import org.freeswitch.esl.client.IEslEventListener;
import org.freeswitch.esl.client.inbound.Client;
import org.freeswitch.esl.client.inbound.InboundConnectionFailure;
import org.freeswitch.esl.client.transport.CommandResponse;
import org.freeswitch.esl.client.transport.SendMsg;
import org.freeswitch.esl.client.transport.event.EslEvent;
import org.freeswitch.esl.client.transport.message.EslHeaders.Name;
import org.freeswitch.esl.client.transport.message.EslMessage;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class SignupCall
{
 //use properties
 //filter by events
    public static Logger log = Logger.getLogger(SignupCall.class);
    private String host = "127.0.0.1";
    private int port = 8021;
    private String password = "ClueCon"; 
    private String digits="";   
    private Long id;
    public SignupCall(Long id) {
     this.id = id;
    }
    public void do_connect(final Long id, final String number) throws InterruptedException
    {
     
     Client client = new Client();
        
        
        log.info( "Client connecting .." );
        try
        {
            client.connect( host, port, password, 20 );
        }
        catch ( InboundConnectionFailure e )
        {
            log.info( "Connect failed" );
            return;
        }
        log.info( "Client connected .." );
        
        client.addEventListener( new IEslEventListener()
        {
            public void eventReceived( EslEvent event )
            {
                log.info( "Event received [{}]" + event );
                String digit = getDTMFDigit(event);
                if (digit == null) {
                 return;
                }
                digits += digit;
                if (digits.length() == 2){
                 Session session = HibernateUtil.getCurrentSession();
                 AccountPending ap = (AccountPending)session.get(AccountPending.class, id);
                 log.info("checking digits <" + digits + ">" + " tncode=" + ap.getTnCode());
                 if (digits.trim().equals(ap.getTnCode().toString())) {
                  log.info("verified");
                  ap.setTnCodeVerified(true);
                  Transaction tran = session.beginTransaction();
                  session.update(ap);
                  tran.commit();
                 } else {
                  //reset digits
                  log.info("resetting digits");
                  digits="";
                 }
                }
            }
            public void backgroundJobResultReceived( EslEvent event )
            {
                log.info( "Background job result received [{}]" + event );
            }
            
        } );       
     String uuid=UUID.randomUUID().toString();
     EslMessage resp=client.sendSyncApiCommand("originate ", "{origination_uuid=" + uuid + "}sofia/gateway/mygateway/OUTBOUND+1" + number +" 1004 park" );
     log.info( "Response to 'park1': [{}]" + resp );
        for ( Entry header : resp.getHeaders().entrySet() )
        {
            log.info( " * header [{}]" + header );
        }
        for ( String bodyLine : resp.getBodyLines() )
        {
            log.info( " * body [{}]" + bodyLine );
        }
        client.setEventSubscriptions( "plain", "DTMF" );
        client.addEventFilter( "Event-Name", "DTMF" );
        int i=0;
        SendMsg playMsg=null;
        while(i++ < 2) {
         //we loop until the user punches the code
         playMsg = new SendMsg(uuid);
         playMsg.addCallCommand( "execute" );
         playMsg.addExecuteAppName( "speak" );
         playMsg.addExecuteAppArg("cepstral|callie|Please enter the digits seen on the screen");
         CommandResponse cmdresp = client.sendMessage(playMsg);
        }
         
        int attempts=0;
        while(!isCodeVerified()) {
         
         Thread.sleep( 10000 );
         if (++attempts > 5) {
          log.info("hanging up");
          hangup(client, uuid);
          client.close();
          return;
         }
        }
        resp=client.sendSyncApiCommand("uuid_break ", uuid);//stop playing the messages
        playMsg = new SendMsg(uuid);
        playMsg.addCallCommand( "execute" );
        playMsg.addExecuteAppName( "speak" );
        playMsg.addExecuteAppArg("cepstral|callie|Congratulations");
        CommandResponse cmdresp2 = client.sendMessage(playMsg);
        Thread.sleep( 20000 );//give time to play the congrats message
        hangup(client, uuid);
        client.close();
        
    }

    public String getDTMFDigit(EslEvent event) {
     Set s=event.getEventHeaders().entrySet();
        Iterator it=s.iterator();
        while(it.hasNext())
        {
            Map.Entry m =(Map.Entry)it.next();
            String key=(String)m.getKey();
            String value=(String)m.getValue();
    if (key.equals("DTMF-Digit")) {
    log.info("You pressed " + value);
    return value;
    }
        }
        return null;
   }
   private Boolean isCodeVerified() {
       Session session = HibernateUtil.getCurrentSession();
       session.close();
       session = HibernateUtil.getCurrentSession();
       AccountPending ap = (AccountPending)session.load(AccountPending.class, id);
       log.info(" tncode=" + ap.getTnCode());
       return ap.getTnCodeVerified();
   }
   private void hangup(Client client, String uuid) {
       SendMsg hangupMsg = new SendMsg(uuid);
       hangupMsg.addCallCommand( "execute" );
       hangupMsg.addExecuteAppName( "hangup" );
       
       CommandResponse response = client.sendMessage(hangupMsg);
       
   }
}

No comments:

Post a Comment