Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Orbita can be integrated with Twilio to make phone calls or send SMS with the help of the Twilio node in Experience Designer. The URL of the TwiML used to create the phone call or msg.payload can contain the text of the SMS message.

...

  • Registered Twilio account.

  • Twilio-powered Phone number.

...

Twilio node

...

The URL will be the local endpoint that was created in the first section.
http://127.0.0.1/oeapi/twilioml.xml

If you configure the node to make a phone call, provide a TwiML URL that is publicly accessible. You can add the receiving phone number in the To field, in the Twilio node, so that Twilio will send the text message(s) or make a phone call. If the number is left blank, set it to use you set the msg.topic property in the function node connected to the Twilio node, the To field should be left blank.

Setting credentials

There are two options in the Credentials drop-down.

...

  • Use global credentials. Contact orbitasupport@orbita.ai to get details on the environmental variables used to configure global credentials.

  • Use local credentials. Use this option to give details of your Twilio account in the node. The recipient(s) will receive messages/phone calls from your Twilio phone number.

Adding a Twilio account to the Twilio node

To add a new Twilio account to the Twilio node:

  1. Open the Twilio node.

  2. Select “Use local credentials“ in the Credentials field and “Add new twilio-api…“ from the Twilio field as shown in the screenshot below. Click Edit in against the Twilio nodefield.

    Image Added

  3. A new dialog box appears.

    Image Removed

    Enter the details from your Twilio account.

    1. Account SID and Token - you will get it from the Twilio console (Refer below section).

    2. From - the Twilio phone number.

    3. Name - Name of the Twilio configuration.

Twilio Account SID and token

  1. Go to https://

    www

    console.twilio.com/

    and click on the console button in the right top corner of the web page

    and log in to your Twilio account

    or click Console and log in

    .

    Image RemovedImage Added

  2. In

    On the console page, you can get the Account SID and Auth Token.

    Image Removed
  3. You can see your Twilio powered phone number on this page. https://www.twilio.com/console/phone-numbers/incoming

    Image Removed
  4. Image Added

Setting output

There are two three types of Output.

...

  • SMS. Lets the Twilio node send a text message to the phone number.

    Image Modified

  • Call. Lets the Twilio node make a phone call to the phone number.

    Image Modified

  • WhatsApp. Lets the Twilio node send a message via WhatsApp.

    Image Added

    • To. The phone number to which a Call phone call or SMS or WhatsApp should be made or sent respectively. If the number is left blank, you use msg.topic property in the function node to add the phone number, you can leave this field blank.

    • URL. Phone calls that you make from a Twilio number to an outside number are controlled using TwiML. The initial URL for the call is provided as a parameter to the Twilio REST API request, which you make, to initiate the call.

      See, https://www.twilio.com/console/voice/twiml/overview to learn more about the URL.

    • Name. Name of the node.

...

The following flow shows how to integrate Twilio with Experience Designer.

In the example, when a valid user triggers the help intent, Twilio reads TwiML instructions at that URL. In the function node, the TwiML is already instructed to respond in an automated voice “Please leave a message after the tone” and start the recording for 20 seconds.

...

Two different flows are given in the above example. The first flow creates an endpoint URL that can be used in the Twilio node. The second flow triggers a call when an authenticated user says “help”.

http in node

Creates an http end-point for creating web services.

  • Method

    . Set

    is set to GET.

  • URL. Enter the XML file that

    will be

    is created.

    Image Modified

Function node

The following code is

...

used with parameters like msg.payload, statusCode, and msg.header. Push the XML code in msg.payload for this example. This XML code sends a short message and

...

records the

...

caller's voice post message.

Code Block
msg.payload='<?xml version="1.0" encoding="UTF-8"?><Response><Say voice="woman">Please leave a message after the tone.</Say><Record maxLength="20" /></Response>';
msg.statusCode=200;
msg.headers = {"content-type": "application/xml"};
return msg; 

...

http response node

Sends responses back to requests that were received from the HTTP input node.

Intent Request node

Triggers the flow when help is called by the user.

Function node

