We've seen how to create Tasks using the TaskRouter REST API and how to accept a Task Reservation using both the REST API and Assignment Callback instructions. TaskRouter also introduces new TwiML instructions that you can use to create a Task from a Twilio phone call.
To receive an incoming phone call, we first need a Twilio phone number. In this example we'll use a US toll-free number, but you can use a Voice capable number from any country.
Before purchasing or setting up the phone number, we need to add on to our TwilioTaskRouterServlet
to handle incoming calls:
1import java.io.IOException;23import javax.servlet.http.HttpServlet;4import javax.servlet.http.HttpServletRequest;5import javax.servlet.http.HttpServletResponse;67import com.twilio.Twilio;8import com.twilio.rest.taskrouter.v1.workspace.Task;9import com.twilio.rest.taskrouter.v1.workspace.task.Reservation;10import com.twilio.twiml.Gather;11import com.twilio.twiml.Say;12import com.twilio.twiml.TwiMLException;13import com.twilio.twiml.VoiceResponse;1415public class TwilioTaskRouterServlet extends HttpServlet {1617private String accountSid;18private String authToken;19private String workspaceSid;20private String workflowSid;2122@Override23public void init() {24accountSid = this.getServletConfig().getInitParameter("AccountSid");25authToken = this.getServletConfig().getInitParameter("AuthToken");26workspaceSid = this.getServletConfig().getInitParameter("WorkspaceSid");27workflowSid = this.getServletConfig().getInitParameter("WorkflowSid");2829Twilio.init(accountSid, authToken);30}3132// service() responds to both GET and POST requests.33// You can also use doGet() or doPost()34@Override35public void service(final HttpServletRequest request, final HttpServletResponse response)36throws IOException {37if (request.getPathInfo() == null || request.getPathInfo().isEmpty()) {38return;39}4041if (request.getPathInfo().equals("/assignment_callback")) {42response.setContentType("application/json");43response.getWriter().print("{\"instruction\":\"accept\"}");44} else if (request.getPathInfo().equals("/create_task")) {45response.setContentType("application/json");46response.getWriter().print(createTask());47} else if (request.getPathInfo().equals("/accept_reservation")) {48response.setContentType("application/json");49final String taskSid = request.getParameter("TaskSid");50final String reservationSid = request.getParameter("ReservationSid");51response.getWriter().print(acceptReservation(taskSid, reservationSid));52} else if (request.getPathInfo().equals("/incoming_call")) {53response.setContentType("application/xml");54response.getWriter().print(handleIncomingCall());55}56}5758public String createTask() {59String attributes = "{\"selected_language\":\"es\"}";6061Task task = Task.creator(workspaceSid, attributes, workflowSid).create();6263return "{\"task_sid\":\"" + task.getSid() + "\"}";64}6566public String acceptReservation(final String taskSid, final String reservationSid) {67Reservation reservation = Reservation.updater(workspaceSid, taskSid, reservationSid)68.setReservationStatus(Reservation.Status.ACCEPTED).update();6970return "{\"worker_name\":\"" + reservation.getWorkerName() + "\"}";71}7273public String handleIncomingCall() {74VoiceResponse twiml =75new VoiceResponse.Builder()76.gather(new Gather.Builder()77.say(new Say.Builder("Para Español oprime el uno.").language(Say.Language.ES)78.build())79.say(new Say.Builder("For English, please hold or press two.")80.language(Say.Language.EN).build())81.numDigits(1).timeout(5).build())82.build();8384try {85return twiml.toXml();86} catch (TwiMLException e) {87return "Error creating TwiML: " + e.getMessage();88}89}90}
You can use the Buy Numbers section of the Twilio Voice and Messaging web portal to purchase a new phone number, or use an existing Twilio phone number. Open the phone number details page and point the Voice Request URL at your new endpoint:
Using any phone, call the Twilio number. You will be prompted to press one for Spanish or two for English. However, when you press a digit, you'll hear an error message. That's because our <Gather>
verb is pointing to another endpoint, enqueue_call
, which we haven't implemented yet. In the next step we'll add the required endpoint and use it to create a new Task based on the language selected by the caller.