Javascript IVR example
From Yate Documentation
(Difference between revisions)
(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== |
| − | + | /* | |
| − | + | * Network-In-a-Box demo | |
| − | + | * To use it put in javascript.conf: | |
| − | + | * | |
| − | + | * [general] | |
| − | + | * routing=welcome.js | |
| − | + | */ | |
| − | + | ||
| − | + | function getPathPrompt(pprompt) | |
| − | + | { | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | function getPathPrompt(pprompt) | + | |
| − | { | + | |
if (prompts_dir!="" && File.exists(prompts_dir+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/"]; | var dirs = ["/usr/share/yate/sounds/", "/usr/local/share/yate/sounds/", "/var/spool/yatebts/"]; | ||
| − | for (var | + | for (var dir of dirs) |
| − | + | if (File.exists(dir+pprompt)) { | |
| − | + | prompts_dir = dir; | |
| − | + | 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:090@192.168.1.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 | |
| − | + | // Otherwise users can continue changing between states | |
| − | + | return; | |
| − | + | ||
if (timeout_started==true) { | 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) { | if(msg.text == 1) { | ||
| − | + | state = "echoTest"; | |
| − | + | playEchoPrompt(); | |
} else if (msg.text == 2) { | } else if (msg.text == 2) { | ||
| − | + | state = "conf"; | |
| − | + | sendToConference() | |
} else if (msg.text == 3) { | } else if (msg.text == 3) { | ||
| − | + | state = "call"; | |
| − | + | 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 | |
| − | + | // 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+"'"); | Engine.debug(Engine.DebugInfo,"Returned to main function in state '"+state+"'"); | ||
if (state == "echoTest") { | if (state == "echoTest") { | ||
| − | + | startEchoTest(); | |
| − | + | return; | |
} | } | ||
| − | } | + | } |
| + | |||
| + | state = ""; | ||
| + | timeout_started = false; | ||
| + | prompts_dir = ""; | ||
| + | |||
| + | Engine.debugName("welcome"); | ||
| + | |||
| + | if (message.called=="32843") | ||
| + | welcomeIVR(message); | ||
| − | |||
| − | |||
| − | |||
| − | + | [[Category:Javascript]] [[Category:IVR]] | |
| − | + | ||
| − | + | ||
| − | + | ||
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);