Skip to main content

Javascript Example - Intercom

About

Add intercom recipients to a conference bridge.This script works by originating a channel to each of your Intercom recipients. The call will be auto-answered by default, but you may specify it to ring in case you are dealing with older or non-sip intercom equipment (or a mixed environment like myself). Once all of the recipients have answered or rejected the call they are added to a conference via a transfer command. Once this has been completed the initiator will be connected to the conference as well. All legs are dropped when the initiator hangs up.

Example Code

intercom.js example Expand source

// Main
var script_major_version = 0;
var script_minor_version = 8;
var script_name = "Intercom";
console_log("notice", script_name+" v"+script_major_version+"."+script_minor_version+"\n");

var intercom_answered = 0;
var recipient_data = argv[0];
var transfer_command = argv[1];
var conference_command = argv[2];

var domain_name = session.getVariable("domain_name");
var originate_options = "ignore_early_media=true";

// exit now if we werent passed what we need
if(!recipient_data || !transfer_command || !conference_command)
{
console_log("warning", "Improper call to "+script_name+" v"+script_major_version+"."+script_minor_version+"\n");
exit();
}


// enumerate users and autodial options
var arr_rlist = new Array();
var arr_rvars = new Array();
var recipients = new Array();
var autoanswer = new Array();

// create our recipient list ... splitting by , then ;
arr_rlist = recipient_data.split(",");
for(i in arr_rlist)
{
if(!arr_rlist[i]) continue;
arr_rvars = arr_rlist[i].split(":");

recipients[i] = arr_rvars[0];
autoanswer[i] = arr_rvars[1];
if(autoanswer[i] != "false") autoanswer[i] = "true";
}


// answer the call if we can, exit if we cant
if(session.ready()) session.answer();
else exit();

pageSessions = new Array();
for(i in recipients)
{
console_log("debug", "Originating: "+recipients[i]+"\n");


session.execute("export", "sip_auto_answer="+autoanswer[i]);
if(autoanswer[i] == "true")
{
session.execute("export", "sip_invite_params=intercom=true");
session.execute("export", "sip_h_Call-Info=<sip:"+domain_name+">;answer-after=0");
}

// if we originate via the Session() constructor, our exported intercom options will not be passed along
// so we construct an empty session and originate via the method
pageSessions[i] = new Session();
//pageSessions[i].setCallerData("caller_id_name", "Intercom Page") <== WRONG
originate_options = originate_options + ",caller_id_name=Intercom Page";
pageSessions[i].originate(session, "{"+originate_options+"}user/"+recipients[i]);

}


for(i in recipients)
{
console_log("debug", "Conferencing: "+recipients[i]+"\n");

// if the session is not ready, send a notice and do not transfer to the conference
if(!pageSessions[i].ready())
{
console_log("notice", recipients[i]+" not ready: "+pageSessions[i].cause+"\n");
}
else
{
// transfer instead of conferencing, since transfer is a nonblocking call
pageSessions[i].execute("transfer", transfer_command);
intercom_answered++;
}
}
console_log("debug", intercom_answered+" recipients answered our page\n");


// send ourselves to the conference if someone is waiting for us
// otherwise send a warning that the pager might not be working
if(intercom_answered)
{
session.execute("conference", conference_command);
}
else
{
console_log("warning", "Intercom page reached no recipients\n");
// stream a sound file if desired here
}


// done :)
console_log("notice", "Intercom page completed");
exit();


The above script can be invoked with the following syntax:

<action application="javascript" data="Intercom.js 'sofia_address1[:auto_answer][,sofia_address2:[auto_answer][,...]]' 'transfer_command' 'conference_command'"/>
  • sofia_addressX are the recipients of the intercom page and can take any format accepted by originate (eg. 'user/101@mydomain')
  • auto_answer: true or false. Determines whether this address will be auto answered by the recipient
  • transfer_command: the data string passed to transfer. This is used on recipients after they have answered the page
  • conference command: the data string passed to conference. This is used on the initiator after all recipients have been conferenced

Below is the relevant section of my dialplan:

Dialplan example for intercom.js

<extension name="Example Intercom">
<condition field="destination_number" expression="^150$" break="never">
<action application="javascript" data="Intercom.js '101@${domain_name},117@${domain_name},150@${domain_name}:false' '9150 XML default' '150@default'"/>
</condition>
</extension>

<extension name="Example Intercom Conference">
<condition field="destination_number" expression="^9150$" break="never">
<action application="conference" data="150@default+flags{mute}"/>
</condition>
</extension>

Extension 150 is my intercom page extension. 9150 is the extension to which paged recipients are directed. 150 is set to false on auto_answer as it is an intercom connected to a legacy device connected to a Sipura 2102 ATA (thus it must ring so the device can pick up). 101 and 117 are Polycom Soundpoint IP phones with reg.x.callsPerLineKey="1". This means that call-waiting is disabled on their pager lines, so incoming pages don't put their current caller on hold.

Feedback for additional phones would be great! Currently tested on:

  • Polycom Soundpoint IP 320/330 and 550/650
  • Linksys/Sipura SPA2102 ATA