by pomegran

GitHub Readme.md


This example connector allows you to establish a phone call with a Teneo bot. The connector makes your Teneo bot available via Twilio IVR (Interactive Voice Response). This guide will take you through the steps of setting a new Twilio phone number and deploying the connector to respond to events sent by Twilio.



When running the connector locally, making the connector available via https is preferred. Ngrok is recommended for this.

Teneo Engine

Your bot needs to be published and you need to know the engine url.

Setup instructions

Below you will find two ways to run the this connector. The first way is by running the connector on Heroku. This is the easiest to get the connector running for non-developers since it does not require you to run node.js or download or modify any code.

The second way is to run the connector locally or to deploy it on a server of your choice. This preferred if you're familiar with node.js development and want to have a closer look at the code and plan to enhance or modify it.

Running the connector on Heroku

Click the button below to deploy the connector to Heroku:


In the 'Config Vars' section, add the following:

  • TENEO_ENGINE_URL: The engine url of your bot

Optionally, you can also add the following parameters:

  • LANGUAGE_STT: Speech to Text language. Defaults to en-US if not provided. For a list of supported languages, see: https://www.twilio.com/docs/voice/twiml/gather#languagetags. Note that your Teneo solution should match the chosen language as well.
  • LANGUAGE_TTS: Text to Speech language. Defaults to en-US if not provided. For a list of supported languages, see: https://www.twilio.com/docs/voice/twiml/say/text-speech#amazon-polly. Note that your Teneo solution should match the chosen language as well.
  • ACCOUNT_SID: Your Twilio Account SID - only needed if SMS pushing is used
  • AUTH_TOKEN: Your Twilio Auth Token - only needed if SMS pushing is used
  • PORT: Port number this runs on. Defaults to 1337

Next, follow the Setup a Twilio phone number instructions. Make sure that in step 6 you set the Webhook to the url of the Heroku app.

Running the connector locally

If you want to run the connector locally, follow the steps below. If you have already followed the instructions above to deploy the connector on Heroku, you can skip this section and jump straight to Setup a Twilio phone number.

  1. Download or clone the connector source code:
    git clone https://github.com/artificialsolutions/tie-api-example-twilio-ivr-sms.git
  2. Install dependencies by running the following command in the folder where you stored the source:
    npm install
  3. Create a .env file in the folder where you stored the source and add the URL of your engine. Optionally you can also specify the langauges for Speech To Text and Text To Speech:
  4. Start the connector:
    node server.js

Next, we need to make the connector available via https. We'll use ngrok for this.

  1. Start ngrok. The connector runs on port 1337 by default, so we need to start ngrok like this:
    ngrok http 1337
  2. Running the command above will display a public https URL. Copy it, we will use it as a Webhook URL in step 6 of the Twilio Setup instructions below.

Setup a Twilio phone number

  1. Setup a free Twilio account, which comes with free credit money you can spend on buying a number.
  2. Go to the left pane menu and click the Programmable Voice phone icon, then from the submenu choose Numbers and click the Get a number button.
  3. Follow the instruction to obtain your phone number (the instruction may differ per region).
  4. Click on "Manage Numbers".
  5. Click your number so you can configure it.
  6. Under "Voice & Fax" -> "A call comes in" set the webhook to the Webhook URL you copied earlier and append /incoming.
  7. Under "Voice & Fax" -> "Call Status Changes" set the webhook to the Webhook URL you copied earlier and append /other.

That's it! Call your Twilio number with your phone, and speak to your bot!

Engine output parameters

The connector will check for the following output parameters in an output to send specific data to Twillo:


If the output parameter twilio_customVocabulary exists, it will be used for custom vocabulary understanding or hints. The value should be a string. You may provide up to 500 words or phrases, separating each entry with a comma. Your hints may be up to 100 characters each, and you should separate each word in a phrase with a space. For more details: https://www.twilio.com/docs/voice/twiml/gather#hints


By default, end of speech is detected automatically. The twilio_customTimeout output parameter allows you to set a custom timeout. This can come in handy when you ask the user for a number for example. In that case you may prefer a longer end of speech detection timeout.


If the output parameter twilio_endCall with the value true exists, the call will be ended.


If the output parameter twilio_speechModel exists, it will be used to set a custom speech model. Allowed values are: 'default', 'numbers_and_commands' and 'phone_call'.


If the output parameter twilio_inputType exists, it will be used to set a custom input type. Allowed values are: 'dtmf', 'speech' or 'dtmf speech'. DTMF allows the end user to enter a number using the keypad of the phone. User must press # to mark end of the input. The digits entered by the user will be sent to engine using an input parameter digits.


If the output parameter twilio_smsText exists, it will be used to send its value to the phone number being used.


If the output parameter twilio_agentChatNumber exists, the call will be handed to number e.g. a call center number, agent etc. This is a number is in E.164 format


If the output parameter twilio_agentEndMessage exists, this will be said back to the caller when the agent chat ends

Triggering a Twilio call i.e. a call out

Outgoing calls can be now be triggered whilst passing context on the first request. Below is an example of starting a call and passing data (in this instance, "info"):


  Example code for triggering an outbound Twilio call
  For other code examples go to twilio.com/docs/voice/make-calls


package twiliostartcall;

// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Call;

import java.net.URI;
import java.net.URLEncoder;

public class TwilioStartCall {

    public static final String ACCOUNT_SID = "<TWILIO ACCOUNT SID>"; // Twilio Account SID
    public static final String AUTH_TOKEN = "<TWILIO AUTH TOKEN>"; // Twilio Auth Token
    public static final String TO = "<NUMBER TO CALL>"; // Number to call in E.164 format
    public static final String FROM = "<TWILIO NUMBER CALLING FROM>"; // Twilio number calling from in E.164 format
    public static final String OUTGOING_STATE = "{ \"info\": \"This is a test message\" }"; // JSON object to pass to Teneo on first input.  This is sent as the parameter "outgoingState"

    public static void main(String[] args) {

        try {
            Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
            Call call = Call.creator(
                    new com.twilio.type.PhoneNumber(TO),
                    new com.twilio.type.PhoneNumber(FROM),
                    URI.create("https://<CONNECTOR URL>/incoming?outgoingState=" + URLEncoder.encode(OUTGOING_STATE, "UTF-8")))

        } catch (Exception e) {
            System.out.println("Error: "+e.getMessage());



The JSON object with additional information is passed to Teneo to be used within the Teneo session, for example:

    "info": "This is a test message"

This will send a parameter called "outgoingState" on the first request to Teneo. Therefore the following code in pre-processing can be used to get the object and use it within conversational flows, set state etc. To consume this in Teneo, here is an example of code to place in pre-processing assuming you have setup a global variable called "outgoingState" with the value "[:]":

if (engineEnvironment.getParameter("outgoingState")) {
    outgoingState = new groovy.json.JsonSlurper().parseText(engineEnvironment.getParameter("outgoingState"))

Accessing the information within the object is achieved as per any other Map e.g.