Javascript IVR example

From Yate Documentation
(Difference between revisions)
Jump to: navigation, search
(Created page with " ==Code== /** * welcome.js * This file is part of the Yate-BTS Project http://www.yatebts.com * * Copyright (C) 2014 Null Team * * This software is distributed under mu...")
 
(Code: Yate svn rev.5791)
 
(11 intermediate revisions by one user not shown)
Line 1: Line 1:
 +
Here are two IVR examples in Javascript. After the changes in svn rev. 5791 you can build IVRs a lot easier. Main changes are:
 +
* you can use Channel object from function called on message handlers
 +
* callTo and callJust methods for Channel object support a second parameter: object with parameters to be added to call.execute message
 +
** Example: Channel.callTo("wave/record/-",{"maxlen":180000});  Channel.callJust("conf/333",{"lonely":true});
  
==Code==
+
==Code: starting with svn rev. 5791==
  
/**
+
  /*
  * welcome.js
+
  * Network-In-a-Box demo
* This file is part of the Yate-BTS Project http://www.yatebts.com
+
  * To use it put in javascript.conf:
*
+
  *
* Copyright (C) 2014 Null Team
+
  * [general]
*
+
  * routing=welcome.js
* This software is distributed under multiple licenses;
+
  */
* see the COPYING file in the main directory for licensing
+
* information for this specific distribution.
+
function getPathPrompt(pprompt)
*
+
{
* This use of this software may be subject to additional restrictions.
+
* See the LEGAL file in the main directory for details.
+
*
+
* This program is distributed in the hope that it will be useful,
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
*/
+
 
+
/*
+
* Network-In-a-Box demo
+
* To use it put in javascript.conf:
+
*
+
* [general]
+
* routing=welcome.js
+
*/
+
 
+
function getPathPrompt(pprompt)
+
{
+
 
     if (prompts_dir!="" && File.exists(prompts_dir+pprompt))
 
     if (prompts_dir!="" && File.exists(prompts_dir+pprompt))
return prompts_dir+pprompt;
+
return prompts_dir+pprompt;
 
+
 
     var dirs = ["/usr/share/yate/sounds/", "/usr/local/share/yate/sounds/", "/var/spool/yatebts/"];
 
     var dirs = ["/usr/share/yate/sounds/", "/usr/local/share/yate/sounds/", "/var/spool/yatebts/"];
     for (var i=0; i<dirs.length; i++) {
+
     for (var dir of dirs)
if (File.exists(dirs[i]+pprompt)) {
+
if (File.exists(dir+pprompt)) {
    prompts_dir = dirs[i];
+
    prompts_dir = dir;
    return prompts_dir+pprompt;
+
    return prompts_dir+pprompt;
}
+
}
    }
+
 
      
 
      
 
     //this should not happen
 
     //this should not happen
 
     Engine.debug(Debug.Warn,"Don't have path for prompt "+pprompt);
 
     Engine.debug(Debug.Warn,"Don't have path for prompt "+pprompt);
 
     return false;
 
     return false;
}
+
}
 +
 +
function onChanDtmf(msg)
 +
{
 +
    if(msg.text == 1) {
 +
state = "echoTest";
 +
Channel.callTo("wave/play/"+getPathPrompt("echo.au"));
 +
    }
 +
 +
    else if (msg.text == 2)
 +
Channel.callJust("conf/333",{"lonely":true});
 +
 +
    else if (msg.text == 3)
 +
Channel.callJust("iax/iax:090@192.168.1.1/090",{"caller":"yatebts"});
 +
}
 +
 +
function welcomeIVR(msg)
 +
{
 +
    Engine.debug(Engine.DebugInfo,"Got call to welcome IVR.");
 +
 +
    Message.install(onChanDtmf, "chan.dtmf", 90, "id", msg.id);
 +
    Channel.callTo("wave/play/"+getPathPrompt("welcome.au"));
 +
 +
    if (state == "")
 +
// No digit was pressed
 +
// Wait aprox 10 seconds to see if digit is pressed
 +
Channel.callTo("wave/record/-",{"maxlen":180000});
 +
 +
    Engine.debug(Engine.DebugInfo,"Returned to main function in state '"+state+"'");
 +
    if (state == "echoTest")
 +
Channel.callJust("external/playrec/echo.sh");
 +
}
 +
 +
