Introduction

The Phono SDK provides an object-oriented JavaScript API for embedding two-way audio and chat onto any web page. The Phono SDK is a pure client-side solution and requires zero server-side logic on your part; all communication is handled transparently by the Tropo Cloud.

But enough introduction - let's dive right in.

Setup

First things first, if you don't have an API Key, please take a minute to sign up for one here. The developer API Key will allow you to track your calls and get access to some killer analytics in future versions. Check out the Phono Object API Reference for more info.

The Phono SDK ships as a jQuery plugin. Just include it at the top of your page and you're ready to start making calls!

 <script src="http://s.phono.com/releases/1.1/jquery.phono.js"></script>

If you're developing from a local file system (i.e. not a web server) you'll need to edit your Flash security settings. Select "Edit locations" > "Add location" > "Browse for folder" and select the the folder that contains your HTML files.

This guide is full of great code samples and will guide you through all the features in the SDK. For the impatient, here's a working example to whet your appetite. Upload this to a web server and give it a try.

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    <script src="http://s.phono.com/releases/1.1/jquery.phono.js"></script>
  </head>
  <body>

    <input id="call" type="button" disabled="true" value="Loading..." />
    <span id="status"></span>

    <script>
    $(document).ready(function(){
      var phono = $.phono({
        apiKey: "",
        onReady: function() {
          $("#call").attr("disabled", false).val("Call");
        }
      });

      $("#call").click(function() {
        $("#call").attr("disabled", true).val("Busy");
        phono.phone.dial("985-655-2500", {
          onRing: function() {
            $("#status").html("Ringing");
          },
          onAnswer: function() {
            $("#status").html("Answered");
          },
          onHangup: function() {
            $("#call").attr("disabled", false).val("Call");
            $("#status").html("Hangup");
          }
        });
      });
    })
    </script>

  </body>
</html>

Get Started

The Phono SDK is pretty simple and consists of only four main objects.

$.phono() To make use of the Phono SDK, you'll first need to create a Phono Object. The easiest way to do this is using the $.phono() jQuery plugin. Phono Objects maintain a connection to the Tropo Cloud and enable every feature of the SDK. We'll learn more about the Phono obejct in the next chapter.
Phone The Phone Object is central to the Phono SDK. Phones can place and receive calls, handle keypad input and control various audio levels. Phone Objects even let you customize incoming and outgoing ring tones!
Call The Call object represents a single incoming or outgoing call. Outgoing calls are created using the Phone.dial() function, whereas incoming calls are provided by the incomingCall event on an existing Phone. See the Making Calls and Receiving Calls sections for more detailed information.
Message The Phono Messaging API turns your browser into a full fledged IM client. Messages are sent and received using the XMPP protocol, but you woudn't know that as the SDK handles all the details for you. Outgoing messages are sent using the Messaging API's send function whereas incoming messages are provided by the a "message" event. We'll cover message events and related topics later in this guide.

The rest of this chapter will introduce the main concepts of the Phono SDK by example. For a complete list of functions, properties and events, see the API Reference at the bottom of this guide.

$.phono()

To start making calls, a Phono Object must be created using the $.phono() jQuery plugin. Upon creation, Phono will connect to the Tropo Cloud. This connection bridges the web browser with Tropo's real-time network service and is capable of making a call, sending and receiving instant messages and/or SMS and much more.

Here's a basic example that creates a Phono Object and logs its connection status to the console:

$.phono({
  onReady: function() {
    console.log("Phono is ready!");
  },
  onUnready: function() {
    console.log("Phono is not ready!");
  }
})

In addition to managing the connection to the cloud, a Phono Object is also the entry point into all of the Phono SDK's calling and messaging features. Phono is based on a plugin-architecture that allows additional features to be added over time. For now, the two plugins available in the SDK are the Phone API and the Messaging API. The following sections will cover the basics, but for a complete list of functions see the API Reference bellow.

Making Calls

The single coolest feature of the Phono SDK is the ability to place calls via various networks using a single API. Using Phono, your browser can place calls to SIP Voice over IP devices (VoIP), other Phono clients, any Tropo application and of course regular phone numbers.

Regular Calls

For demonstration purposes, the Phono SDK can natively make calls to any US toll-free number. Just use the Phone Object's dial method and off you go. These demo calls are are sponsored by Tropo and are limited to 10 minutes. To call numbers other than US toll free numbers, and for longer calls, you can easily create a Tropo application that relays your Phono call to any phone number you would like.

