Vocode supports using agents with inbound and outbound phone calls. Users can create their own agents and use them to fulfill a variety of use cases like information collection, appointment scheduling, sales, customer support, and more.
- Ngrok (used to host the
a. If you have Homebrew installed, run
brew install ffmpeg
a. If you have Homebrew installed, run
brew install redis
- (optional) Docker
- Copy the
.env.templatefile and fill in the values of your API keys. You’ll need to get API keys for:
- Deepgram (for speech transcription)
- OpenAI (for the underlying agent)
- Azure (for speech synthesis)
- Twilio (for telephony)
cp .env.template .env
- Set up hosting so that Twilio can hit your server. An easy way to do this is
ngrok: in our code we set it up to be running on port 3000, run:
ngrok http 3000
Copy the URL that is tunneling localhost:3000 to your
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.
Running the server
Pick one of these two ways to run the server: 1. Run everything with Docker, 2. Run Python directly
Option 1: Run everything With Docker
- Build the telephony app Docker image. From the
docker build -t vocode-telephony-app .
- Run the application using
docker-compose. From the
Option 2: Run Python directly
Run the following steps from the
- Install Poetry and install dependencies.
- Run Redis with the default port of 6379.
For example, using Homebrew:
brew services start redis
Or if you prefer to use Docker for this part:
docker run -dp 6379:6379 -it redis/redis-stack:latest
- Run the server with
uvicorn(should be already installed in step 1).
poetry run uvicorn main:app --port 3000
Setting up an inbound number
- Create a Twilio account
- Once inside your dashboard, go to Phone Numbers -> Manage -> Buy a number to get a phone number.
- Then, go to Phone Numbers -> Manage -> Active Numbers and select the number you want to set up.
- Update the config to point the Webhook URL to
https://<YOUR BASE URL>/inbound_call- if you’re using
ngrok, it looks like
- Hit Save and call the number!
Executing outbound calls
Make sure the server we just set up is already running. Then, in
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.
telephony_app.py) classes can accept a
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
class SpellerAgentConfig(AgentConfig, type="agent_speller"): pass class SpellerAgent(BaseAgent): def __init__(self, agent_config: SpellerAgentConfig): super().__init__(agent_config=agent_config) async def respond( self, human_input, conversation_id: str, is_interrupt: bool = False, ) -> Tuple[Optional[str], bool]: return "".join(c + " " for c in human_input), False class SpellerAgentFactory(AgentFactory): def create_agent(self, agent_config: AgentConfig) -> BaseAgent: return SpellerAgent(agent_config=agent_config)
AgentFactory instance is passed into the
We provide a small set of agents with already created
AgentConfigs, including, importantly, one that sets up ChatGPT with a configured prompt: see our
Python Quickstart for more info.
Accessing call information in your agent
We store the
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:
class SpellerAgent(BaseAgent): def __init__(self, agent_config: SpellerAgentConfig): super().__init__(agent_config=agent_config) self.config_manager = RedisConfigManager() async def respond( self, human_input, conversation_id: str, is_interrupt: bool = False, ) -> Tuple[Optional[str], bool]: call_config = self.config_manager.get_config(conversation_id) if call_config is not None: from_phone = call_config.twilio_from to_phone = call_config.twilio_to return "".join(c + " " for c in human_input), False