Making Voice Calls with Java and Twilio

April 23, 2021
Written by
Reviewed by

Title: Making Voice Calls with Java and Twilio

The capability to make outbound calls from code has a long history at Twilio. It will only take you a few minutes to set up a Java project to do just that and see the magic for yourself. To follow along with this post you'll need:

The easiest way to call the Twilio API is with the Java Helper Library. In this tutorial I'll give examples using the Apache Maven build tool, which will download and manage the dependency and package the project. You can get up to speed with Maven in 5 Minutes, and other tools like Gradle will work, too, if that's what you prefer.

If you want to skip to the end, check out the completed project on GitHub.

Creating a new project

The first thing you need to do is create a new project. Create a new directory and open your IDE.

A new Maven project

You can create a new Maven project in IntelliJ IDEA using these settings:

Screenshot of IntelliJ maven configuration, config as described in the prose.

It's also possible to create the same setup from the command line by creating a directory for your source code using the standard directory structure with mkdir -p src/main/java and a file called pom.xml with this content:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>java-make-voice-calls</artifactId>
    <version>1.0-SNAPSHOT</version>

</project>

[this code on GitHub]

To finish up the project's configuration, we need to tell Maven to download the Twilio Helper Library for Java and to use Java 8 (any newer version would be fine too).  Update the pom.xml file to make sure that the following properties and dependency are present:

<properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>com.twilio.sdk</groupId>
        <artifactId>twilio</artifactId>
        <version>8.10.0</version>
    </dependency>
</dependencies>

We always recommend using the latest version of the Twilio Helper Library. At the time of writing the latest version is 8.10.0 but new versions are released frequently. You can always check the latest version at mvnreporistory.com.

On to the code

Inside src/main/java create a class called TwilioMakeVoiceCall with a package of org.example. The directory structure will be:

├── pom.xml
└── src
    └── main
        └── java
            └── org
                └── example
                    └── TwilioMakeVoiceCall.java

Start off the TwilioMakeVoiceCall class with a main method:

package org.example;

public class TwilioMakeVoiceCall {

    public static void main(String[] args) {
        //code will go in here
    }
}

[this code on GitHub]

In the main method, you need to do two things:

  • Authenticate the Twilio client with your Account SID and Auth Token
  • Call the API to make someone's phone ring

Let's see what that code looks like.

Authenticate the Twilio client

You'll need your ACCOUNT_SID and AUTH_TOKEN from your Twilio Console. You should keep these secret, so I'd always recommend reading these from environment variables rather than hard-coding them.  I use the EnvFile plugin for IntelliJ IDEA, and there are alternatives for other IDEs or you can set them in your OS. Once they are set in the environment, add this code in the main() function body:

Twilio.init(
    System.getenv("TWILIO_ACCOUNT_SID"),
    System.getenv("TWILIO_AUTH_TOKEN"));

This code will throw com.twilio.exception.AuthenticationException: Username can not be null if you have not set the environment variables.

Make your first call

After you have authenticated your Twilio client, use the following code in your main method to make a phone call:

String helloTwiml = new VoiceResponse.Builder()
    .say(new Say.Builder("Hello from Twilio")
        .voice(Say.Voice.POLLY_MATTHEW).build())
    .build().toXml();

Call call = Call.creator(
        new PhoneNumber("<TO - your cellphone number>"),
        new PhoneNumber("<FROM - your Twilio number>"),
        new Twiml(helloTwiml))
    .create();

System.out.println(call.getSid());

[this code including imports on GitHub]

Replace the notes on lines 7 and 8 with real phone numbers, in E.164 format.

This code does three things:

  • Creates some instructions for what Twilio should do during the call
  • Creates the call, using those instructions and the "to" and "from" phone numbers
  • Prints out the call SID

Let's look at these in a bit more detail.

Instructions for the call

Twilio takes instructions in a language we call TwiML, short for Twilio Markup Language The TwiML generated by the code above is:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say voice="Polly.Matthew">Hello from Twilio</Say>
</Response>

This is the "Hello World" of TwiML - there are a lot more possibilities. You can Say messages, Play recordings, Record the call, Gather speech or DTMF tones, create Conference calls, Stream audio to another service, and do a lot more.

Creating the call

The Call.creator(...) method above takes the "to" and "from" numbers as well as the TwiML code. In this case, we've provided the TwiML directly as a String. Another option is passing a URL instead of TwiML. Twilio will make a request to that URL, passing in metadata about the call, and the response should contain the TwiML that will be used.

There are a few options for hosting TwiML on Twilio:

  • TwiML Bins: fixed TwiML, useful for quick prototyping or simple services.
  • Twilio Functions: a serverless JavaScript platform which can have complex logic or call out to other online services

For the ultimate flexibility you can host your own web service using any stack you like. As long as you return valid TwiML with a content-type of application/xml you're good to go.

The call SID

Every call that Twilio makes or receives is given a String Identifier (SID). You can use the SID to look up the details of the call (status, duration, cost) in the Call Logs page on the Twilio console.

Summing up

Now you know how to make calls with Java and Twilio something you could learn next might  be how to handle inbound calls. Or perhaps you'd like to learn how to send and receive SMS messages.

It's time to put your imagination to work — what will you build next? Whatever you make with Java and Twilio, I'd love to hear about it! Please get in touch:

I can't wait to see what you build!