twilio-in-ten-minutes
twilio-in-ten-minutes copied to clipboard
Create and deploy a Twilio Interactive Voice Prompt System with Ruby, Rails and Heroku in Ten minutes.
h1. Awesome IVR!
Twilio IVR Development Framework
This project includes a few parts: a gem for generating "TWML":http://www.twilio.com/docs/api/twiml/ (Twilio's markup language); a modified "Newflow":https://github.com/trotter/newflow; and an IVR Workflow base class.
h1. Prerequisits
You have PostgreSQL installed and have administrative access.
To render the workflows you will need to have GraphViz installed (the @dot@ tool is required).
You have signed up for Twilio and Heroku (see "An Interactive Voice Response System in 10 Minutes":http://asymmetrical-view.com/2011/02/20/twilio-in-ten-minutes.html for a walk through of signing up for these services).
h1. Installation
The project was developed to be deployed to "Heroku":http://heroku.com/. Because of this, it makes use of a postgres database. To initialize your database, install PostgreSQL and perform the the following grants (also found in the pg-grants.psql file):
create role twilio with createdb login encrypted password 'tw9987$$5'; create database twilio_app_development with owner=twilio encoding='UTF8' template template0; create database twilio_app_test with owner=twilio encoding='UTF8' template template0; grant all privileges on database twilio_app_development to twilio; grant all privileges on database twilio_app_test to twilio;
h2. Configuration
The system should fail to initialize unless @config/twilio.yml@ exists. You must create this file and include your Twilio configuration into the file. It follows the same format as other Rails configuration files, being broken out by the Rails environment (development, test, staging, and production).
NB: DO NOT PUBLISH THIS FIILE! It will contain information about your Twilio account that allows the framework to interact with your twilio accoun. As such you should keep it private.
An example is provided here:
development: account_sid: "'Account SID' from https://www.twilio.com/user/account/" auth_token: "'Auth Token' from https://www.twilio.com/user/account/" base_url: "https://api.twilio.com/2010-04-01" ivr_phone_number: "'Number' from https://www.twilio.com/user/account/" sandbox_pin: "'PIN' from https://www.twilio.com/user/account/" test: account_sid: "'Account SID' from https://www.twilio.com/user/account/" auth_token: "'Auth Token' from https://www.twilio.com/user/account/" base_url: "https://api.twilio.com/2010-04-01" ivr_phone_number: "'Number' from https://www.twilio.com/user/account/" sandbox_pin: "'PIN' from https://www.twilio.com/user/account/" staging: account_sid: "'Account SID' from https://www.twilio.com/user/account/" auth_token: "'Auth Token' from https://www.twilio.com/user/account/" base_url: "https://api.twilio.com/2010-04-01" ivr_phone_number: "'Number' from https://www.twilio.com/user/account/" sandbox_pin: "'PIN' from https://www.twilio.com/user/account/" production: account_sid: "'Account SID' from https://www.twilio.com/user/account/" auth_token: "'Auth Token' from https://www.twilio.com/user/account/" base_url: "https://api.twilio.com/2010-04-01" ivr_phone_number: "'Number' from https://www.twilio.com/user/account/" sandbox_pin: "'PIN' from https://www.twilio.com/user/account/"
h3. Heroku
When you deploy to Heroku they will create a database and set the configuration for your dyno.
Once you've allocated your Heroku instance, not your application's hostname for when you configure Twilio.
h3. Twilio
In your dashboard, fill in the 'Voice URL' box with your Heroku applicaiton's URL followed by @/workflow/CCard@. This will configure Twilio to use the sample credit card activaiton flow when you call your sandbox phone number.
h1. Components
h2. TWML Gem
This gem provides an internal DSL for Ruby for generating Twillio Markup Language. See the file @app/ivr_workflows/ccard.rb@, or the spec tests in @twml/spec@ for examples of using the TWML gem.
h3. gather
|Parameter|Description| |:numDigits|The number of digits to allow for input.| |:timeout|The number of seconds to wait for the caller to complete their input.|
Used for gathering input from the caller. @gather@ statemens may be cut short by user in put. If you put one or more @say@ statements in a @gather@ block, any input will cut them short, while @say@ statements outside of a @gather@ will complete before input is taken.
h3. say
Used to invoke Twilio's speech synthesizer to talk to the caller.
h3. hangup
Terminates the phone call.
h2. Newflow Gem
The gem has been customized to allow states to transition to themselves while still executing triggers.
h2. Ivrflow
Implement your workflow as you would with Newflow, declaring the states, transitions, predicates and triggers. The @Ivrflow@ base class and the @workflow_controller@ will handle managing the state of your workflow in the database. For each state you declare, you can either implement a @#{state_name}_message@ method, or declare a @message@ block using the DSL:
class MyFlow true do transitions_to :stop, :if :pressed_1? transitions_to :stop, :if :not_pressed_1? end state :stop, :stop => true end message :start do gather(:numDigits => 1, :timeout => 10) do say "Hello there, press 1 or 2 please." end end message :stop do say "Thanks for calling!" hangup end end
h3. Method Missing or Automatic Methods
h3. @pressed_(digits)?@
Used to test if the user has entered a specific set of digits, eg: @pressed_1?@, @pressed_10?@
h3. @not_(predicate)?@
This form will invert the logic (convenient for trigger functions) of any method that your worklfow supports. Eg: @not_pressed_1?@
h3. @(state_name)_message@
If you don't declare the message for a state using the @message@ declaration, the framework will look for and call a method composed of the name of the state plus a @_message@ suffix.
h1. Developing Workflows : Ivrflow
h1. Testing
h2. Ineractive Testing Uisng the Web Console
Visit your application's root @/@ and you should see a list of the registered workflows in the top left. Clicking on a workflow name will bring up a console that allows you to interact with the workflow.
h2. Cucumber
Your IVR Workflows may be tested via the "Cucumber":http://cukes.info/ BDD testing tool. The framework has been extended to support calling into the IVR application framework. Please have a look at @features/ccard.feature@ for an example of how to write test for your workflow.
h1. Spying on Sessions with the Web Console
h1. Rendering the Workflows
To render the workflows you will need to have GraphViz installed, then execute: @rake ivr:render_workflows@
h1. Developing / Hacking
Create a local branch that you will_not_push to a public repo, this branch will contain your @config/twilio.yml@.
Create your @config/twilio.yml@. Add it to git, check it in.
Push your branch to Heroku as the master.
user@host: ~/projects/twilio-in-ten-minutes $ git checkout -b twilio-deploy user@host: ~/projects/twilio-in-ten-minutes $ vi config/twilio.yml user@host: ~/projects/twilio-in-ten-minutes $ git add config/twilio.yml user@host: ~/projects/twilio-in-ten-minutes $ git ci -m 'my twilio config' user@host: ~/projects/twilio-in-ten-minutes $ git push heroku twilio-deploy:master
When you're done, re-checkout @master@ and do your development there. Then to deploy, checkout @twilio-deploy@, merge master into it and push to Heroku again.
This will keep your @config/twilio.yml@ out of the master branch - which is key for me since it has my Twilio credentails and my master branch gets pushed to Github (which is probably where you're reading this).
h1. Other Services
h2. Telephony
h4. "Twilio":http://www.twilio.com/
Voice and SMS.
h4. "Tropo":https://www.tropo.com/home.jsp
Voice, SMS, IM and Twitter integration.