JavaScript

Built-in JavaScript libraries

Commands

CALL – call controls

call.play()

play a .wav file available via http

call.play('https://example.com/files/welcome.wav');

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)

set music for customers who are on hold

call.play('https://example.com/files/music.wav');

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&param2=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();