Flowroute, a SIP service provider, recently enabled SMS on all of their phone numbers (DIDs). This means that if you have a DID from Flowroute, your phone number can now be used to send and receive SMS messages.

This article will show you how you can receive those SMS messages with Perl. (You can skip the background to get to that part quicker.)

Background

I first learned about Flowroute at Astricon 2008 (Phoenix, AZ). At the time, I was working for a Residential VoIP carrier and we were always looking for new service providers.

Flowroute immediately distanced themselves from the other providers by (1) sending engineers instead of sales staff and (2) offering Asterisk prompts from Pat Fleet.

Now, don’t get me wrong… I love Allison and consider her a friend. My wife loves Allison. I routinely recommend Allison’s services to my clients who are incredibly happy with work. After all, she’s the voice of Asterisk for a reason. That being said, having a few disconnected messages coming from Pat Fleet was pretty awesome.

Astricon provided an opportunity for me to learn about Flowroute without listening to sales jargon. What I learned made me a fan, and more importantly— a client.

I’ve been a client of Flowroute since 2008. I recommend Flowroute to my clients and although they do have a reseller program, I’ve opted out. (A recommendation means more to my clients when they know I don’t get kickbacks or financial incentives.)

Flowroute SMS

Recently, Flowroute enabled SMS capabilities for all of their DIDs. SMS immediately provides you with additional means of communication… retailers can better communicate with customers, providers can offer new services, and everyone can benefit from increased availability.

Flowroute has offered some great tutorials for working with SMS, including proxying SMS, setting appointment reminders, and making your own two-factor authentication.

Of course, some of us don’t use Python… or node.js… or even go. Some of us like Perl and believe that if it ain’t broke, don’t fix it.

The bottom line is that since Flowroute sends SMS via JSON, you can use whatever you’d like to handle messages.

Simple Perl JSON API, or Receiver

So, let’s not get in a debate here about what or what isn’t an API. What we are going to do is:

  1. Point Flowroute SMS to our webserver
  2. Handle the POST via Perl script
  3. Query a database to get an email address
  4. Store the SMS in a table
  5. Send an email with the message received

First, I’m using a database because we have quite a few DIDs to process and I really like the idea of updating/maintaining this information in a database. The information is “live” and works for my scenario.

The nice thing here is that if you only have a few DIDs, you could simply hard code the email and use the same script. Do what makes you happy.

For the rest of this, I’m going to assume that you have a web server (although you could make a daemon if you wanted) and know how to add a script to your site.

Lately, I’ve been using nginx/fastcgi but apache is still great, too. Use what makes you happy.

Set up your Database

If you don’t know SQL enough to work with tables, you can skip this step.

This script will create a mysql database called flowroute, tables for accounts, dids, and sms storage. Please make sure you change the username and password.

grant all on flowroute.* to 'USERNAME'@'localhost' identified by 'AWESOMEPASSWORD';

Ironically, that’s not an awesome password.

The script will also create a stored procedure called “add_sms.” Why use a stored procedure? I like stored procedures.

Benefits for using procedures can be discussed another time, the takeaway here is that the add_did stored procedure matches the last 10 digits of a DID to the did table and finds the account email. It also stores the message in the sms table.

If no DID is matched, the procedure returns fail.

At this point, create some accounts, add your DIDs, and associate them to the account_ids.

Perl Script to parse JSON

When Flowroute sends you an SMS, it looks like this:

POST /runpost HTTP/1.1
Content-Length: 72
Host: 54.68.158.17:11111
Content-Type: application/json
Accept-Encoding: gzip

{"to": "12066418000", "body": "Hello there from Flowroute!", "from": "18553569768", "id": "mdr1-febb118b9b034338adfc662a8c02fd88"}

Our goal is to parse this JSON and return a JSON encoded response.

Knowing that to, from, id, and body are required fields, if they aren’t there, the script will return a JSON encoded error.

There are two versions of the script; both available on github:

Example Perl script:

#!/usr/bin/env perl
#
# Author: Fred Posner <fred@qxork.com>
# Twitter: @fredposner
# Contact: http://qxork.com
# Date: 2016-03-18
# Copyright: The Palner Group, Inc.
# License: GPLv3
#
use strict;
use warnings;

#
# need CGI, JSON,
# MIME::LITE for email,
#
use CGI ();
use JSON ();
use MIME::Lite;

#
# Declare variables
#
my ($status, $input);

#
# Where do you want to send the email?
#
my $email = "ME\@MYDOMAIN.ORG";

#
# receive and parse POSTDATA
#
my $q = CGI->new;
my $json = JSON->new->utf8;
if ($q->param('POSTDATA')) {
   $input = $json->decode( $q->param('POSTDATA') );
} else {
   &SimpleJSONResponse("error","no JSON data found");
   exit(0);
}

unless (($input->{to}) && ($input->{from}) && ($input->{body}) && ($input->{id})) {
   #
   # if we don't get the required fields from flowroute,
   # return an error
   #
   &SimpleJSONResponse("error","required fields not present");
} else {
   my $msg = MIME::Lite->new(
      From => "sms-no-reply\@DOMAIN",
      To => $email,
      Subject => "SMS Received",
      Data => "Sent to: " . $input->{to} . "\n\nSent from: " . $input->{from} . "\n\nSMS: " . $input->{body} . "\n\n"
   );

   MIME::Lite->send('smtp','localhost',Timeout=>60);
   $msg->send;

   &SimpleJSONResponse("success","message sent to $email");
}

#
# Subroutines
#
sub SimpleJSONResponse() {
   my($key, $value) = @_;
   print $q->header(-type => "application/json", -charset => "utf-8");
   print $json->encode({ $key => $value });
}

In closing…

We’ve waited patiently for SMS from Flowroute and working with it, couldn’t be easier— even if you still like writing scripts in Perl.

Remember to point your SMS to the URL of your script within your Flowroute dashboard to enable SMS.

Additional Information