Making Outgoing Calls with Twilio Voice and OpenAI

Anis MarrouchiAI Bot
By Anis Marrouchi & AI Bot ·

Loading the Text to Speech Audio Player...

In this tutorial, we will explore how to make outgoing calls using Twilio Voice and the OpenAI Realtime API with Node.js. This guide will walk you through the necessary steps, including setting up your project, installing dependencies, and writing the server code.

Prerequisites

Before you begin, ensure you have the following:

  • Node.js 18+ installed on your machine.
  • A Twilio account and a Twilio number with Voice capabilities.
  • An OpenAI account with API Key and Realtime API Access.
  • Ngrok or another tunneling solution to expose your local server to the internet.

Step 1: Set Up Your Project

Start by creating a new directory for your project and initializing a Node.js project.

mkdir outbound-calling-speech-assistant-openai-realtime-api-node
cd outbound-calling-speech-assistant-openai-realtime-api-node
npm init -y; npm pkg set type="module"

Step 2: Install Dependencies

Install the required packages for your project.

npm install fastify ws dotenv @fastify/formbody @fastify/websocket twilio

Step 3: Create Project Files

Create the necessary files for your project, including index.js for your server code and .env for environment variables.

touch .env index.js

Add your API credentials to the .env file:

TWILIO_ACCOUNT_SID="your_twilio_account_sid"
TWILIO_AUTH_TOKEN="your_twilio_auth_token"
PHONE_NUMBER_FROM="your_twilio_phone_number"
DOMAIN="your_ngrok_domain"
OPENAI_API_KEY="your_openai_api_key"

Step 4: Write the Server Code

Open index.js in your favorite text editor and start by importing the necessary modules and setting up environment variables.

import Fastify from 'fastify';
import WebSocket from 'ws';
import dotenv from 'dotenv';
import fastifyFormBody from '@fastify/formbody';
import fastifyWs from '@fastify/websocket';
import twilio from 'twilio';
 
dotenv.config();
 
const { TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, PHONE_NUMBER_FROM, DOMAIN, OPENAI_API_KEY } = process.env;
 
const client = twilio(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN);
const fastify = Fastify();
fastify.register(fastifyFormBody);
fastify.register(fastifyWs);

Define a Number Filter

Create a function to check if a number is allowed to be called.

async function isNumberAllowed(to) {
  try {
    const incomingNumbers = await client.incomingPhoneNumbers.list({ phoneNumber: to });
    if (incomingNumbers.length > 0) {
      return true;
    }
    const outgoingCallerIds = await client.outgoingCallerIds.list({ phoneNumber: to });
    if (outgoingCallerIds.length > 0) {
      return true;
    }
    return false;
  } catch (error) {
    console.error('Error checking phone number:', error);
    return false;
  }
}

Make an Outbound Call Function

Create a function to make an outbound call using Twilio.

async function makeCall(to) {
  try {
    const isAllowed = await isNumberAllowed(to);
    if (!isAllowed) {
      console.warn(`The number ${to} is not recognized as a valid outgoing number or caller ID.`);
      process.exit(1);
    }
 
    const call = await client.calls.create({
      from: PHONE_NUMBER_FROM,
      to,
      twiml: outboundTwiML,
    });
    console.log(`Call started with SID: ${call.sid}`);
  } catch (error) {
    console.error('Error making call:', error);
  }
}

Initialize and Launch the Server

Set up the server to listen on a specified port and initiate an outbound call.

fastify.listen({ port: PORT }, (err) => {
  if (err) {
    console.error(err);
    process.exit(1);
  }
  console.log(`Server is listening on port ${PORT}`);
 
  const args = process.argv.slice(2);
  const phoneNumberArg = args.find(arg => arg.startsWith('--call='));
  if (!phoneNumberArg) {
    console.error('Please provide a phone number to call, e.g., --call=+18885551212');
    process.exit(1);
  }
  const phoneNumberToCall = phoneNumberArg.split('=')[1].trim();
  makeCall(phoneNumberToCall);
});

Run and Test Your Code

  1. Launch ngrok to expose your server to the internet.
  2. Set the DOMAIN variable in your .env file to the ngrok forwarding address.
  3. Run the Twilio Dev Phone or use a verified caller ID.
  4. Place an outbound call using the command:
node index.js --call=+18005551212

Conclusion

Congratulations! You have successfully created an AI voice assistant that can make outbound calls using Twilio Voice and the OpenAI Realtime API. For more advanced features, check out the Twilio documentation and OpenAI's Realtime API docs.


Reference: Twilio Blog, Author: Paul Kamp


Want to read more tutorials? Check out our latest tutorial on 4 Laravel 11 Basics: CSRF Protection.

Discuss Your Project with Us

We're here to help with your web development needs. Schedule a call to discuss your project and how we can assist you.

Let's find the best solutions for your needs.