$.phono({
  onReady: function() {
    this.phone.dial("800-777-3456")
  }
})

SIP

The Session Initiation Protocol (SIP) is the workhorse of the internet telephony world. SIP is at the heart of most telephone carriers and is the most prevalent Voice Over IP standard in the world. Luckily for you, Phono can natively call any SIP endpoint right out of the box.

$.phono({
  onReady: function() {
    this.phone.dial("sip:9991443046@sip.tropo.com")
  }
});

Phono-to-Phono

Phono Objects receive a Session ID on connection. The Phono SDK once again leverages the awesomeness of the Tropo network to route calls between Phono clients using the SIP protocol. Simply add "sip:" to a Phono Object's Seesion ID and you have a fully working SIP address for your web browser!

$.phono({
  onReady: function() {
    alert("My Address address is sip:" + this.sessionId);
  }
});

Tropo Applications

The Tropo platform allow developers to create interactive speech and messaging applications using standard web technologies such as JavaScript, Ruby and Python. Regardless of the language used, these applications can be anything from an interactive banking system to a completely custom team conferencing service. Each Tropo application receives a unique identifier; Phono lets you connect directly with these applications by pre-pending it's Application ID with "app:".


$.phono({
  onReady: function(event, phone) {
    var text = prompt("Enter some text you'd like to hear in Spanish");
    phone.dial("app:9991442945", {
       headers: [
         {
           name:"x-source",
           value:"en"
         },
         {
           name:"x-target",
           value:"es"
         },
         {
           name:"x-text",
           value:text
         }
       ]
    });
  }
});
	

This section covered the basics of making a call. Check out the Call API Reference for a complete list of options and events.

Custom headers

Phono allows developers to pass custom headers, which makes integration into existing voice applications (e.g. Tropo.com ) truly a snap! However, there are a few things you need to know when using them. First, please make sure to preface any custom headers with x- (eg. myHeader => x-myHeader). Second, if you plan to send headers back into the Tropo network (when calling a Tropo application for example), any headers will be downcased by our SBCs ( Session Border Controllers). This means "x-myReallyCoolHeader" will be "x-myreallycoolheader" in your Tropo application.


    $.phono({
      onReady: function(event, phone) {
        phone.dial("app:9991442945", {
           headers: [
             {
               name:"x-foo",
               value:"bar"
             },
             {
               name:"x-name",
               value:"homer"
             }
           ]
        });
      }
    });
    	

Receiving Calls

Phono phones can receive calls too. When a Phono phone connects to the Tropo Cloud, it receives a unique session id. That session id is a fully addressable SIP URI. The ability to address a Phono client via SIP creates a world of possibilities. Imagine a web-based game where each player has their own personal "phone number". Players can chat with each other, join team conferences and plan world domination from the comfort of their browser.

To register an event handler on an incoming call (for example to detect hangup), use the call.bind() method.

Here's a simple example of a Phone receiving a a call. When the call arrives, an alert box is displayed on the browser:

