Tropo is part of CiscoLearn More

A Simple Call Center sample application

Posted on May 10, 2016 by Tim Scheuering

The challenge of building a basic call center application using Tropo might seem a bit overwhelming, so over the next few weeks, we’ll build one from a basic starting point we have here, to something that will demonstrate how a small business can use Tropo to answer, queue, and route their calls.

In this first part, we’ll have an inbound call from a customer that triggers an outbound call to an agent and places them both in the same conference. We’ve received many requests for a tutorial on how to record all conference participants, so this guide includes a simple recording function as well.

Why a conference instead of a transfer? A conference will let us do some interesting things later on, like adding a listen only mode for a supervisor or splitting the agent and caller legs to let them act separately.

Here’s the major components of this application (and provided info to help familiarize yourself with RESTful events) to try and make it simpler.

First, let’s create an overview of what we need:

  • A call director, to separate logic based on session type
  • An agent function, to handle agent joins/parts
  • An inbound caller function, to handle the initial call

Because JavaScript has no built in HTTP client, we’ll use a snippet from the knowledge base to simplify the REST calls:

function httpGet(url){ //Performs GET requests here 
	connection = new;
	connection.setRequestProperty("Content-Type", "text/plain");
	connection.setRequestProperty("charset", "utf-8");

	dis = new;
	while (dis.available() !== 0) {
		line = dis.readLine();

This will be the platform for all REST GET requests used in our application.

Because we need to record audio and launch user applications, we want to set some variables early on:

//Predefined Variables

var token = "MYTOKEN";
var launchURL = "";
var ftpAddress = ""
var ftpUserName = "USERNAME";
var ftpPassword = "PASSWORD";
var queueNumber = "+13215556677";

You need to change the values above to match those specific to your applications.

Next, we need to set up the basic call director structure:

var incoming = false; //Variable Constructor

if(currentCall){ //If the call is inbound, set incoming to true
 incoming = true;

if (incoming) {
	InboundLeg(currentCall.sessionId + "", token, launchURL, ftpAddress, ftpUserName, ftpPassword, queueNumber);
} else if (theCall == "agent") {
	call("+" + theAgentNumber);
	AgentLeg(currentCall.sessionId, theConfID, ftpAddress, ftpUserName, ftpPassword);
} else {
	log("xxxxxxxxxxLOGxxxxxxxxxx - ERROR: NO DIRECTION");

Notice in the above code, variables like theAgentNumber and theCall are passed parameters. More on parameters can be found in our Quickstart Documentation:

Now that we configured which direction the call is going before any real logic is performed, let’s generate the logic for each leg:

function InboundLeg(mySessionID, myToken, myLaunchURL, myFTP, myUN, myPW, myNumber) { //For Inbound Portion of Call
	startCallRecording("ftp://" + myUN + ":" + myPW + "@" + myFTP + "INBOUND-" + mySessionID + ".wav");

	say("Thank you for contacting the Call Center Template application.");

	say("We are connecting you to an agent now.");

	httpGet(myLaunchURL + myToken + "&theConfID=" + mySessionID + "&theCall=agent&theAgentNumber=" + myNumber);


function AgentLeg(mySessionID, myConfID, myFTP, myUN, myPW) { //For Agent Portion of Call
	log("xxxxxxxxxxLOGxxxxxxxxxx - " + mySessionID);
	startCallRecording("ftp://" + myUN + ":" + myPW + "@" + myFTP + "INBOUND-" + myConfID + "-AGENT-" + mySessionID + ".wav");

	say("Connecting you to a caller now");


You may notice the passed arguments to the AgentLeg function contain both the original caller’s sessionID (called myConfID at this point), as well as its own sessionId, to distinguish all interactions with the user from others.

At this point, the basic application is complete. A user calls in and is directed to an inbound leg. This leg then relaunches your application with agent leg details in place using the HTTP GET request with your application’s launch token. The agent leg then calls into the queue’s main number first, but can be changed to call into any number via a REST launch parameter. This allows you to transfer or connect new agents to the current inbound caller at will.

The complete, functioning code is available on Github.

S3 Recordings, ring detection, and a heap of improvements

Posted on March 7, 2016 by Adam Kalsey

Today’s Tropo release has bunch of improvements and bug fixes in it. You can read the full change log as usual, but I’m going to highlight two new features here: recording upload to Amazon S3, and a new event that lets your code know when an outgoing call is ringing. All these changes are available now in the developer environment so you can start using them in your applications now. They will be promoted to the production environment in a few weeks.

Tropo’s recording feature currently can upload a recording to your server by FTP, SFTP, HTTP post, or HTTP Put. A popular request is the ability to push a recording to an Amazon S3 bucket, and we’ve in the past published sample code and blog posts showing how to do that by using HTTP Post to your own server and then pushing to S3. Today’s release adds the ability for Tropo to push to your own S3 bucket natively – no middle layer required.

In keeping with Tropo’s API design philosophy, we layered this new S3 support into our existing API so instead of giving you any new API calls to learn, we just taught the ones you already know a new trick. To use S3 as your recording storage, you’ll first need to set up an S3 bucket with Amazon. Then, in your Tropo application, set the record method to “s3” and the recording URL to the S3 bucket plus file name you want to use, for example Use your AWS Access Key ID as the recording username and the AWS Secret as the recording password.

Here’s a Javascript example showing startCallRecording uploading to an S3 bucket. The recording file name is the caller ID.

startCallRecording("" + currentCall.callerID + ".wav", {
recordPassword: "apPetuyEqfmc3mIygtjOU812GClNG+Oh0lJbe1meB",
method: "s3"
say("This is a recording test!");
say("Thanks for calling");

Tropo’s new onRinging event is available in the call() or transfer() functions. It is triggered when the number you’re calling begins ringing. This allows applications that want to track state changes on a call to track the ring. For example, if you’re building a web interface that lets a person make calls to a list of people, you might show the status of every call on the interface: ringing, answered, no answer, hung up.

Using onRinging is the same as using other Tropo events such as onAnswer or onBusy: define a function and that function will run when a call enters a ringing state. The onRinging event is only available in Tropo’s Scripting API.

Other changes in this release include an updated Ruby version, some SIP interoperability improvements, and lots of small usability improvements on both the web site and in how Tropo behaves in error conditions. Read the full change log if you’re interested in the details.

Announcing Tropo in Europe

Posted on February 12, 2016 by Team Tropo

EU flagWe are off to a rocking great year fueled by you, our growing customer base, as well as the synergies from the broader Cisco ecosystem. On top of us lowering our domestic prices on the first day of 2016 we have more exciting news for you:

Tropo will be coming to Europe in spring 2016 as is our response to customer requests for tighter alignment to European privacy and data security laws. With this upcoming launch, we’ll be enabling a protected instance of Tropo in the UK serving all of our European customers.

We have leveraged our deep experience putting Tropo in private, highly secure data centers around the world and will release our European instance with your data privacy in mind. Your confidential data will remain within the borders of the EU and we will be able to provide you with the highest call quality and lowest latency for EU to EU calls out of our portal.

Initially, when we launch this spring, we will have some additional processes in place: For example to get numbers in Germany you have to provide your proof of address.

We will provide more details over the next few months at If you cannot find what you are looking for or need more information, please contact

We hope you are as excited as we are that we are finally able to deliver a product that will resonate with companies of all sizes in a very important market to us.

Come see us in action!

For those of you at Cisco Live! Berlin next week, we invite you to stop by the Tropo booth in the DevNet Zone to learn more about this announcement and receive a demo of our voice and SMS offerings. There will also be a series of Tropo API introductory sessions and learning labs available throughout the week. View the session times and locations here.

Be sure to follow us on Twitter @Tropo for the latest information, tips and events that we will be at!