state = "";
 +
prompts_dir = "";
 +
 +
Engine.debugName("welcome");
 +
 +
if (message.called=="32843")
 +
    welcomeIVR(message);
 +
 
 +
==Code: Yate svn rev.5791  ==
  
function sendToConference()
+
This is an older option (before svn rev. 5791) to implements the same functionality.
{
+
 
 +
/*
 +
  * Network-In-a-Box demo
 +
  * To use it put in javascript.conf:
 +
  *
 +
  * [general]
 +
  * routing=welcome.js
 +
  */
 +
 +
function getPathPrompt(pprompt)
 +
{
 +
  // same as above chapter
 +
}
 +
 +
function sendToConference()
 +
{
 
     var m = new Message("chan.masquerade");
 
     var m = new Message("chan.masquerade");
 
     m.message = "call.execute";
 
     m.message = "call.execute";
Line 54: Line 95:
 
     m.lonely = true;
 
     m.lonely = true;
 
     m.dispatch();
 
     m.dispatch();
}
+
}
 
+
function makeCall()
+
function makeCall()
{
+
{
 
     var m = new Message("chan.masquerade");
 
     var m = new Message("chan.masquerade");
 
     m.message = "call.execute";
 
     m.message = "call.execute";
 
     m.id = partycallid;
 
     m.id = partycallid;
     m.callto = "iax/iax:32843@83.166.206.79/32843";
+
     m.callto = "iax/iax:090@192.168.1.1/090";
    //m.callto = "iax/iax:090@192.168.168.1/090";
+
 
     m.caller = partycaller;
 
     m.caller = partycaller;
 
     m.dispatch();   
 
     m.dispatch();   
}
+
}
 
+
function startEchoTest()
+
function startEchoTest()
{
+
{
 
     var m = new Message("chan.masquerade");
 
     var m = new Message("chan.masquerade");
 
     m.message = "call.execute";
 
     m.message = "call.execute";
Line 75: Line 115:
 
     m.timeout = 0;
 
     m.timeout = 0;
 
     m.dispatch();
 
     m.dispatch();
}
+
}
 
+
function playEchoPrompt()
+
function playEchoPrompt()
{
+
{
 
     var m = new Message("chan.masquerade");
 
     var m = new Message("chan.masquerade");
 
     m.message = "call.execute";
 
     m.message = "call.execute";
Line 84: Line 124:
 
     m.callto = "wave/play/"+getPathPrompt("echo.au");
 
     m.callto = "wave/play/"+getPathPrompt("echo.au");
 
     m.dispatch();
 
     m.dispatch();
}
+
}
 
+
function onChanDtmf(msg)
+
function onChanDtmf(msg)
{
+
{
 
     Engine.debug(Engine.DebugInfo,"Got dtmf "+msg.text+" for "+partycallid+" in state='"+state+"'");
 
     Engine.debug(Engine.DebugInfo,"Got dtmf "+msg.text+" for "+partycallid+" in state='"+state+"'");
 
     if (state != "")
 
     if (state != "")
// Ignore dtmfs after state changed
+
// Ignore dtmfs after state changed
// Otherwise users can continue changing between states
+
// Otherwise users can continue changing between states
return;
+
return;
 
+
 
     if (timeout_started==true) {
 
     if (timeout_started==true) {
// reset timeout if it was started
+
// reset timeout if it was started
var m = new Message("chan.control");
+
var m = new Message("chan.control");
m.targetid = partycallid;
+
m.targetid = partycallid;
m.timeout = 0;
+
m.timeout = 0;
m.dispatch();
+
m.dispatch();
 
     }
 
     }
 
+
 
     if(msg.text == 1) {
 
     if(msg.text == 1) {
state = "echoTest";
+
state = "echoTest";
playEchoPrompt();
+
playEchoPrompt();
 
     } else if (msg.text == 2) {
 
     } else if (msg.text == 2) {
state = "conf";
+
state = "conf";
sendToConference()
+
sendToConference()
 
     } else if (msg.text == 3) {
 
     } else if (msg.text == 3) {
state = "call";
+
state = "call";
makeCall();
+
makeCall();
 
     }
 
     }
}
+
}
 
