Tropo: Interesting New IVR Platform by Voxeo That Supports Groovy

| Comments

Late last night, I ran across Tropo, a new IVR platform by Voxeo that supports a large variety of modern scripting languages, including my current favorite, Groovy (it also supports JavaScript, Ruby, Python, Jython, and PHP).

They just opened their “early beta” to the public about 10 days ago and have free accounts for developers to try things out.

They also have a github repository with a bunch of sample applications, and the adapter code that they’re using to make their core functionality available to all these different languages.

It’s nice to see an IVR company support all these modern things. VoiceXML has been rotting in a dungeon for the last 5 years and making a programming language out of an XML syntax was wrongheaded to begin with. Bringing languages like Groovy to bear on IVR problems will enable much more robust applications and quickent development.

Tropo’s documentation is a good start, but there are a number of holes in it since it’s so new. Because we have access to all of the yummy Groovy metaprogramming and reflection, we can find out lots of information about the system and it’s functionality for ourselves.

I’m just starting to dig into this, but here’s a quick groovy script that I threw together to spit out a bunch of information. It includes the version of groovy that they’re using (1.6, yay!) and what each of the variables are that are available through the script bindings. For each variable in the binding, I then spit out the variable’s class and all of the methods that are on it that aren’t the boring methods from the Object class:

import org.codehaus.groovy.runtime.InvokerHelper

answer()
say("putting bindings into log")

log("groovy version = ${InvokerHelper.version}")
log("binding variables: \n" + this.binding.variables.collect {k, v -> "$k = $v"}.join('\n\t'))

this.binding.variables.each {k, v ->
    log("(${v.class.name}) $k interesting methods\n = ${interestingMethods(v).join('\n\t')}")
}

say("successfully logged information about environment")
hangup()

def interestingMethods(clazz) {
    // remove boring Object methods
    return classMethods(clazz) - classMethods(Object.class)
}

def classMethods(clazz) {
    return clazz.metaClass.methods.name.sort().unique()
}

After uploading that script to my account (nice WebDAV support BTW!) and calling my new app with my skype phone, I can look at the logs and see this output towards the bottom:

groovy version = 1.6.0

binding variables: 
    callFactory = com.voxeo.fluffer.core.SimpleCallFactory@f4502f
    currentApp = TropoApp@1578f73
    appInstance = Application[36255:groovy:http://hosting.tropo.com/36255/www/helloWorld.groovy](sas_2-8-smonh87dfluffer)
    currentCall = TropoCall@18acac9, context = javax.script.SimpleScriptContext@10754f6
    incomingCall = SimpleCall [("null")sip:redacted]
    out = java.io.PrintWriter@5b112a

(com.voxeo.fluffer.core.SimpleCallFactory) callFactory interesting methods = 
    call

(TropoApp) currentApp interesting methods = 
    getBaseDir 
    getMetaClass 
    getProperty 
    get_app 
    invokeMethod 
    setBaseDir 
    setMetaClass 
    setProperty 
    set_app

(com.voxeo.fluffer.app.SimpleInstance) appInstance interesting methods = 
        block 
    getApp 
    getApplicationSession 
    getCurrentApplicationInstance 
    log 
    run 
    terminate

(TropoCall) currentCall interesting methods = 
    answer 
    ask 
    await 
    getCalledID 
    getCalledName 
    getCallerID 
    getCallerName 
    getMetaClass 
    getProperty 
    get_call 
    hangup 
    invokeMethod 
    isActive 
    log 
    prompt 
    record 
    redirect 
    reject 
    say 
    setCalledID
    setCalledName
    setCallerID 
    setCallerName 
    setMetaClass 
    setProperty 
    set_call 
    state 
    transfer

(javax.script.SimpleScriptContext) context interesting methods = 
    getAttribute 
    getAttributesScope 
    getBindings 
    getErrorWriter 
    getReader 
    getScopes
    getWriter 
    removeAttribute 
    setAttribute 
    setBindings 
    setErrorWriter 
    setReader 
    setWriter

(com.voxeo.fluffer.core.SimpleIncomingCall) incomingCall interesting methods = 
    answer 
    await 
    block 
    getASR 
    getCalledId 
    getCalledName 
    getCallerId 
    getCallerName 
    getState 
    getTTS 
    hangup 
    isActive 
    lock 
    log 
    prompt 
    promptWithRecord 
    redirect 
    reject 
    setState 
    signal 
    transfer 
    unlock 
    updateEndpoint

(java.io.PrintWriter) out interesting methods = 
    append 
    checkError 
    close 
    flush 
    format 
    print 
    printf 
    println 
    write

Looks like most of the coolest stuff is on the currentCall and incomingCall objects.

From what I’ve seen, I think there are a couple of holes in what Tropo currently supports for it to be a replacement for people using current VoiceXML technology in enterprise environments (stuff like backup TTS for missing .wav files), but I’ve found that their support people are very responsive (even at 1AM on a Friday night :). I believe that they have plans to fill in many of these gaps as the product matures and moves out of beta.

There’s plenty here for people to start experimenting with things and creating some sample applications.

I hope Voxeo continues to develop this platform as it has a lot of potential. I could see a fun grails plugin in the future to easily add IVR capabilities to an application.

Comments