New Adhearsion Feature: Sexy Rails integration 3
This feature has been in trunk for a while so it’s time to bring it into the limelight.
Let’s say you’ve a really fancy Ruby on Rails web application with which you wish to integrate your new Adhearsion app. Though you may only need five or so of the thirty models that exist within the app, they’re inter-related somehow with has_many :through, belongs_to and a dozen other SQL fragments sprinkled about. That’s no good—looks like it’s all or nothing. Oh, and you’ve eight Rails plugins installed, of which five heavily modify ActiveRecord’s internals for your obscure purposes. That’s no good, either. Looks like it all of Rails or nothing.
You can now do this “all of Rails” integration extremely easily in Adhearsion. When you create a new Adhearsion app with trunk, you’ll see the following option in config/startup.rb:
config.enable_rails :path => “/path/to/your/rails/project”, :env => :developmentAnd voila! Just uncomment this line and point it to the appropriate path. Adhearsion will do the rest.
Still more features to blog about! Stay tuned…
New Adhearsion Feature: Dialplan Menus 5
Those who watch the Adhearsion trunk commits probably noticed a new feature I snuck in recently: the menu() dialplan command. Now that I’ve had a chance to actually use the feature myself, it’s time I cover it in more detail here.
For the record, I’m totally excited about it. I’ve wished for something like this for over a year and only recently did I discover a way to get around the one technical limitation to implement it.
The problem
The menu() command solves the problem of building enormous input-fetching state machines in Ruby without first-class message passing facilities or an external DSL. After completely scrapping the feature several times and starting over, I eventually settled on my design of a state machine using a second-class message passing pattern. I’ll be writing about this pattern soon here.
Meet menu()
For now, here’s an example of menu():
from_pstn {
menu 'welcome', 'for-spanish-press-8', 'main-ivr',
:timeout => 8.seconds, :tries => 3 do |link|
link.shipment_status 1
link.ordering 2
link.representative 4
link.spanish 8
link.employee 900..999
link.on_invalid { play 'invalid' }
link.on_premature_timeout do |str|
play 'sorry'
end
link.on_failure do
play 'goodbye'
hangup
end
end
}
shipment_status {
# Fetch a tracking number and pass it to a web service.
}
ordering {
# Enter another menu that lets them enter credit card
# information and place their order over the phone.
}
representative {
# Place the caller into a queue
}
spanish {
# Special options for the spanish menu.
}
employee {
dial "SIP/#{extension}" # Overly simplistic
}If you haven’t, take a minute to read the dialplan above before reading on.
The main detail to note is the declarations within the menu() command’s block. Each line seems to refer to a link object executing a seemingly arbitrary method with an argument that’s either a number or a Range of numbers. The link object collects these arbitrary method invocations and assembles a set of rules. The seemingly arbitrary method name is the name of the context to which the menu should jump in case its argument (the pattern) is found to be a match.
With these context names and patterns defined, the menu() command plays in sequence the sound files you supply as arguments, stopping abruptly if the user enters a digit. If no digits were pressed when the files finish playing, it waits :timeout seconds. If no digits are pressed after the timeout, it executes the on_premature_timeout hook you define (if any) and then tries again a maximum of :tries times. If digits are pressed that result in no possible match, it executes the on_invalid hook. When/if all tries are exhausted with no positive match, it executes the on_failure hook after the other hook (e.g. on_invalid, then on_failure).
When the menu() state machine runs through the defined rules, it must distinguish between exact and potential matches. It’s important to understand the differences between these and how they affect the overall outcome:
| exact matches | potential matches | result |
|---|---|---|
| 0 | 0 | Fail and start over |
| 1 | 0 | Match found! |
| 0 | 1 | Get another digit |
| 0 | >1 | Get another digit |
| >1 | 0 | Go with the first exact match |
| 1 | >0 | Get another digit. If timeout, use exact match |
| >1 | >0 | Get another digit. If timeout, use first exact match |
Database integration
To do database integration, I recommend programatically executing methods on the link object within the block. For example:
menu do |link|
for employee in Employee.find(:all)
link.internal employee.extension
end
endor this more efficient and Rubyish way
menu do |link|
link.internal *Employee.find(:all).map(&:extension)
endIf this second example seems like too much Ruby magic, let me explain — Employee.find(:all) effectively does a “SELECT * FROM employees” on the database with ActiveRecord, returning (what you’d think is) an Array. The map(&:extension) is fanciness that means “replace every instance in this Array with the result of calling extension on that object”. Now we have an Array of every extension in the database. The splat operator (*) before the argument changes the argument from being one argument (an Array) into a sequence of n arguments, where n is the number of items in the Array it’s “splatting”. Lastly, these arguments are passed to the internal method, the name of a context which will handle dialing this user if one of the supplied patterns matches.
Handling a successful pattern match
Which brings me to another important note. Let’s say that the user’s input successfully matched one of the patterns returned by that Employe.find... magic. When it jumps to the internal context, that context can access the variable entered through the extension variable. This was a tricky design decision that I think, overall, works great. It makes the menu() command feel much more first-class in the Adhearsion dialplan grammar and decouples the receiving context from the menu that caused the jump. After all, the context doesn’t necessary need to be the endpoint from a menu; it can be its own entry point, making menu() effectively a pipeline of re-creating the call.
I encourage you to give this command a try and let me know what you think! Feel free to post on the mailing list or here on my blog.
Enjoy, folks!
The Lack of Emerging Telephony 4
The telephony industry sickens me. I make it a point to follow things closely. I sift through the nauseatingly boring Del.icio.us VoIP feeds, catching the occasional library I hadn’t seen before that mildly captures my interest. I hear that SuperBigComm has bought TinySmallVox every week or so. I subscribe to the feeds of the VoIP’s biggest bloggers (of which there are surprisingly few) and usually read their posts last, procrastinating the tedium. I don’t unsubscribe and keep the faith because I want to believe this industry is going somewhere.
But last night my feeds agreed with my doubts. Resounding through the VoIP blogosphere, O’Reilly announced they have cancelled their Emerging Telephony conference and blog. To help paint the picture, Emerging Telephony was widely considered to be one of the actually fun, innovative conferences every year in this space.
Therein lies the problem. Too little fun and innovation exists in this industry to make a full conference out of it.
Remember the last episode of Star Trek: The Next Generation where the omnipotent Q places all of humanity on trial for being a savage, inferior species? Q asserts that the years since the first time he placed humanity on trial has been squandered with virtually no progress toward enlightenment. I’m convinced Q was so pissed off because of this ridiculous blemish in our history. We are a savage, uncivilized race apparently.
This is a frustration I’ve had since I created Adhearsion. The framework’s name reflects my attempt to unify this godforsaken wilderness. I’m herding cats and fighting the good fight simultaneously.
But I’m not giving up yet.
There are many wonderful things brewing under the covers of the new version of Adhearsion. It’s a maverick, opinionated approach but it may just work. The effect could be truly disruptive:
- A significantly next-generation approach reaches hackers who can finally develop actual open-source VoIP applications.
- An open-source ecosystem forms.
- More people become professional VoIP developers.
- Additional global expertise increases the number of open-source VoIP applications.
- The ability to host the applications becomes predictable and inexpensive through standardization.
- Startups form around new applications.
- A few startups succeed and contribute back.
- Years of contributions improves software quality and lowers barrier to entry.
- Disruptively innovative companies catch big telecom companies with their pants down and chip away at their market share.
The fight will be a long and difficult one, though the next baby step is to get Adhearsion v0.8.0 out the door. Near the end of the this month I’ll outline the changes in the new version of Adhearsion which should see a release by RubyConf on November 4th, 2007!
Superators Add New Operators to Ruby 27
This one’s for the fellow DSL mavens. I’m releasing now a new library I’ve developed that adds new operators to Ruby. Install the superators gem and run the following code in irb:
require 'rubygems'
require 'superators'
class Array
superator "<---" do |operand|
self << operand.reverse
end
end
["jay"] <--- "spillihp"Dear demagogues of domain specificity! Yes, this actually works. Now, how about this cutie:
require 'rubygems'
require 'superators'
class String
superator "++" do |operand|
upcase + operand.upcase
end
superator "-~+~-" do |operand|
puts "Using pretty superators"
self + operand
end
end
p "Tangy" ++ "Erlangy"
p "Super" -~+~- "ators"Superators are a superset of Ruby operators. And they’re pretty super too.

