Twilio now supports a One-Click integration with Google's Dialogflow CX, which simplifies the process of connecting a Dialogflow agent with Twilio Programmable Voice.
In this tutorial, we'll show you how to integrate a Google Dialogflow CX agent with Conversations using a Node.js server-side application to create interactive conversations using a Dialogflow chatbot.
Let's get started!
Before you get started, you will need to have:
Note: We're using the Twilio CLI to make API requests to Twilio's Conversations service, but you can choose another method such as a helper library.
Let's purchase an SMS-capable phone number that suits your fancy. Navigate to the Buy a Number page in the Twilio Console. Make sure the SMS box under Capabilities is selected, then click Search.
You'll then see a list of available phone numbers and their capabilities. Find a number of your choice and click Buy to add it to your account. Click Close.
If you've never used Twilio Conversations, please navigate to Conversations > Defaults in the Console. Visiting this page will trigger some initial setup on your Twilio account for Conversations. You can skip ahead if you already use Conversations.
Open a new terminal window and navigate to the directory where you want your project to live. Then, create a project folder and change into this directory:
_10mkdir tutorial-dialogflow-conversations && cd tutorial-dialogflow-conversations
In order to connect your application to Twilio, you'll need to collect a few values from the Twilio Console. You will store these values in a .env
file, and your server will read in these values.
Let's create a new .env
file within the new project folder that you created above. Open this file in your favorite code editor.
The first value you'll need is your Account SID, which you can find in the Twilio Console. Once you've gotten that value, store it in the .env
file:
_10TWILIO_ACCOUNT_SID=<your account sid>
Next, you'll need to create an API key. This is what you'll use to authenticate with Twilio when making API calls.
You can create an API key using the Twilio CLI, the REST API, or the Twilio Console. This tutorial will show how to generate it via the Console.
To generate the API Key from the Twilio Console:
When you've created the key, you'll see the friendly name, type, key SID, and API key secret.
Make sure to copy the secret now, because you'll only be able to see it once. When you leave this page, you won't be able to see the secret again.
Copy the API Key SID and the API Key Secret and store both values in the .env
file.
_10TWILIO_API_KEY_SID=<key sid>_10TWILIO_API_KEY_SECRET=<secret>
Now that you've stored your credentials, you can install the dependencies and create the Express server.
First, set up a new Node.js project with a default package.json
file by running the following command:
_10npm init -y
Once you have your package.json
file, you're ready to install the required dependencies.
For this tutorial, you'll need the following packages:
Run the following command to install all the dependencies:
_10npm install @google-cloud/dialogflow express twilio dotenv
If you check your package.json
file now, you'll notice that the packages above have been installed as "dependencies".
Create a new file called server.js
at the root of the project directory from your terminal:
_10touch server.js
In this server file, you'll put all the core logic for your web server. Open that file in your favorite code editor. Then, copy and paste the following code into the file:
_16require("dotenv").config();_16const dialogflow = require("@google-cloud/dialogflow");_16const express = require("express");_16_16const app = express();_16app.use(express.urlencoded({extended: true}));_16const port = 3000;_16_16const projectId = "";_16_16//create the twilioClient_16const client = require("twilio")(_16 process.env.TWILIO_API_KEY_SID,_16 process.env.TWILIO_API_KEY_SECRET,_16 {accountSid: process.env.TWILIO_ACCOUNT_SID}_16);
This code imports the Dialogflow client, sets up the Express server (which will receive the HTTP requests from Twilio) and sets the application to run on port 3000.
In server.js
you will write a function to handle the communication between your server and Dialogflow. This async function will pass the response from the Conversation's user to Dialogflow and receive a fulfillment (a response from the bot).
In server.js
, paste in the following code:
_32async function sendToDialogflow(_32 projectId,_32 sessionId,_32 query_32) {_32_32 const sessionClient = new dialogflow.SessionsClient();_32 // The path to identify the agent that owns the created intent._32 const sessionPath = sessionClient.projectAgentSessionPath(_32 projectId,_32 sessionId_32 );_32_32 // The text query request_32 const request = {_32 session: sessionPath,_32 queryInput: {_32 text: {_32 text: query,_32 languageCode: "en-US",_32 },_32 },_32 };_32_32 try {_32 const responses = await sessionClient.detectIntent(request);_32 return responses[0];_32 } catch (err) {_32 console.log("Dialogflow error: " + err);_32 }_32 return false;_32}
Now, let's create an async function to inject the bot's response back into the Conversation on Twilio's side.
Copy and paste the following sendToTwilio
function in the server.js
file, under the sendToDialogflow
function:
_11async function sendToTwilio(response, conversationSid) {_11 try {_11 await client.conversations.conversations(conversationSid)_11 .messages_11 .create({author: 'system', body: response})_11 return true;_11 } catch (err) {_11 console.log('Twilio error: ' + err);_11 return false;_11 }_11}
You'll add an endpoint on the Express server that will receive the message events from the user connected to Conversations and set the Express app to listen for incoming requests.
Add the following code in the server.js
file, under the sendToTwilio
function:
_15app.post("/dialogflow", async (req, res) => {_15 let sessionId = req.body.ConversationSid;_15 let query = req.body.Body;_15_15 let response = await (await sendToDialogflow(projectId, sessionId, query)).queryResult.fulfillmentText;_15 if (!(response)) { res.status(500).send(); }_15_15 let result = await sendToTwilio(response, sessionId);_15 if (result) { res.status(201).send(); }_15 res.status(500).send();_15})_15_15app.listen(port, () => {_15 console.log(`Dialogflow integration listening on port ${port}`)_15 })
You can manage the Dialogflow CX agent via theDialogflow Consoleor the Dialogflow API. Let's go to Google's Dialogflow console and log in.
Then, create a new Agent and name it "ConversationsBot". Click Create.
Next, for the purpose of this tutorial, we'll import a pre-built agent from Google. Click Prebuilt Agents:
There are a lot of options to explore here, but we'll use the Jokes agent this time. Type 'jokes' into the search field, and click the green Import button. Follow the prompts on the next screen to finish creating it and then click Go to Agent.
Now that you've created your "Jokes" agent, grab the project ID from the URL bar. The project ID should be "jokes-" + some random string (e.g. "jokes-qncx"). Then, insert this into your server.js
file as the value for "projectId".
_10const projectId = "jokes-<string>";
In order for the Dialogflow client to be able to authenticate with our project, you need to add some credentials to your Google Cloud API environment.
Navigate to Google's authentication Getting Started page and follow the instructions for Creating a service account and Setting the environment variable.
Start those engines! It's time to fire up your server and pipe it to the internet using ngrok.
Let's start your application by running the following command in your terminal from your project's directory. This will start your server on localhost:3000.
_10node server.js
When you're working on your Express application in your development environment, your app is only reachable by other programs on the same computer, so Twilio won't be able to talk to it. Ngrok solves this problem. Once started, it provides a unique URL on the ngrok.io domain, which will forward incoming requests to your local development environment.
Let's open another window in your terminal and type the following command:
_10ngrok http 3000
This will create a publicly accessible URL that will forward incoming requests to localhost:3000 on your machine.
Make a note of the ngrok URL that displays in your terminal. You'll use it for the next step.
You can also add your bot to an existing Conversation using the Conversation-Scoped Webhook API
Now it's time to put it all together! We'll use the twilio-cli in this tutorial, but you can follow these samples to use the REST API or one of our other helper libraries.
We'll be using theAddress Configuration API to set a Conversations autrocreation rule that autocreates a new Conversation when your Twilio number receives a text and passes any subsequent messages from the user to your server.js
file.
Copy and paste this command in your terminal, substituting your ngrok url where it says [your_ngrok_url] and the Twilio phone number you purchased where it says [your_twilio_number]:
_10twilio api:conversations:v1:configuration:addresses:create \_10 --friendly-name "dialogflow" \_10 --auto-creation.enabled \_10 --auto-creation.type webhook \_10 --auto-creation.webhook-url [your_ngrok_url]/dialogflow \_10 --auto-creation.webhook-method POST \_10 --auto-creation.webhook-filters onMessageAdded \_10 --type sms \_10 --address [your_twilio_number]
Last step! Send a text message to the Twilio phone number you added to the Conversations autocreation rule. You should see that message appear in the window that's running your server.js
file, followed by the Dialogflow response.
Finally, Dialogflow's response will be texted back to your phone by Conversations 🎉
Note: We used SMS in this tutorial, but you can apply the concepts you learned here to any channel Conversations supports (i.e. Webchat/SDK, WhatsApp, Facebook Messenger, etc.).