How to use agents with inbound and outbound phone calls.
TelephonyServer
locally)brew install ffmpeg
brew install redis
.env.template
file and fill in the values of your API keys. You’ll need to get API keys for:ngrok
: in our code we set it up to be running on port 3000, run:.env
without https://
, e.g.
TelephonyServer
is–as implied by the name–a server that is responsible for
receiving and making phone calls.
The server is built using FastAPI and utilizes Twilio for telephony services.
Clone the Vocode repo or copy the Telephony app directory.
telephony_app
directory, run:docker-compose
. From the telephony_app
directory, run:telephony_app
directory.
uvicorn
(should be already installed in step 1).https://<YOUR BASE URL>/inbound_call
- if you’re using ngrok
, it looks like https://asdf1234.ngrok.app/inbound_call
outbound_call.py
Replace the to_phone
with the number you want to call and the from_phone
with the number you want to call from. In order to make a call from the from_phone
, you must have access to it via Twilio (either a number purchased via Twilio or verify the caller ID).
Note: To ensure legal compliance with robocall regulations in California, the following code snippet from the Vocode library utilizes Twilio Line Intelligence to check if calls are made to mobile phones: For Canadian phone numbers, the Twilio Lookup API may not return carrier data due to the Canadian Local Number Portability Consortium (CLNPC) requirements. More information on this issue can be found in the Twilio Support Article.Run the script with
poetry run python outbound_call.py
.
OutboundCall
(in outbound_call.py
) and InboundCallConfig
(in telephony_app.py
) classes can accept a TranscriberConfig
, AgentConfig
or SynthesizerConfig
- the default transcriber is Deepgram and the default synthesizer is Azure.
This example sets up an agent that spells every word that is sent to it - any text-in, text-out function can be turned into a voice conversation by subclassing BaseAgent
and creating an AgentFactory
.
AgentFactory
instance is passed into the TelephonyServer
in telephony_app.py
.
We provide a small set of agents with already created AgentConfig
s, including, importantly, one that sets up ChatGPT with a configured prompt: see our Python Quickstart
for more info.
to
and from
numbers in the ConfigManager
- so
if you’d like to access them in your agent, you can instantiate the manager to hook into the same Redis instance:
OutboundCall
class provides a simple abstraction for creating outbound calls.
TelephonyServer
from above to be running.
OutboundCall
calls Twilio to initiate the call, giving it a URL to call after the call is initiated:
TelephonyServer
. The TelephonyServer itself includes a couple of routers:
TwiMLRouter
CallsRouter
TwiMLRouter
includes the matching route:
connect_call.xml
which uses TwiML to tell Twilio to establish a websocket with a given URL:
Call
object and start it:
Call
is a kind of StreamingConversation
that manages the various pieces: transcriber, synthesizer, agent, etc.
InboundCallServer
class provides a simple abstraction to create an endpoint that can host your agent
to respond to inbound calls. In order to implement an inbound call agent, start by defining an InboundCallServer
like so:
/vocode
route that returns a TwiML object that we will need in the next
step. If you’re using our Replit template, this is already set up for you!
Next, we’ll set up a programmable phone number on Twilio that can accept the TwiML object from
above. To do this,
Tip: if you already have existing Twilio integrations, set up the number in a subaccount
TWILIO_ACCOUNT_SID
and TWILIO_AUTH_TOKEN
in your environment. If you’re using Replit, use Replit secrets. Otherwise, packages like python-dotenv are useful for this./vocode
route we just set up. ngrok one option to quickly to host the server.
If you’re using the Replit template, use the provided hosted URL that looks something like https://<repl>.<username>.repl.co/vocode