+
function welcomeIVR(msg)
+
function welcomeIVR(msg)
{
+
{
 
     Engine.debug(Engine.DebugInfo,"Got call to welcome IVR.");
 
     Engine.debug(Engine.DebugInfo,"Got call to welcome IVR.");
 
     partycallid = msg.id;
 
     partycallid = msg.id;
 
     partycaller = "yatebts";
 
     partycaller = "yatebts";
 
+
 
     Message.install(onChanDtmf, "chan.dtmf", 90, "id", msg.id);
 
     Message.install(onChanDtmf, "chan.dtmf", 90, "id", msg.id);
 
     Channel.callTo("wave/play/"+getPathPrompt("welcome.au"));
 
     Channel.callTo("wave/play/"+getPathPrompt("welcome.au"));
 
+
 
     if (state == "") {
 
     if (state == "") {
// No digit was pressed
+
// No digit was pressed
// Wait for 10 seconds to see if digit is pressed
+
// Wait for 10 seconds to see if digit is pressed
var m = new Message("chan.control");
+
var m = new Message("chan.control");
m.targetid = partycallid;
+
m.targetid = partycallid;
m.timeout = 10000;
+
m.timeout = 10000;
m.dispatch();
+
m.dispatch();
timeout_started = true;
+
timeout_started = true;
 
+
Channel.callTo("wave/record/-");
+
Channel.callTo("wave/record/-");
 
     }
 
     }
 
+
 
     Engine.debug(Engine.DebugInfo,"Returned to main function in state '"+state+"'");
 
     Engine.debug(Engine.DebugInfo,"Returned to main function in state '"+state+"'");
 
     if (state == "echoTest") {
 
     if (state == "echoTest") {
startEchoTest();
+
startEchoTest();
return;
+
return;
 
     }
 
     }
}
+
}
 +
 +
state = "";
 +
timeout_started = false;
 +
prompts_dir = "";
 +
 +
Engine.debugName("welcome");
 +
 +
if (message.called=="32843")
 +
    welcomeIVR(message);
  
state = "";
 
timeout_started = false;
 
prompts_dir = "";
 
  
Engine.debugName("welcome");
+
[[Category:Javascript]] [[Category:IVR]]
// 32843 -> david
+
if (message.called=="32843")
+
    welcomeIVR(message);
+

Latest revision as of 18:05, 27 February 2014

Here are two IVR examples in Javascript. After the changes in svn rev. 5791 you can build IVRs a lot easier. Main changes are:

  • you can use Channel object from function called on message handlers
  • callTo and callJust methods for Channel object support a second parameter: object with parameters to be added to call.execute message
    • Example: Channel.callTo("wave/record/-",{"maxlen":180000}); Channel.callJust("conf/333",{"lonely":true});

[edit] Code: starting with svn rev. 5791

/*
 * Network-In-a-Box demo
 * To use it put in javascript.conf:
 *
 * [general]
 * routing=welcome.js
 */

function getPathPrompt(pprompt)
{
   if (prompts_dir!="" && File.exists(prompts_dir+pprompt))
	return prompts_dir+pprompt;

   var dirs = ["/usr/share/yate/sounds/", "/usr/local/share/yate/sounds/", "/var/spool/yatebts/"];
   for (var dir of dirs)
	if (File.exists(dir+pprompt)) {
	    prompts_dir = dir;
	    return prompts_dir+pprompt;
	}
   
   //this should not happen
   Engine.debug(Debug.Warn,"Don't have path for prompt "+pprompt);
   return false;
}

