An Express app that responds with TwiML to <Connect>
to a MediaStream and connect it with a specified Dialogflow.
- Setup a Dialogflow Agent and make note of the Google Project ID
- Download your Google Credentials (that has access to your Dialogflow project) to a file named
google_creds.json
store that in the root of this folder. - Optional: Setup and Configure the gcloud command line tool so that you can deploy to Google AppEngine
npm install
Populate your .env
file from the .env.example
file using configure-env
npx configure-env
Install the Twilio CLI
Optional: Purchase a Twilio number (or use an existing one)
Optional: Search for available numbers in the 650 area code in the US
twilio api:core:available-phone-numbers:local:list --area-code="650" --country-code=US --voice-enabled
Optional: Buy a number
twilio api:core:incoming-phone-numbers:create --phone-number="+16505551234"
Start the server locally
npm start
Wire up your Twilio number with your endpoint on incoming calls. This will automatically start an ngrok tunnel to your machine.
twilio phone-numbers:update +15552223333 --voice-url=http://localhost:3000/twiml
gcloud app deploy
Point your Incoming Webhook to your AppEngine instance.
twilio phone-numbers:update +15552223333 --voice-url=https://YOUR-APPENGINE-INSTANCE.appspot.com/twiml
If you set END_OF_INTERACTION_URL
in your .env
file to a Webhook that you host, you can handle events. You will receive dialogflowJSON
as a querystring on your Webhook.
The JSON will contain the Intent's information for you to code your response.
Here is an example using a Twilio Function:
exports.handler = function(context, event, callback) {
const twiml = new Twilio.twiml.VoiceResponse();
const dialogflow = JSON.parse(event.dialogflowJSON);
switch (dialogflow.intent.displayName) {
case 'speak-to-an-agent':
console.log(`Dialing agent number configured in environment: ${process.env.AGENT_NUMBER}`);
twiml.dial(process.env.AGENT_NUMBER);
break;
default:
console.error(`Intent: "${dialogflow.intent.displayName}" (${dialogflow.intent.name}) was not handled.`);
twiml.hangup();
}
callback(null, twiml);
}