Control Your Tropo Scripts with External Events

January 20th, 2011 by Mark Headd

A few weeks back, Adam Kalsey introduced an exciting new piece of functionality on the Tropo platform – the ability to control a Tropo script by injecting events into a running session.

This type of functionality has lots of very cool applications – you can break a caller out of a long running process, or stop an executing action like a conference or a transfer. And what’s even cooler, now you can have access to all of this functionality through the existing Tropo WebAPI library for PHP.

Here is a quick example to demonstrate how to use external events to interrupt an executing action – in this case, an inbound call to a Tropo script that performs a transfer to another number.

Say, for example, that you wanted to limit the amount of time that a caller could stay on the transfer. With external events, it’s a snap.

Consider the follow sample script.

// Include required classes.
require 'classes/tropo.class.php';
require 'classes/sag/sag.php';

// Grab the raw JSON sent from Tropo.
$json = file_get_contents("php://input");

// Create a new Session object and obtain the session ID value.
$session = new Session($json);
$session_id = $session->getId();

// Insert the Session object into a CouchDB database called sessions.
try {
	$sag = new Sag();
	$sag->setDatabase("sessions");
	$sag->put($session_id, $json);	
}
catch (SagCouchException $ex) {
	die("*** ".$ex->getMessage()." ***");
}

// Create a new Tropo object.
$tropo = new Tropo();

$tropo->say("Please hold while your call is transferred.");
$tropo->transfer("5551112222", array("from" => "7861112233", "allowSignals" => "transferOver"));

// Set event handlers
$tropo->on(array("event" => "continue", "next" => "hangup.php?uri=end&timeout=false"));
$tropo->on(array("event" => "transferOver", "next" => "hangup.php?uri=end&timeout=true", "say" => "You have reached the time limit. Transfer over"));

// Render JSON for Tropo to consume.
$tropo->renderJSON();

As you can see, I’m using a property of the WebAPI Transfer object called “allowSignals” and giving it a value of transferOver. This is the name of the external event we want to send to our script. When it is received, our Tropo script will end execution of the transfer and invoke the handler set up for the transferOver event.

In order to control a Tropo script with external events, we need to know the unique ID for the session the Tropo script is executing in. We can get this from the Session object which is sent to our script at the inception of the call.

$session = new Session($json);
$session_id = $session->getId();

We want to store this session ID somewhere so that we can access it when we want to end an outbound transfer that has gone on longer than some set time interval. For the purposes of this example, I’m just going to stick it into a running instance of CouchDB. Since the session ID for our Tropo script is globally unique, we can use it as the document ID for our CouchDB document.

In this example, I’ using the very handy Sag CouchDB library for PHP. It’s dead simple, and makes working with CouchDB from PHP a snap.

For this example, I’m using a fresh CouchDB database named “sessions.” Because we want to insert a CouchDB document with a specific document ID, we’re going to do an HTTP PUT – we do this by simply invoking the put() method of the sag object:

$sag = new Sag();
$sag->setDatabase("sessions");
$sag->put($session_id, $json);	

Now we can send a transferOver event to the session running our Tropo script. This is easy to do with the new sendEvent() method of the Tropo class.

Here is a simple script that uses this method to send an event to a running script:

#! /usr/bin/php
<?php

if(empty($argv[1])) {
	die("*** You must use a Session ID with this script ***\n");
}

$session_id = $argv[1];
$event_name = $argv[2];
$path_to_classes = $argv[3];

require $path_to_classes.'/tropo.class.php';
$tropo = new Tropo();

try{

	if($tropo->sendEvent($session_id, $event_name)) {
		echo "Event { $event_name } successfully queued.\n";
	}
	else {
		echo "ERROR: Could not queue event { $event_name }.\n";
	}

}

catch(TropoException $ex) {
	die("*** There is big trouble in River City: ".$ex->getMessage()." ***");
}

After you make this script executable, you simply invoke it by:

  • Giving it the id of the session to send an event to;
  • The name of the event to send, and;
  • The path to the Tropo WebAPI library files.

When invoked, it will generate a response like this:

{"status": "QUEUED"}

This means that the event is queued and will be delivered to the session that is running our script.

When the event is delivered to the script, it interrupts the ongoing transfer and causes a Result object to be sent to the URL specified in the transferOver event handler. The JSON for the Result object looks like this:

{
    "result": {
        "sessionId": "bc9fe7edf356cfa045cf6d814ff07bf1",
        "callId": "b7feb41c8e50768733a8875713d5541e",
        "state": "ANSWERED",
        "sessionDuration": 94,
        "sequence": 1,
        "complete": true,
        "error": null,
        "actions": {
            "disposition": "EXTERNAL_EVENT"
        }
    }
}

Note the disposition value in this object – EXTERNAL_EVENT – this lets your application know that the result was caused by an external event being injected into the Tropo session.

This functionality opens up a host of new avenues for Tropo developers to build sophisticated applications.

We’ll be adding this functionality to other Tropo libraries in the days ahead, and if you use Tropo scripting it’s already available to you.

Have fun!

Related posts:

  1. Connecting to an External Database with Tropo Scripting
  2. New at Tropo: SSL and REST APIs for provisioning & remote control
  3. Weekend Hacking and Events
  4. New Guidelines for Naming Tropo Web API Language Libraries (ruby, PHP, python, C#)
  5. Hacking History with Tropo

Tags: couchdb, Events, PHP, webapi

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

Click here to cancel reply.

Please note: By submitting a comment you agree to comply with our Comment Policy. We welcome all comments, positive or negative, but do reserve the right to remove all or part of blog comments that do not comply with our policy.

Additionally, the first time you leave a comment on this blog, it will be held for moderation. After that first comment has been approved, future comments will be posted without delay.

Additional comments powered by BackType


gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.