function onChanDtmf(msg)
{
   if(msg.text == 1) {
	state = "echoTest";
	Channel.callTo("wave/play/"+getPathPrompt("echo.au"));
   }

   else if (msg.text == 2) 
	Channel.callJust("conf/333",{"lonely":true});

   else if (msg.text == 3)
	Channel.callJust("iax/iax:090@192.168.1.1/090",{"caller":"yatebts"});
}

function welcomeIVR(msg)
{
   Engine.debug(Engine.DebugInfo,"Got call to welcome IVR.");

   Message.install(onChanDtmf, "chan.dtmf", 90, "id", msg.id);
   Channel.callTo("wave/play/"+getPathPrompt("welcome.au"));

   if (state == "")
	// No digit was pressed
	// Wait aprox 10 seconds to see if digit is pressed
	Channel.callTo("wave/record/-",{"maxlen":180000});

   Engine.debug(Engine.DebugInfo,"Returned to main function in state '"+state+"'");
   if (state == "echoTest")
	Channel.callJust("external/playrec/echo.sh");
}

state = "";
prompts_dir = "";

Engine.debugName("welcome");

if (message.called=="32843")
   welcomeIVR(message);

[edit] Code: Yate svn rev.5791

This is an older option (before svn rev. 5791) to implements the same functionality.

/*
 * Network-In-a-Box demo
 * To use it put in javascript.conf:
 *
 * [general]
 * routing=welcome.js
 */

function getPathPrompt(pprompt)
{
  // same as above chapter
}

function sendToConference()
{
   var m = new Message("chan.masquerade");
   m.message = "call.execute";
   m.id = partycallid;
   m.callto = "conf/333";
   m.lonely = true;
   m.dispatch();
}

function makeCall()
{
   var m = new Message("chan.masquerade");
   m.message = "call.execute";
   m.id = partycallid;
   m.callto = "iax/iax:090@192.168.1.1/090";
   m.caller = partycaller;
   m.dispatch();  
}

function startEchoTest()
{
   var m = new Message("chan.masquerade");
   m.message = "call.execute";
   m.id = partycallid;
   m.callto = "external/playrec/echo.sh";
   m.timeout = 0;
   m.dispatch();
}

function playEchoPrompt()
{
   var m = new Message("chan.masquerade");
   m.message = "call.execute";
   m.id = partycallid;
   m.callto = "wave/play/"+getPathPrompt("echo.au");
   m.dispatch();
}

function onChanDtmf(msg)
{
   Engine.debug(Engine.DebugInfo,"Got dtmf "+msg.text+" for "+partycallid+" in state='"+state+"'");
   if (state != "")
	// Ignore dtmfs after state changed
	// Otherwise users can continue changing between states
	return;

   if (timeout_started==true) {
	// reset timeout if it was started
	var m = new Message("chan.control");
	m.targetid = partycallid;
	m.timeout = 0;
	m.dispatch();
   }

   if(msg.text == 1) {
	state = "echoTest";
	playEchoPrompt();
   } else if (msg.text == 2) {
	state = "conf";
	sendToConference()
   } else if (msg.text == 3) {
	state = "call";
	makeCall();
   }
}

function welcomeIVR(msg)
{
   Engine.debug(Engine.DebugInfo,"Got call to welcome IVR.");
   partycallid = msg.id;
   partycaller = "yatebts";

   Message.install(onChanDtmf, "chan.dtmf", 90, "id", msg.id);
   Channel.callTo("wave/play/"+getPathPrompt("welcome.au"));

   if (state == "") {
	// No digit was pressed
	// Wait for 10 seconds to see if digit is pressed
	var m = new Message("chan.control");
	m.targetid = partycallid;
	m.timeout = 10000;
	m.dispatch();
	timeout_started = true;

	Channel.callTo("wave/record/-");
   }

   Engine.debug(Engine.DebugInfo,"Returned to main function in state '"+state+"'");
   if (state == "echoTest") {
	startEchoTest();
	return;
   }
}

state = "";
timeout_started = false;
prompts_dir = "";

Engine.debugName("welcome");

if (message.called=="32843")
   welcomeIVR(message);
Personal tools
Namespaces

Variants
Actions
Preface
Configuration
Administrators
Developers