Checks whether the user is an authenticated user.

Say node

Configure the bot to say something based on the output from the attached function node.

...

Twilio node

...

The URL will be the local endpoint that was created in the first section.
http://127.0.0.1/oeapi/twilioml.xml

...

Status call back

We can identify the delivery status of the Twilio SMS or IVR calls we make from the system through the Twilio status call back property.

Voice/ IVR status callBack

Please use the below snippet to set the status call back function for IVR communication.

Code Block
msg.twilio = {
    settings: {
        machineDetection: "DetectMessageEnd",
        machineDetectionTimeout: 30,
        asyncAmd: false,
        asyncAmdStatusCallbackMethod: "POST",
        asyncAmdStatusCallback: "https://domain/oeapi/amd",
        statusCallback:'https://domain/oeapi/twilio/voice/status',
        statusCallbackMethod: 'POST',
        statusCallbackEvent: ['initiated', 'answered', 'ringing', 'completed']
    }
}

The status of the connection will be available under the response property CallStatus

  1. When the call is initiated the status is CallStatus: "initiated"

  2. When the phone is ringing the status is CallStatus: "ringing"

  3. When the user attends the phone call the status is CallStatus: "In-Progress"

  4. When the call is disconnected the status is CallStatus: "completed"

  5. When the user does not attend the call or when the user disconnects the call without attending, then the status is CallStatus: "no-answer"

SMS status callBack

Please use the below snippet to set the status call back function for SMS communication.

Code Block
msg.twilio = {
    settings: {
        statusCallbackMethod:'POST',
        statusCallback: 'https://domain/oeapi/twilio/sms/status',
    }
}

The status of the connection will be available under the response property CallStatus

  1. When the SMS is sent, the status is SmsStatus: "sent"

  2. When the SMS is delivered, the status is SmsStatus: "delivered"

StatusCallBack Flow sample

The sample code to set up Twilio SMS and IVR services are given below. Import this code snippet in the Experience Designer.

