Skip to content

Quick Hacks: Asterisk account codes, Ruby programming, and the Freshbooks API

I put together a quick hack last night that will help with managing truant accounts on JKL5’s “Cloudphones” SMB VoIP PBX. Ostensibly, it’s a pre-paid service for small to medium businesses, as well as a couple of residential customers. However, we have a couple of problem accounts that require checking on the accounts payable report followed by a few nagging emails to get to pay their bills at the 45 day mark.

In each trunk and phone configuration, I have the customer’s company name set as the “Account Code” for any call they take or make. In an IAX2 trunk, it looks like this:


With something like a SIP phone, it’s just as easy:

SNOM 870 VoIP Phone
SNOM 870 VoIP Phone, using SIP over WiFi … great phone!
 callerid=John Doe <5150>

So, when a call either comes or goes, we can recover the account call from the CDR data from the call, even as the call is progressing. An Asterisk dialplan example might look like:

 exten => s,1, NoOp(... Checking account status 
     for [${CDR(accountcode)}] )
 same => n, Set(__account_status=${SHELL(/opt/
     check_account.rb ${CDR(accountcode)} )})
 same => n, NoOp("Accounting: account_status is
 same => n, Return()
Asterisk PBX
Asterisk PBX – Helping Solve the VoIP Puzzle for small and medium sized businesses

“check_account.rb” uses the “ruby-freshbooks” Gem to open an API connection to the FreshBooks server. It pulls a list of “Cloudphones” customers, finds the customer ID # based on the name it is sent and then checks to see if there are invoices more than 30 days old and unpaid for that customer. It then returns a status indicator that can be used to make a “yes” or “no” decision if the customer’s call service needs to be impacted due to a truant account.

Note that the double-underscore at the start of the variable name means that the variable is kept and passed on from one context to another, so it is always accessible during the call.

Within the dialplan, code similar to the following before the call is delivered to the extension or to the outgoing trunk does the job:

same => n, Gosub(accounting_system_check,s,1)
same => n, GotoIf($["${account_status}" =

Naturally, “account_restricted” should do something valuable, such as inform the outgoing caller about their account status, or send an incoming call directly to voicemail. Using a “Gosub()” avoids repeating the check code across multiple contexts

The best part about all of this is that as soon as the over due invoices are marked paid on FreshBooks, such as an online payment via credit card or PayPal, then the next call coming in or going out gets the “Green Light” and call flow behavior is normal.

We don’t have to waste time policing our Cloudphones accounts recievables, and we leverage a great functionality provided by FreshBooks. The customer status is always up to date, as fast as the payment arrives. It’s a “win” all the way around.

Published inInformation TechnologyJKL-5 GroupProgrammingTelephony

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.