To elaborate more, they work by exploiting the way Ruby parses binary and unary operators. For example, the code
foo ++- baris equivalent to
foo.+(bar.-@().+@())and the Superators library keeps track of the unary operators called on the operand in their appropriate order. A valid Superator’s format is simple: take (almost) any Ruby binary operator and tail on an indefinite number of unary operators after it.
These are the Ruby binary operators you can use: ** * / % + - << >> & | ^ <=> >= <= < > === == =~And here are the unary operators: - ~ +
The only operators you can’t use are the logical ones (e.g. &&, ||, !, and, or, not, etc.) Ruby offers no way of overloading these.
I’m releasing this into the wild to hopefully see what mischief it stirs. But take heed! Superators are second-class citizens still and are victims of vicious discrimination in certain circumstances. In the current implementation the second operand is extend()ed with a Ruby module (unobtrusively setting a flag for later inspection), therefore a Superator can only have a second operand capable of possessing its own eigenclass. Superators will not work with second operands such as true, false, nil, Symbols or Fixnums yet. I’m working on a branch that could fix this if my mad scientist lab experiments bear fruit (or a resentful monster whom I chase to the Arctic Circle after he destroys those I love). Stay tuned.
Despite this limitation, Superators can still be used effectively! Use it when you expect the second operand to be an Array, String, Hash, Range, Regexp, Class, or whatever.
I should note that I strongly frown upon any use of Superators outside of the DSL space. Don’t use it in your company’s Rails app controllers. Use it in your tenderly crafted Ruby DSLs where they make sense.
Enjoy, comrades.
Update: There seems to be some confusion that Superators are a C extension that modify Ruby’s internals. A valid Superator is actually just valid Ruby—something we’ve had at our disposal this whole time!
Full Video Recording of my Ruby Hoedown Presentation 6
On August 10th I gave a presentation about Adhearsion at the Ruby Hoedown conference. Despite only two hours of sleep the night before, I think it came out quite well.
The ConFreaks guys were there and recorded my presentation. It’s completely available online on their website here. It can also be downloaded in AVI format at 640×240 or 960×360.
Here are a few snapshots from my talk:


