Ribbit Developer Platform
So, what’s Ribbit? Ribbit is a platform that allows you to add voice to your Flash and Flex applications. Check out my (simple) entry for Ribbit’s first developer challenge.
Once the app has successfully logged in, press the Call Me button to call me at Agile Media Ventures. If your Flash Player supports audio, Flash will ask you to give it access to your microphone. If your Flash Player does not support audio (or if you’re viewing this page on a Mac), you’ll need to enter your phone number and Ribbit will place a bridge call between the phone number you entered and my phone number at Agile Media Ventures.
Check out the Ribbit Developer Platform for more details…
Feel free to leave me a message if you call me via the Ribbit application above. You could leave a short message with your name, location and favorite food
I’ll post the best responses on my blog…
Below is the complete source code for the application. I’m still trying to figure out the best way to format ActionScript code… if you have suggestions, please let me know.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:ribbit="com.ribbit.api.*"
layout="vertical" width="333" height="294" creationComplete="init()" verticalAlign="middle" horizontalAlign="center" backgroundColor="#FFFFFF" verticalScrollPolicy="off" horizontalScrollPolicy="off" currentState="InitialState">
<ribbit:RibbitServices id="request" logLevel="debug"/>
<mx:states>
<mx:State name="PlaceAudioCall">
<mx:SetProperty target="{btnCallMe}" name="visible" value="false"/>
<mx:SetProperty target="{btnCallMe}" name="includeInLayout" value="false"/>
<mx:SetProperty target="{vbox}" name="visible" value="true"/>
<mx:SetProperty target="{vbox}" name="includeInLayout" value="true"/>
<mx:SetProperty target="{btnPlaceCall}" name="visible" value="false"/>
<mx:SetProperty target="{btnPlaceCall}" name="includeInLayout" value="false"/>
<mx:SetProperty target="{hboxPhoneNumber}" name="visible" value="false"/>
<mx:SetProperty target="{hboxPhoneNumber}" name="includeInLayout" value="false"/>
<mx:SetProperty target="{btnPlaceCall}" name="enabled" value="true"/>
</mx:State>
<mx:State name="PlaceBridgeCall">
<mx:SetProperty target="{btnCallMe}" name="visible" value="false"/>
<mx:SetProperty target="{btnCallMe}" name="includeInLayout" value="false"/>
<mx:SetProperty target="{vbox}" name="visible" value="true"/>
<mx:SetProperty target="{vbox}" name="includeInLayout" value="true"/>
</mx:State>
<mx:State name="InitialState">
</mx:State>
<mx:State name="EndState" basedOn="InitialState">
<mx:RemoveChild target="{btnCallMe}"/>
<mx:RemoveChild target="{lblStatus}"/>
<mx:AddChild position="lastChild">
<mx:Text id="txtRibbit" text="Thanks for trying the demo. Visit Ribbit.com for more details." width="100%" height="50" fontFamily="Arial" fontSize="12" fontWeight="normal" textAlign="center"/>
</mx:AddChild>
<mx:RemoveChild target="{lblRibbit}"/>
</mx:State>
</mx:states>
<mx:Script>
<![CDATA[
import flash.system.Capabilities;
import com.ribbit.api.objects.CallState;
import com.ribbit.api.interfaces.ICallObject;
import com.ribbit.api.events.CallEvent;
import com.ribbit.api.RibbitServices;
import com.ribbit.api.interfaces.IRibbitUser;
import mx.core.Application;
import com.ribbit.api.objects.LoginParam;
import com.ribbit.api.events.AuthenticationEvent;
import com.ribbit.api.interfaces.IUserSummary;
import com.ribbit.api.interfaces.IAuthenticationManager;
import mx.utils.ObjectUtil;
public var authMgr:IAuthenticationManager;
/** instance of loginParam which can hold username, password, devID, appID, env, messageComponentName, phoneComponentName, among others */
public var loginParam:LoginParam;
public var appID:String = "";
public var devID:String = "";
private static const USERNAME:String = "(username goes here)";
private static const PASSWORD:String = "(password goes here)";
private static const CALLEE:String = "(phone number to call)";
public static const STATE_ACTIVE:String = CallState.ACTIVE.NAME;
public static const STATE_ANSWERED:String = CallState.ANSWERED.NAME;
public static const STATE_BUSY:String = CallState.BUSY.NAME;
public static const STATE_CONNECTING:String = CallState.CONNECTING.NAME;
public static const STATE_DIALING:String = CallState.DIALING.NAME;
public static const STATE_DISCONNECTING:String = CallState.DISCONNECTING.NAME;
public static const STATE_ERROR:String = CallState.ERROR.NAME;
public static const STATE_HUNGUP:String = CallState.HUNGUP.NAME;
public static const STATE_INCOMING:String = CallState.INCOMING.NAME;
public static const STATE_OUTGOING:String = CallState.OUTGOING.NAME;
public static const STATE_READY:String = CallState.READY.NAME;
public static const STATE_RINGING:String = CallState.RINGING.NAME;
private function init():void {
request = Application.application.request;
authMgr = request.authenticationManager;
request.callManager.addEventListener(CallEvent.CONNECTED, onCallEvent);
request.callManager.addEventListener(CallEvent.DISCONNECTED, onCallEvent);
request.callManager.addEventListener(CallEvent.CALL_CONTROL_CHANGE, onCallControlChange);
login();
}
protected function onCallControlChange(event:CallEvent):void
{
//check event type and ignore types that are not CALL_CONTROL_CHANGE
if ( event.type != CallEvent.CALL_CONTROL_CHANGE )
return;
trace("call control event:", event.oldState, event.newState);
}
private function onCallEvent(event:CallEvent):void
{
switch(event.type)
{
case CallEvent.CONNECTED:
{
if(event.newState == CallState.RINGING)
{
lblStatus.text = "Ringing...";
trace("Ringing...");
}
break;
}
case CallEvent.DISCONNECTED:
{
lblStatus.text = "Disconnected.";
break;
}
case CallEvent.ERROR:
{
break;
}
}
}
private function txtPhoneNumberFocusIn():void {
if (txtPhoneNumber.text == "(your phone number)") {
txtPhoneNumber.text = ""
}
}
private function txtPhoneNumberFocusOut():void {
if (txtPhoneNumber.text == "") {
txtPhoneNumber.text = "(your phone number)"
}
}
private function callMe(event:MouseEvent):void {
var os:String;
var audioCapabilities:Boolean;
// Check capabilities
os = Capabilities.os;
audioCapabilities = Capabilities.hasAudio;
if (os == "MacOS") {
lblMessage.htmlText = "Your Flash player is running on " + os + ".<br><br>Please enter your phone number below and press the Place Call button to place a bridge call to <a href='http://www.agilemediaventures.com'>Agile Media Ventures, LLC.<br><br>Press the Hang Up button when you're finished."
this.currentState = "PlaceBridgeCall"
} else {
if (audioCapabilities) {
lblMessage.htmlText = "Your Flash player is running on " + os + " and audio capabilities are available. Placing call to <a href='http://www.agilemediaventures.com'>Agile Media Ventures, LLC</a>.<br><br>Press the Hang Up button when you're finished."
this.currentState = "PlaceAudioCall"
placeAudioCall();
} else {
lblMessage.htmlText = "Your Flash player is running on " + os + " and audio capabilities are <b>not</b> available.<br><br>Please enter your phone number below and press the Place Call button to place a bridge call to <a href='http://www.agilemediaventures.com'>Agile Media Ventures, LLC.<br><br>Press the Hang Up button when you're finished."
this.currentState = "PlaceBridgeCall"
}
}
}
private function placeAudioCall():void {
lblStatus.text = "";
btnHangUp.enabled = true;
request.callManager.dial(CALLEE);
}
private function placeBridgeCall():void {
btnPlaceCall.enabled = false;
btnHangUp.enabled = true;
lblStatus.text = "";
request.callManager.dial(CALLEE, txtPhoneNumber.text);
}
public function login():void
{
if (authMgr == null)
return;
if (authMgr.loggedIn)
throw new Error("Already logged in.");
authMgr.addEventListener(AuthenticationEvent.LOGGING_IN, loggingIn);
authMgr.addEventListener(AuthenticationEvent.LOGGED_IN, loggedIn);
authMgr.addEventListener(AuthenticationEvent.ERROR, authError);
authMgr.login(USERNAME, PASSWORD, appID, devID, loginParam);
}
public function loggingIn(event:AuthenticationEvent):void
{
lblStatus.text = "Logging in..."
}
public function loggedIn(event:AuthenticationEvent):void
{
lblStatus.text = "Logged in."
btnCallMe.enabled = true;
}
public function authError(event:AuthenticationEvent):void
{
lblStatus.text = "Error logging in. Please try again later."
}
private function hangUp():void {
request.callManager.hangup();
lblStatus.text = "Hanging up...";
currentState = "EndState";
}
private function onChange():void {
if (txtPhoneNumber.length == 10) {
btnPlaceCall.enabled = true;
} else {
btnPlaceCall.enabled = false;
}
}
]]>
</mx:Script>
<mx:Button label="Call Me" width="183" height="69" fontSize="36" id="btnCallMe" click="callMe(event)" enabled="false"/>
<mx:VBox id="vbox" visible="false" includeInLayout="false" width="100%" height="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5" horizontalAlign="center">
<mx:Text id="lblMessage" height="100%" width="100%"/>
<mx:HBox id="hboxPhoneNumber" width="100%" paddingBottom="10" paddingTop="10">
<mx:Label text="Calling Number:"/>
<mx:TextInput id="txtPhoneNumber" text="(your phone number)" width="100%" focusIn="txtPhoneNumberFocusIn()" focusOut="txtPhoneNumberFocusOut()" height="20" change="onChange()"/>
</mx:HBox>
<mx:HBox id="hboxButtons" height="20" width="100%" horizontalAlign="center">
<mx:Button label="Place Call" id="btnPlaceCall" enabled="false" height="20" click="placeBridgeCall()"/>
<mx:Button label="Hang Up" id="btnHangUp" enabled="false" height="20" click="hangUp()"/>
</mx:HBox>
</mx:VBox>
<mx:Label id="lblRibbit" text="Ribbit Developer Community Challenge 1" width="250" height="18" fontFamily="Arial" fontSize="10" fontWeight="normal" textAlign="center"/>
<mx:Label text="" id="lblStatus" width="100%" horizontalCenter="0" textAlign="center" height="22"/>
</mx:Application>Below is a link to the main MXML file. If you’re comfortable with Flex/Flash and ActionScript, the Ribbit API is very easy to use. The code that Ribbit provides in the sample applications are very helpful. In fact, a lot of the code in this example was taken from the CallManagerSample application.
Source code for Ribbit Developer Challenge 1

[...] Ribbit Developer Platform [...]
[...] many of you know, I do some Flex development on the side (see my post about Ribbit for an example). One of the most helpful resouces I have found is Flash and Flex [...]