$.phono({
  onReady: function(event) {
    alert("My SIP address is sip:" + this.sessionId);
  },
  phone: {
    onIncomingCall: function(event) {
      var call = event.call;
      alert("Incoming call");
      call.bind({
          onHangup: function(event) {
               console.log("Call hung up");
          });
    }
  }
});

Check out the Kitchen Sink demo for a complete inbound/outbound Phone application.

Ringtones

Phono can use any MP3 as it's ringtone (incoming calls) or ringback tone (outgoing call). Just configure the Phone Object using it's ringTone and ringbackTone properties and you'll be head nodding to your favorite tune before your next call. See the Phone API Reference for details.

Too embarrassed to blare that Britney Spears at the office? We've got you covered with a nice selection of ring tones brought to you by our friend Johhny Diggz.

* All ring tones are distributed royalty free for your bumpin' enjoyment.

Chat Messages

The Phono Messaging API provides a simple API for sending and receiving XMPP messages. The Extensible Messaging and Presence Protocol is the core protocol behind many of the most popular IM networks. For example, Google Talk uses it exclusively for chat, video and voice calling.

With Phono, your web page is instantly capable of sending and receiving chat messages to and from any XMPP compatible network!

Sending Messages

Once Phono is connected, text messages are sent via the Messaging API's send function.

$.phono({
  onReady: function() {
     this.messaging.send("phono-echo@tropo.im","Hello");
  }
});

Receiving Messages

Chatting wouldn't work too well without the ability to receive messages. Phono makes it super easy to receive chat messages in much the same way as Calls.

$.phono({
  onReady: function(event) {
    alert("My XMPP address is " + this.sessionId);
  },
  messaging: {
    onMessage: function(event) {
       var message = event.message;
       alert("Message from: " + message.from + "\n" + message.body);
    }
  }
})

The previous example creates a Phono Object, pops an alert with its XMPP address and then waits for an incoming message. When a message arrives, the onMessage handler fires and an alert box is displayed with the sender's address and the message body.

API Reference

This is the complete API reference for Phono v1.1

Phono Object / $.phono()

var phonoObject = $.phono({

  apiKey: "YOUR_API_KEY_GOES_HERE",

  onReady: function() {
    console.log("Connected");
    console.log("Phono Session ID: " + this.sessionId);
  },
  onUnready: function() {
    console.log("Disconnected");
  }
});

console.log("Connected?  " + phonoObject.connected());

Functions

connect() Connects the Phone to the Tropo Cloud. This is done automatically when the Phone is constructed using the jQuery $.phono() function.
disconnect() Disconnects the Phone from the Tropo Cloud. Phono will automatically disconnect when the web page is closed, so this method is rarely used.
connected() Returns true if the Phono Object is connected

Properties

apiKey Sets the developer apiKey to use when making phone calls. Using an API will allow Phono to provide useful analytics and tracking capabilities in future version. This option must be set when initializing the Phono SDK like so:
$.phono({
  apiKey: "YOUR_KEY_GOES_HERE",
  onReady: function(event) {
    // stuff
  }
});
sessionId Returns the unique Session ID for the Phone instance. Session IDs serve several purposes in the Phono framework. First, it is a globally unique string that can be useful if you're maintaining multiple Phones on a page. Beyond being just an identifier, a Phone's Session ID is also a fully addressable SIP and XMPP address.
audio This property is new to Phono version 0.3 and above. It sets the desired audio client to engage on the web browser or mobile device. Valid options include: auto (default), jsep, flash, java, and none. This property is optional and is defaulted to auto. Auto selects the most appropriate technology to use based on what is available. The order of preference is for webrtc followed by flash as a fallback. A java audio layer is also available which can be detected manually and set if desired:
$(document).ready(function(){ 
             var audioType = 'auto'; 
             if (navigator.javaEnabled()) { 
             audioType = 'java'; 
             } 

             var phono = $.phono({ 
             apiKey: "YOUR_KEY_GOES_HERE", 
             audio: {type:audioType},
             onReady: function(event) { // stuff  } 
             });

Events

ready Dispatched when Phono makes a successful connection to the Tropo Cloud.
unready Dispatched when Phono's connection to the Tropo Cloud has disconnected.

Phone API

$.phono({

  apiKey: "YOUR_API_KEY_GOES_HERE",

  onReady: function() {
    console.log("Phono Connected");
  },

  // Phone API Configuration
  phone: {
    // Same as calling the get/set functions
    ringTone: "http://s.phono.com/ringtones/Diggztone_Agent94.mp3",
    headset: true,

    // Event Handlers
    onIncomingCall: function(event) {
      console.log("Incoming Call: " + event.call.id);
    },
    onError: function(event) {
      console.log("Phone error: " + event.reason);
    }
  }

});

Functions

dial(destination, config) Used to make an outgoing call. This function takes two arguments: the destination, and a config object with additional parameters.

var call = phone.dial("774-271-7100", {
  volume: 80,
  pushToTalk:true,
  headers: [
	{
   	name:"x-foo",
   	value:"bar"
 	},
	{
   	name:"x-bling",
   	value:"baz"
 	}
  ]
});
	
tones(boolean) Gets/Sets whether digit tones should be played on the client.
headset(boolean) When headset is false, Phono will optimize the user experience for your computer's speakers and supress echo.
wideband(boolean) When wideband is false, Phono will optimize the bandwidth of the call for slower connection speeds. Wideband is defaulted to true to provide an HD audio experience to users.
ringTone(string) Gets/Sets an external MP3 file to play when receiving an incoming call. This audio file will start playing as soon as the call arrives and will stop when it's either answered or rejected by calling the Call.hangup() function.
ringbackTone(string) Gets/Sets an external MP3 file to play when placing an outgoing call. This audio file will start playing as soon as the call is dialed and will stop when the call is canceled by invoking Call.hangup(), is answered by the far end, or otherwise fails to complete.

Events

incomingCall Dispatched when a new inbound call has arrived.
error Dispatched when an error is encountered.

Call Object

$.phono({

  apiKey: "YOUR_API_KEY_GOES_HERE",

  onReady: function() {

    console.log("Phono Connected");

    // New calls can be configured inline when dialing
    this.phone.dial("857-239-0087", {

      // Same as calling the get/set functions
      gain: 25,
      volume: 75,
      mute: false,
      pushToTalk: false,

      // Events
      onRing: function() {
        console.log("Ringing");
      },
      onAnswer: function() {
        console.log("Answered");
      },
      onHangup: function() {
        console.log("Hangup");
      },
      onError: function() {
        console.log("Call Error");
      },
    });
  },

  phone: {
    onIncomingCall: function(event) {
      var call = event.call;
      console.log("Auto-answering call with ID " + call.id);
      // Answer the call
      call.answer();
      // Send a 1 as keypad input
      call.digit("1");
    }
  }

});

Functions

answer() When a call arrives via an incomingCall event, it can be answered by calling this function.
hangup() Hangs up an active call.
bind(config) Binds the given functions to the events specified.
digit(string) Sends a touch-tone signal to the remote party. This is equivalent to pressing a key on a touch tone phone.
pushToTalk(boolean) When set to true, Phono will act as a walkie-talkie and the microphone will be muted. When in push to talk mode, toggling the "talking" property is equivalent to pressing and releasing the talk button on a two-way radio. This is useful when using Phono to interact with speech-driven telephone systems or when carrying a conversation without a headset. Most computer microphone's lack the ability to do proper acoustic echo canceling resulting in poor audio quality. Using a computer headset alleviates this problem. Please note that future releases of Phono will include built-in acoustic echo cancelation.
talking(boolean) This setting only applies when pushToTalk is true. When in pushToTalk mode, setting the talking property to true will enable the microphone and slightly mute the incoming audio. When set to false, the microphone will be muted and incoming audio returned to normal.
mute(boolean) Stops sending audio to the remote party.
hold(boolean) Mutes the microphone and stops sending audio to the remote party. Useful if implementing "call waiting" in your Phone.
volume(int) Sets the volume of the call.
gain(int) Sets the microphone gain for the call.

Properties

id Returns the unique identifier for this Call.
state Returns the current state of the Call. Numeric value. Possible values with their meanins in parentheses are:
  • 0 (connected)
  • 1 (ringing)
  • 2 (disconnected)
  • 3 (progress)
  • 4 (initial)
  • 5 (answering)
"Initial" will be set during call setup, before signaling has been sent to the other party. "Progress" means signalling has started, but neither side is ringing yet. Both statuses will only exist for a moment and should be rarely observed.

Events

ring Dispatched when an outbound call is ringing.
answer Dispatched when an outbound call is answered.
hangup Dispatched when a call is terminated by the remote party.
error Dispatched when an error is reported relating to this call.

Messaging API

$.phono({

  apiKey: "YOUR_API_KEY_GOES_HERE",

  onReady: function() {
    console.log("Phono Connected");
    // Send a message as soon as we connect
    this.messaging.send("phono-echo@tropo.im", "Hello");
  },

  messaging: {
    onMessage: function(event) {
      // Get message from event and log it
      var message = event.message;
      console.log(message.from + " says '" + message.body + "'");

      message.reply("ACK");
    }
  }

}); 

Functions

send(to, body) Sends an XMPP message to the user specified by the "to" parameter

Events

message Dispatched when an incoming message is received. The event object's "message" property provides access to the Message. See the Message Object Reference for complete details.

Message Object

Functions

reply(body) Send a reply to the sender of the message.

Properties

from The sender of the message.
body A string reprenting the actual message.

Mobile

Phono Mobile provides an SDK with native iOS and Android components to add voice, IM and real-time messaging to mobile applications. Phono Mobile is in beta and instructions are included in the SDK download.