Blog Downtime
While working on a mundane detail for this site last weekend, I thought it’d be fun to run “rake test” on my Typo blog install to evaluate their testing framework. Instead, this experiment quickly became an evaluation of my own ability to frantically reconstruct my suddenly vaporized blog.
Apparently, when I first configured my blog, I set my “test” Rails database settings as the same as development and production, hosing everything with that one command. Lesson learned.
If you’re reading my blog from an RSS reader, you’ll probably see every single blog post again. Sorry about that. Google Reader also snatched up a lot of draft blog posts that were mostly lists of blog post ideas completely unintended for the public eyes to see. Again, sorry about that. Things are now back up and actually better than before.
Adhearsion v0.8.0 and Beyond
It was about one year ago that the Adhearsion name came to be, along with an invigorating second wind to develop it after writing Rails apps for several months and seeing real Ruby development. The ease and sense I saw Ruby make in the web development scene was an enormous inspiration to build Adhearsion into what it is today and what it will soon become.
It's this near future that excites me the most. For the past few months I've been intensively working on a rewrite of the Adhearsion core and it's showing great promise. Since I've never formally announced my intentions, here is what the community can expect from Adhearsion v0.8.0:
- Sustained quality. An enormous problem with Adhearsion 0.7.x has been avoiding regression when changes are made. The codebase today is unfortunately very monolithic and, consequentially, very easy for a change in one area to affect the rest of the framework without my knowing until someone reports it on the mailing list. This time around I am working on 100% RSpec coverage of Adhearsion and using the development principles of Behavior Driven Development. The telecom world expects rock solid dependability and Adhearsion should never be a question mark.
- First-class community portal. Another big issue in the Adhearsion scene I'm noticing is a weak adhesion (pun intended) of the Adhearsion community. My vision long ago was to facilitate the exchanging of Adhearsion-related source code on the official Adhearsion website. The problem has been in finding time to develop this community portal. Thankfully an opportunity arose to work with Alex Pilafian of Sikanrong.com on the site. In just the one month we've been developing it we've made enormous headway. Imagine this: a community-maintained open-source call center application exists online at Adhearsion.com; the "ahn" command allows dead-simple ease of deployment with only "ahn install appname"; suddenly you receive a fully functional call center PBX with AJAX-enabled web frontend, PBX clustering support, Java integration (mentioned below), easily maintainable application code, and all of the other benefits of Adhearsion. Yes, it's pretty exciting, disruptive stuff. I'll write more about this as it nears completion.
- Steps toward PBX independence. In doing some consulting for Gaboogie, I've been steadily working on FreeSwitch bindings to Adhearsion for them which will ultimately become open-source and standard with Adhearsion. FreeSwitch is still pre-beta at the moment but does tackle scalability very well. Unlike Asterisk where most of the functionality is already written and must be abstracted, FreeSwitch simply opens APIs for the implementor to develop his own functionality. This means more work on my end but, ultimately, a more robust and modifiable set of VoIP applications.
- New Asterisk Manager Interface library. Adhearsion AMI features are presently based on the two-year old RAMI library which exposes an API to read and execute Asterisk events outside of live phone calls. The library definitely shows its age, being a very tangly mess of unintuitive code that I'd expect from the non-Prototype Javascript world but not from the Ruby '07 scene. Dave Troy and I sat down at the Asterisk Developers Conference in Atlanta a few months ago and pounded out an unprecedented new library that vastly improves Asterisk integration.
- JRuby compliance. At RailsConf 2007, Charles Nutter and Thomas Enebo demonstrated deploying Mephisto on Glassflish in front of our eyes during a three-hour tutorial session. In the lobby immediately after their presentation I was able to replicate their success by deploying a simple "hello world" Rails app. Now with JRuby v1.0.0 stable out in the wild with "complete" 1.8.5 compliance, Adhearsion can be deployed seamlessly with other Java technologies. With Microsoft's efforts in the IronRuby space, a Ruby interpreter written in .NET, Adhearsion's use of the Ruby platform will make integration with that microcosm native, too. Of course, provided Microsoft doesn't fork our language! (J#, anyone?)
- More on Micromenus. With both the advent of the iPhone and its need for a good SDK, I've been working on the new Micromenus namespace that will render special iPhone-specific interfaces. With this complete, database-driven Micromenus applications can be busted out in minutes, complete with Asterisk integration out of the box. I don't want to spill these beans quite yet so stay tuned. :)
There are a few other things I'll leave in as surprises for the 0.8.0 release but this list should whet your appetite.
Beyond Adhearsion v0.8.0 there are many things on the roadmap, some of which will be axed and some of which will remain. Perhaps the biggest feature in my mind for version 1.0.0 stable will be a real abstraction of the PBX, letting the implementor not worry about any of the inconsistencies of the underlying framework. Adhearsion v0.9.x will be the first step toward the PBX independence and, when sufficient and stable, the 1.0 release will be triggered.
In the meantime, I'd love for others' help in this exciting ramping up phase! Let me know if you've like to lend a hand!
Adhearsion IRC Channel
Need help getting started with Adhearsion? Having issues with your Adhearsion deployment? Want to become an Adhearsion developer and need pointers in the right direction?
Join #adhearsion on irc.freenode.net. I'll be hanging out there whenever I'm on an internet-accessible machine.
First Adhearsion Job Posting 33
The first of its kind (to my knowledge), EngineYard posted a job search for someone to develop their in-office PBX, requiring Adhearsion skills. EngineYard’s definitely on the right track—especially since so much of their own infrastructure is written with Ruby and things such as in-office PBXs can be done extremely effectively with Adhearsion. Hopefully other companies with follow their lead and support pioneers in this new Adhearsion frontier.
Though I make my business in Adhearsion consulting, I’m totally open to developers jumping on these kind of postings. I couldn’t be happier to have Adhearsion perpetuate its own economy — even if that means people beat me at price occasionally. :)
Adhearsion Roadshow Tour Dates
Perhaps "roadshow" isn't the right term but I am doing quite a bit of Adhearsion and VoIP promotion. Below is the current list. As I land more, I'll expand it:
Past speaking events:
- Emerging Telephony, San Francisco, Feb 27th
- Gotham Ruby Conference, NYC, April 21st
- Boulder/Denver.rb, May 15th
- Asterisk Developers Conference, Atlanta, May 22nd
Upcoming speaking events:
- Cluecon, Chicago, June 26th
- PDX.rb, Portland, July 3rd
- Ruby Hoedown, Raleigh, Aug. 10th
- Lone Star Ruby Conference, Austin, Sept. 8th
- Astricon, Phoenix, Sept. 24th
Unconfirmed Events:
- FOSCON, Portland, July 26th
If you are a member of a Ruby brigade or Asterisk users group and would like me to present, shoot me an email. My contact info is available on the Adhearsion contact page.
Back in the Blogosphere!
Alright folks, I'm back!
I've finally switched my blog from my own Gosling software running on Dreamhost to Typo running on my rack server. My old design too is gone until I can implement graphical elements for the snazzy features Typo offers.
I ditched my old setup because the spam and homepage length got out of hand, I didn't have fancier features such as trackbacks or captchas, and I had no XML-RPC API for posting with blogging software. Wrestling with Apache 2.2, Mongrel and Typo was a hurricane of pain but I'm at long last in the calm after the storm and can work on content!
Grab the feed and stay tuned guys. Lots of juicy Adhearsion/Ruby/VoIP goodness coming. :)
Adhearsion in Linux Journal Magazine 1
Woot! Linux Journal Magazine, the original magazine of the Linux community and a fantastic barometer for exciting new open-source technologies, has published an article I wrote about Adhearsion in their March 2007 issue. These are the guys that had DHH’s smug mug on the cover of their issue devoted almost entirely to Ruby a few months ago.
This issue’s concentration is VoIP, hence Adhearsion’s inclusion. Thus far it’s the best overview of Adhearsion for a newbie so I recommend to everyone reading this now a trip down to your closest Barnes & Nobles to pick up this copy. No really. Go get a copy. Stop reading my blog, grab your keys, and go.
I chose to send Linux Journal my article because I have an enormous respect for them. I’ve been a reader of their issues for many months and with every issue I find something great. Hopefully people can say the same with this issue referring to Adhearsion. :)
Jay’s got pics:
What is Adhearsion?
“Adhearsion! Adhearsion! Adhearsion!” has been my mind’s mantra for many months now. Though Adhearsion.com went live Christmas along with the first release, it’s never received due announcement on my blog. Well, here you go folks.
Adhearsion is new twist on collaboration technologies. Its name derives from its VoIP-oriented origins as “adhesion you can hear” because it understands the VoIP picture and ties many VoIP-related (or, rather, collaboration related) technologies together in a comprehensive solution. From Adhearsion.com, these technologies include:
- Writing call-processing instructions
- Trading VoIP functionality
- Integrating with on-phone XML-based microbrowsers
- Collaborating with technology beyond VoIP
- Database integration for DB-driven VoIP apps
- Sophisticated relationships with Asterisk’s internals
- Opening up your PBX to RPC distributed computing
...to name a few. The end result is an exciting albeit lightweight package that is simply fun to hack with and beautifully simple. I wake up each morning giddy to resume my programming on Adhearsion from the previous night because each day brings some new and exciting possibility. This passion too is now shared — more are joining the project and more are seeing this vision. It’s great how all this is falling in place.
So great in fact my company Codemecca LLC is now the Adhearsion company. It will be the official sponsor of Adhearsion’s development and proliferation while bringing Adhearsion to the small business and enterprise markets through training, consulting, support, and so forth.
Technically, Adhearsion is written in Ruby with a sweet helper architecture. These “helpers” or framework extensions can be written in Ruby or C (more languages coming) and plug right into your app to extend, for example, the dial plan instructions or to introduce instant messaging functionality over Jabber.
In the spirit of “adhearing” things together, functionality brought by helpers can be used for your PBX, by other helpers, or — and this is the key — over Remote Procedure Calls (RPC). Take for example credit card processing. A new company wants to provide a public number into which customers can call and place orders for particular items. Also, because we’re living in the 21st century, they want to have the same credit card processing logic available to their PHP/Rails/Django/J2EE/whatever web apps. Writing the credit card processing logic in Adhearsion makes the functionality available to the PBX, but also to any other program or service needing it within the company. And by the way, writing that actual logic and having it set up like this would require nearly no effort whatsoever.
Stay tuned on this blog for more updates on Adhearsion. I’m hitting a wall with my custom blogging software Gosling and will soon be switching over to Typo. This will make the blog a much nicer place to facilitate my ramblings. :)
My Interview with Mind Petals, the Young Entrepreneur Network 1
Poking through my del.icio.us web design feeds one early September morning, I stumbled across one site bookmarked with the description “CHECK OUT THIS GREAT DESIGN!”
Totally falling for Mr. CAPSLOCK’s effectiveness, I obeyed. “MindPetals.com, the young entrepeneur’s network” caught my eye and my eyebrows shot up. Coincidentally, this was just around the time I was forming my company Codemecca, making me a new, young entrepeneur.
I emailed Mind Petals’ owner Dave Askaripour and we’ve been keeping in touch ever since. He’s recently entered the printed newletter market and, for his first issue, he asked to interview me on the great growth of Codemecca since we first met.
The interview’s now on the Mind Petals website. It’s a good read – go check it out and snag his feed!
I'll Be Speaking at O'Reilly Emerging Telephony 2007
And I can’t wait. The conference is going down early next year and caters to the high-end Telecom world. The biggest names in the industry will be there and will get to see all the exciting work I’ve been pouring into Codemeccca. What a great opportunity!
I’ll be giving a ninety minute hands-on workshop showing why Adhearsion rocks by example of a fictitious new Web 2.0 service starting with VoIP integration. What’s more, speakers get free tickets. I had a blast at Astricon 2006 here in Dallas and ETel I’m sure will become a lifelong memory. Just looking at the lineup this year gets my mouth watering.
Older posts: 1 2