Code Block
[{"id":"fd8bf50c.2ce77","type":"tab","label":"Twilio sms/voice status callback","disabled":false,"info":""},{"id":"c8ccf1b3.e47898","type":"alexa-flow-config reff","z":"fd8bf50c.2ce77","skillConfig":"ad3fc2e.9afca4","x":100,"y":50,"wires":[]},{"id":"2b8e648b.70e6c4","type":"twilio out","z":"fd8bf50c.2ce77","twilio":"b84e0bf3.5721c8","twilioType":"call","url":"","number":"","name":"IVR ","x":770,"y":140,"wires":[]},{"id":"5d780d4a.4c1c84","type":"inject","z":"fd8bf50c.2ce77","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":380,"y":140,"wires":[["7738659a.6fc32c"]]},{"id":"7738659a.6fc32c","type":"function","z":"fd8bf50c.2ce77","name":"IVR status call back","func":"msg.topic = '+1999996666' // Phone number to call, needs the +1, we are set up for US based calling. \nmsg.payload = 'https://domain/oeapi/twilio/voice'\n// https://www.twilio.com/docs/voice/answering-machine-detection\nmsg.twilio = {\n    settings: {\n        machineDetection: \"DetectMessageEnd\",\n        machineDetectionTimeout: 30,\n        asyncAmd: false,\n        asyncAmdStatusCallbackMethod: \"POST\",\n        asyncAmdStatusCallback: \"https://domain/oeapi/amd\",\n        statusCallback:'https://domain/oeapi/twilio/voice/status',\n        statusCallbackMethod: 'POST',\n        statusCallbackEvent: ['initiated', 'answered', 'ringing', 'completed']\n    }\n}\nreturn msg;\n","outputs":1,"noerr":0,"x":590,"y":140,"wires":[["2b8e648b.70e6c4"]]},{"id":"c3c90630.5b944","type":"comment","z":"fd8bf50c.2ce77","name":"Twilio- Voice","info":"(617) 622-5611","x":190,"y":140,"wires":[]},{"id":"7e5811e9.bbb408","type":"http in","z":"fd8bf50c.2ce77","name":"Twilio - Voice","url":"/twilio/voice","method":"post","upload":false,"swaggerDoc":"","x":190,"y":220,"wires":[["a2e2e292.9b1978"]]},{"id":"a2e2e292.9b1978","type":"function","z":"fd8bf50c.2ce77","name":"IVR","func":"msg.payload2 = msg.payload;\nif(msg.req.body.AnsweredBy && msg.req.body.AnsweredBy === 'machine_start') {\n  global.set('AnswerType','machine_start');  \n} else {\n  global.set('AnswerType','notMachine');   \n}\nif(msg.payload.SpeechResult) {\n    var SpeechResult = msg.payload.SpeechResult.toLowerCase();\n    if (SpeechResult === 'snow' || SpeechResult === 'no.') {\n        msg.payload.SpeechResult = 'no';\n    }\n} else {\n    if (msg.req.url.indexOf(\"sessionId\") !== -1) {\n    msg.payload.SpeechResult = 'did not understand';  // have intent did not understand\n    } \n}\n\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":240,"wires":[["f04173b2.4d176"]]},{"id":"f04173b2.4d176","type":"orbita-bot-provider-v2","z":"fd8bf50c.2ce77","name":"","botInParser":"var utterance = msg.payload2.SpeechResult || \"launch\";\nif(utterance) {\n    utterance =utterance.replace('.', '');\n}\nnode.warn(utterance);\nmsg.payload = {\n    \"query\": utterance,\n    // \"sessionId\": msg.payload.sessionId,\n    \"originalRequest\": {\n        \"source\": \"twilio\",\n        \"data\": msg.payload2\n    }\n}\n\n// msg.payload.sessionId = msg.req.query.sessionId || msg.payload.sessionId;\n\n\nif(msg.req.query.sessionId) {\n  msg.payload.sessionId = msg.req.query.sessionId\n}\n\nif(msg.payload.sessionEnd) {\n    msg.payload.session = {};\n}\n\n","botOutParser":"","transcriptEnabled":false,"ttsconfig":"{\n    \"languageCode\": \"en-US\",\n    \"ssmlGender\": \"FEMALE\",\n    \"name\": \"en-US-Standard-C\",\n    \"audioEncoding\": \"MP3\"\n}","providerType":"Google","skillConfig":"ad3fc2e.9afca4","token":"","noerr":0,"agentId":"","nlpData":false,"x":540,"y":240,"wires":[["611dc26.c789f3c"]]},{"id":"611dc26.c789f3c","type":"switch","z":"fd8bf50c.2ce77","name":"End?","property":"payload.sessionEnd","propertyType":"msg","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":710,"y":240,"wires":[["ed8b6d4c.c424c8"],["b150adb4.3517f8"]]},{"id":"ed8b6d4c.c424c8","type":"template","z":"fd8bf50c.2ce77","name":"Hangup","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Response>\n    <Say voice=\"Polly.Joanna\" language=\"en-US\">{{payload.ssml}}</Say>\n    <Hangup/>\n</Response>\n","x":860,"y":200,"wires":[["6bb145a5.d9aa64"]]},{"id":"b150adb4.3517f8","type":"template","z":"fd8bf50c.2ce77","name":"Respond","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Response>\n    <Gather  input=\"speech dtmf\" enhanced=\"true\" speechModel=\"phone_call\" actionOnEmptyResult=\"true\" timeout=\"3\" action=\"https://14a2-120-138-12-133.ngrok.io/oeapi/twilio/voice?sessionId={{payload.sessionId}}\" method=\"POST\">\n         <Say voice=\"Polly.Joanna\" language=\"en-US\">{{payload.ssml}}</Say>\n    </Gather>\n\n    <Say voice=\"Polly.Joanna\" language=\"en-US\">Sorry, I couldn't hear you. Goodbye!</Say>\n</Response>\n\n","output":"str","x":860,"y":260,"wires":[["6bb145a5.d9aa64"]]},{"id":"6bb145a5.d9aa64","type":"http response","z":"fd8bf50c.2ce77","name":"","x":1030,"y":220,"wires":[]},{"id":"cd4bae9b.d398b","type":"http in","z":"fd8bf50c.2ce77","name":"","url":"/twilio/voice/status","method":"post","upload":false,"swaggerDoc":"","x":380,"y":360,"wires":[["9c0b623b.1515b8"]]},{"id":"9c0b623b.1515b8","type":"http response","z":"fd8bf50c.2ce77","name":"","statusCode":"","headers":{},"x":630,"y":360,"wires":[]},{"id":"be1e060b.b0f6c","type":"comment","z":"fd8bf50c.2ce77","name":"voice status callback","info":"","x":150,"y":360,"wires":[]},{"id":"5dab882c.9a03f8","type":"http in","z":"fd8bf50c.2ce77","name":"","url":"/twilio/sms/status","method":"post","upload":false,"swaggerDoc":"","x":380,"y":580,"wires":[["95fbf349.599458"]]},{"id":"95fbf349.599458","type":"http response","z":"fd8bf50c.2ce77","name":"","statusCode":"","headers":{},"x":697,"y":579,"wires":[]},{"id":"719336fe.5978b","type":"comment","z":"fd8bf50c.2ce77","name":"SMS status callback","info":"","x":150,"y":580,"wires":[]},{"id":"864486d9.21396","type":"inject","z":"fd8bf50c.2ce77","name":"","topic":"","payload":"{}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":500,"wires":[["855cdd12.993a9"]]},{"id":"855cdd12.993a9","type":"function","z":"fd8bf50c.2ce77","name":"SMS","func":"if(!msg) {\n    msg = {};\n    \n}\n\nmsg.twilio = {\n    settings: {\n        statusCallbackMethod:'POST',\n        statusCallback: 'https://domain/oeapi/twilio/sms/status',\n    }\n}\n\nmsg.payload = 'Hello welcome to twilio SMS'\n\nreturn msg;","outputs":1,"noerr":0,"x":530,"y":500,"wires":[["8b30b926.342f58"]]},{"id":"8b30b926.342f58","type":"twilio out","z":"fd8bf50c.2ce77","twilio":"b84e0bf3.5721c8","twilioType":"sms","url":"","number":"","name":"","x":710,"y":500,"wires":[]},{"id":"58603a8d.f4c5f4","type":"comment","z":"fd8bf50c.2ce77","name":"Twilio- SMS","info":"","x":170,"y":500,"wires":[]},{"id":"6c97f3c6.7c8e34","type":"http in","z":"fd8bf50c.2ce77","name":"","url":"/amd","method":"post","upload":false,"swaggerDoc":"","x":380,"y":420,"wires":[["d9ada7c7.818e88"]]},{"id":"d9ada7c7.818e88","type":"http response","z":"fd8bf50c.2ce77","name":"","statusCode":"","headers":{},"x":650,"y":420,"wires":[]},{"id":"98df258d.8cd8a","type":"http in","z":"fd8bf50c.2ce77","name":"","url":"/failure","method":"post","upload":false,"swaggerDoc":"","x":170,"y":260,"wires":[["a2e2e292.9b1978"]]},{"id":"ad3fc2e.9afca4","type":"alexa-skill-config","skillname":"Version Three","projectId":"6225f5afb596ce006bd75a36","intents":"[]","skillstate":"fromsession"},{"id":"b84e0bf3.5721c8","type":"twilio-api","z":"","sid":"ACace0e69fb0f8de8904ead0afacecc082","from":"+1999996666","name":""},{"id":"slots","type":"slots","z":"","slots":[]}]

Best Practices

  1. Do not use special characters in the messages.

  2. If the message is large (i.e. greater than 140 characters), split the message into segments and use multiple Twilio nodes to send the segments with a delay.

  3. The maximum number of characters allowed in one segment is 140. If you use multiple segments, then you should restrict the maximum number of characters used in each segment to 134 as 6 characters will be utilized to link the segments together.

Related Articles

Filter by label (Content by label)
showLabelsfalse
max5
showSpacefalse
sorttitle
cqllabel = "node"