JavaScript
Built-in JavaScript libraries
Commands
CALL – call controls
call.play()
call.say()
say a text via English speach synthesis
call.say(“Welcome to our support center!”);
call.sayPL()
say a text via Polish speach synthesis
call.sayPL(“Witaj świecie!”);
call.getCallerId()
return a telephone number of a calling person
call.debug(string)
log a string to a console
call.debug('new call from ' + callGetCallerId());
call.getCallUUID()
return a unique identifier of an incoming call (UUID)
call.setMusicOnHold(url)
call.hangup()
cause immediate hang up
call.ask(object)
get output from caller’s phone keyboard Object parameters:
- timeout – a number of seconds to wait for input
- say – a text to be spoken in English
- sayPL – a text to be spoken in Polis
- play – sound (a link to a wav file) to be played
- limit – a number of keys pressed to wait for
- terminator – a key for terminating a keyboard input before a limit is reached (* or #, optional)
data = call.ask({
timeout: 10,
limit: 3,
sayPL: 'please enter three numbers',
terminator: '#'
});
data2 = call.ask({
say: 'please enter a number'
limit: 1
});
call.menu(object)
Telephone menu Object parameters:
- tries – maximum number of tries (default: 3)
- timeout – time to wait for a key to be pressed (default: 8 seconds)
- allowed – array of allowed keys
- say – announcement (English voice synthesis)
- sayPL – announcement (Polish voice synthesis)
- play – sound (a link to a wav file) to be played
call.dialLocalAgent(login)
connect directly to an Agent. It doesn't support recording, callbacks, etc. Designed mainly for testing purposes, as it doesn't collect any statistics nor records calls.
call.dialLocalAgent('outrageous-snowflake-7057');
call.dialRemoteNumber(number)
redirect calls to an external number. Designed mainly for testing purposes, as it doesn't collect any statistics nor records calls.
call.dialRemoteNumber('48123456789');
call.dialRemoteNumber('sip:name@cloud.restcomm.com');
A number has to be given with international dialing code, e.g. 442012345678 for the UK or be a Restcomm user address.
call.huntGroup()
connects to a hunt-group
- name – a hunt-group’s name
- ann – (optional) a language to be used to announce what is the calling person’s position in a queue (empty – no announcements at all)
- acd – (optional) approximate time of a single call; used for announcements about a queue position
- vip – (optional, true/false) – if true, a calling person is placed first in a queue
- msg – (optional) – a message to send via SIP INFO just after answering a phone call by your Agent
- limit_time (optional) – a minimum time in seconds to wait before leaving a queue and proceeding further
- hangup_after_success (optional) – hang up an incoming call after talking with your Agent
call.huntGroup({
name: "support",
ann: 'en',
acd: 5,
});
var vip = false
var callerid = call.getCallerId();
if (/123456789/.test(callerid)) {
vip = true
}
call.huntGroup({
name: 'support',
vip: vip
})
If a telephone line has a configured Amazon S3 account, all calls are automatically recorded.
call.voicemail(email)
Records voicemail and sends it to given email address.
Using external JS libraries
var data = http.get('https://cdnjs.cloudflare.com/ajax/libs/randomcolor/0.4.4/randomColor.min.js')
eval(data.body);
call.debug(randomColor());
HTTP – HTTP client
http.get/post/put/delete()
data = http.get('http://example.com/data.json')
data = http.get('http://example.com/user', {
params: {
login: 'adam'
}});
data = http.post('http://example.com/abc', {
params: {
name: 'abc',
age: 44
}
});
var myJson = {
'field_1': 'Hello',
'field_3': 'World'
}
data = http.post('https://api.knackhq.com/v1/objects/object_1/records', {
headers: {
'X-Knack-Application-Id': '57855a2a48cxxxxxxxxxxx',
'X-Knack-REST-API-Key': '11a103f0-xxxx-11e6-9726-xxxxxxxxxxxxx'
},
body: myJson
});
XMLHttpRequest - emulation
In order to allow you to employ ready-to-use JS libraries, there is an XMLHttpRequest object available which is compatible with its equivalent from Internet browsers.
var req = new XMLHttpRequest();
req.open('GET', 'http://www.mozilla.org/', false);
req.send(null);
call.debug(req.status);
call.debug(req.responseText);
var req2 = new XMLHttpRequest();
req2.open('POST', 'https://example.com/api.php', false);
req2.setRequestHeader('X-Foo', 'bar');
req2.send('param1=test¶m2=test2');
call.debug(req2.status);
call.debug(req2.responseText);
Global Variables – a local database key-value
db.set(key, value)
set a key from a local database
db.incr(key)
atomically increase a key in a database by 1 (a key has to be integer)
db.decr(key)
atomically decrease a key in a database by 1 (a key has to be integer)
db.del(key)
delete a key from a local database
Dynamic announcements (only for Polish speech synthesis)
If a key starts with “tts_”, its value may be used in a conversation plan in statements like sayPL and similar. It’s useful when you want to change an announcement without changing your code. For example, you can set a key “tts_announcement” to “Welcome to our support department!” using GUI – and use it in your code:
call.sayPL(db.get('tts_announcement'));
ASYNC – sending text messages and e-mails
async.sms()
send a text message
async.sms({
to: '48795248011',
content: 'You have one new voice message'
});
async.email()
send an email
async.mail({
to: 'test@example.com',
content: 'hello',
content_type: 'text/plain',
subject: 'you have one new voice message'
});
Limdesk
CloudIVR easily integrates with Limdesk - a customer support system. With the use of a built-in library you can add events (Limdesk Activities) and new support tickets during a phone conversation.
// instead of APIKEY STRING you should enter your API key here. It is available in Limdesk Settings.
limdesk.setup('APIKEY STRING');
// check if a person who is calling right now is already in your Limdesk customer database
var who = limdesk.getClientByPhone(call.getCallerId());
// create a new Ticket for an existing customer
// or create a new Ticket for a newly created customer
limdesk.createTicket({
content: 'new conversation',
client_id: who_id,
title: 'A new call from ' + call.getCallerId()
});
// create a new Limdesk Activity for an existing customer
// or for a newly created customer
limdesk.createActivity({
client_id: who_id,
content: 'A new call from ' + call.getCallerId()
});
CALLBACKS
Callbacks have a separate code which is run independently from the conversation plan. Thanks to this solution you can asynchronously serve events that can appear during the phone conversation.
Callbacks available during a phone conversation:
- hunt_group_enter - redirecting a calling person to a queue
- call_end - ending a call
- hunt_group_agent_answer - an Agent picking up a phone
- hunt_group_recording - appearance of a new recording
- call_start - a new incoming call
every callback sent during a phone call has to include:
- timestamp
- parent_uuid
- event
- callerid
The above data is available for every callback via params object. One code serves all callbacks. A checking structure params.event should be used for catching a certain callback.
Call-independent callbacks:
- agent_outbound_call_start - an Agent has started an outbound call
- agent_outbound_call_end - an Agent has ended a call
logger.debug() is used for logging from callbacks level. You can’t use statements available via call object in callbacks.
logger.debug('hello');
// a way to check what’s inside params
logger.debug(JSON.stringify(params));
limdesk.setup('xxxxxxxxxxxxx');
var who_id = limdesk.getClientByPhone(params.callerid);
if (params.event == 'hunt_group_agent_answer') {
limdesk.createTicket({
content: 'call answered',
client_id: who_id,
title: 'Agent ' + params.agent_name + ' answered a call'
});
} else if (params.event == 'hunt_group_enter') {
async.sms({
to: '4812345679',
content: 'a new call!'
});
}
Notices
Alias numbers
Advanced functionality. Please contact our support first.
call.getAliasNumber()
return a phone number alias, if an alias number was called
call.getAliasNumberTag()
return a tag of a phone number alias, if an alias number was called and an alias has an active tag
Polish speech synthesis
Polish speech synthesis is buffered. Variables (e.g. var a = “hello”; call.sayPL(a)) will not work properly. Only static texts are available.
Internal numbers and transfer initiation
Local and remote Agents can redirect calls to each other (e.g. a secretary redirecting calls to her boss). You only need to assign them a 2-digit number.
- an Agent who answers a phone call presses '#'
- he hears the word “transfer” and the caller hears a melody
- the Agent selects a 2-digit number (e.g. 99) which connects him to another Agent
- now he can tell him about the caller before actually transferring the call
- he can press '#' in order to hang up and transfer the call to the other Agent or he can press '*' to return to the caller
Attention!
- Transfers feature is in BETA status, therefore it may work unstable!
- Calls are not recorded after being transferred
- You can’t transfer more than once
The transfers feature will be undergoing intensive development in the near future.
Knack
Embedding the KNACK application in a web phone.
var myJson = {
'field_1': 'Hello',
'field_3': 'World'
}
data = http.post('https://api.knackhq.com/v1/objects/object_1/records', {
headers: {
'X-Knack-Application-Id': '57855a2a48cxxxxxxxxxxx',
'X-Knack-REST-API-Key': '11a103f0-xxxx-11e6-9726-xxxxxxxxxxxxx'
},
body: myJson
});
call.huntGroup({
name: "sprzedawcy",
msg: '<script type="text/javascript">app_id57855a2a48cxxxxxxxxxxx";distribution_key="dist_2";</script><script type="text/javascript" src="https://loader.knack.com/57855a2a48cxxxxxxxxxxx/dist_2/knack.js"></script><div id="knack-dist_2">Loading...</div>'
});
OnePageCRM + Mustache
var shortInfo = "\
OnepageCRM Integration Demo\
client {{first_name}} {{last_name}} {{company_name}}\
yes, cloudivr.io can render HTML inside WebRTC clients! :)";
onepagecrm = new OnePageCRM('xxxx', 'yyyyy');
call.say('hello');
var tmp = onepagecrm.get('contacts.json', {phone: call.getCallerId()});
var contact = tmp.data.contacts[0]
if (typeof contact === 'undefined') {
call.debug('adding new customer to CRM');
resp = onepagecrm.post('contacts.json', {'last_name': 'NewCustomer', 'first_name': call.getCallerId()});
call.debug(resp);
call.huntGroup({
name: 'sales',
acd: 3,
ann: 'pl'
});
} else {
call.debug('existing customer - adding this call to his activity stream');
resp = onepagecrm.post('calls.json', {contact_id: contact.contact.id});
var msg = Mustache.render(shortInfo, contact.contact);
call.debug(msg);
call.huntGroup({
name: 'support',
msg: msg
})
}
call.hangup();