My solution for implementing Flowroute SMS into Asterisk

How I implemented Flowroute’s SMS services into my X-Lite softphone’s IM feature.

Introduction and background

As many of you are no doubt aware, SMS messaging is not really an integrated part of FreePBX/Asterisk. In fact as far as I know, SIPStation is the only SIP Trunk provider that offers integrated SMS capabilities. Other providers offer SMS, but they don’t work out of the box like SIPStation. However for my basic home VoIP needs, their offerings aren’t a lot cheaper than the services I already had through my provider.

I did some shopping around and decided on Flowroute for my SIP trunk. Their basic services were within my budget, and they offer SMS. Now came the fun part; making it work with the X-Lite instant messenger. From what I understand, the SIP SIMPLE protocol used by the X-Lite softphone also works with a variety of SIP phones as well, but I don’t own any SIP phones and don’t really have a way to verify that my solution works on those phones as well.

How Flowroute’s SMS services work

Flowroute’s SMS service works via a basic RESTful HTTP interface, using simple POST and GET HTTP requests.

Through Flowroute’s account manager, their SMS API can be “pointed” to an SMS Callback URL, a specific address on your network. Any incoming SMS messages they receive for one of your DIDs is sent to this callback URL in the form of an HTTP request. Software on your end receives the message, and it’s up to you to take it from there.

They also provide a URL on their network to receive outgoing SMS messages, utilizing an HTTP request as well. Again, it’s up to software on your end to format, prepare, and send the message.

How I handle incoming SMS messages

Using Apache and a perl script, I receive an incoming SMS message and use the information to create a .call file that I drop into Asterisk’s outgoing call directory. Asterisk takes it from there and sends the message to a specific softphone extension as an IM.

How I handle outbound SMS messages

Using a custom context stored in Asterisk’s custom extension file, instant messages are examined to determine if the destination is a local extension or a 10 digit phone number. If it’s a 10 digit phone number, the message data is passed on to a bash script where it’s formatted into a valid HTTP request and sent to Flowroute through cURL.

Overall, it’s a working solution. It’s a bit of a kludge, but it does work. I have been considering writing up a more detailed explanation with an explanation of the underlying code, if anyone is interested.

6 Likes

Out of curiosity, I could probably google, are these callbacks authenticated?

Some feedback:

  1. Security is always a risk but if your script is homebrewed and not public it is likely someone will find an exploit.
  2. Spiders tend to “find” things. Things like shodan will find almost any server during their sweeps. If the answer to the above question is no that should be corrected or I would avoid webhooks and just poll and keep states like “last message”
  3. If you are using webhooks I would recommend https in both directions so people can’t sniff out your info. Domains are cheap if you don’t have one and with letsencrypt there is no reason to NOT have ssl.

<-- Interested!

Yes, the callbacks are authenticated, using an access key and security key.

And you have a very valid point regarding SSL - I am looking into that today. I knew letsencrypt existed, but never really had a need for an SSL cert in the past.

I do have restrictions in place in Apache that only allow access from Flowroute’s specified IPs, but I suppose that it wouldn’t be that hard for a hacker to spoof the IP.

I’ve done something similar for sending/receiving SMS with Twilio, which also uses a REST interface. One difference is that instead of using .call files I am delivering incoming SMS into Asterisk as SIP MESSAGE requests to be handled by message-specific dial plan. Your .call files may have some advantage over the SIP approach in that you can write the .call file to do automatic retries on failure.

both methods should net the same result on their face. Call files or direct still land in a context they just take different busses to get there.

For fun someone could do this in ARI… <.< >.>

Shameless plug come see my talk at Astricon

The dialplan script I am using was actually written by Sanjay WS from code I found on this link, and then modified to split outgoing messages into extension-to-extension IMs and outgoing SMS messages. So by design it does just what you suggested; it allows incoming messages to be queued until the recipient’s extension is available to receive the message.

Well, as a follow-up, I got a Let’s Encrypt SSL certificate installed on the server. When I responded you your post the other day, I wasn’t aware now easy it was through FreePBX! I was able to do it all from the Dashboard in about 10 minutes.
I already have another server on the home network using port 80, so I had to temporarily change the port forwarding on the router so it pointed port 80 at the FreePBX box so the acme client could authenticate, but that was no big deal.
The only thing I struggled with was getting the SSL to then function properly on the non-standard port I am using for receiving SMSs from Flowroute. I have a fair bit of experience with Apache configuration, so it wasn’t so bad, but it still took me a minute to properly configure Apache for SSL on a port other than 443.
Long story short,the Callback URL I provide to Flowroute now has an “HTTPS” in front of it.
Oh and by the way, I checked and Flowroute’s URL for receiving SMS messages is an HTTPS address, so messages are now secure in both directions.
Thanks again for your suggestions (and your concerns) regarding security. I never really worried about security before, but it seems like having a VoIP server (even behind a firewall) is a magnet for hackers. I need to step up my game.

3 Likes

Would it be possible for you to create a guide on how to set this up for a novice? I’d like to get this going as well.

3 Likes

Seconded!

can you give me codes and configurations.

I am trying to handle sms over asterisk . I use http api and bulk sms. can you tell me how to handle sms before sending and add some marks in it as a string.

thanks in advance

+1 - I have several clients on FlowRoute, would love to see this.

I would also love it if Sangoma could support this directly through major vendors like Twilio and FlowRoute…would be a HUGE value add…

4 Likes

Add Telnyx to this mix.

I know this is pretty old.

Anyone have a way to do this with FreePBX? or maybe some script or asterisk changes?

Almost the same problem was with our system, which have been build for bulk sms services…

I would be very interested in how you did this… I have been using Twilio for years now, and am wanting to integrate sms into my freepbx somehow. If you can share what all needs to be done I would appreciate it greatly!

I don’t have my code for Twilio anymore. I use Telnyx now and have code for that. The APIs are very similar.

I worked out a way to use an otherwise unused field in FreePBX extension config to indicate which phones can send and receive SMS and the DID they will send/receive as.

The scripts are a bit much to paste here so I will put them on github.

The components are essentially:

  • a php script to receive SMS from the provider’s web API
  • another php script to send SMS to the provider’s web API
  • some dialplan in the /etc/asterisk/extensions_custom.conf file for routing SMS
  • a “loopback” SIP trunk to receive SIP MESSAGEs from the script
  • updates to each extension in FreePBX that will use SMS

This will give you the ability to send and receive SMSes from SIP phones that implement the MESSAGE method of sending text. What it doesn’t give you is SMS from the User Control Panel, which is a nice feature but only available now using SIPStation or Clearly IP SIP trunks.

I’ll come back and update the post after I’ve cleaned up my code and put it on github somewhere.

2 Likes

I put my scripts and documentation on github at https://github.com/simontelephonics/freepbx-telnyx-sms

These are specific to Telnyx but could be easily adjusted for any web API-based SMS exchange.

5 Likes

Thanks for this script, I was looking for a way to use Telnyx SMS with FreePBX.

However, after setting things up as per your instruction on Github, it doesn’t work. Perhaps you can help point me in the right direction to troubleshoot?

I can access both telnyx.php and out.php from a browser. When I access telnyx.php I get “OK” displayed in the browser. When I access out.php I get a blank screen.

I added a folder called php-sip under the sms folder and uploaded the PhpSIP.Exception.php and the PhpSIP.class.php files to that directory with no modifications.

The owner of the sms folder and subdirectories and files is “asterisk” with permissions set to 0775

I am using the Groundwire softphone

When I send an sms message telnyx reports receiving a message but nothing happens on my phone.

When sending a message from my phone it appears to send but I get not “outgoing” message reported at Telnyx.

I see no log files in /tmp/

Any ideas?

Thanks!

Asterisk logs in /var/log/asterisk/full will show you if something has gone wrong when executing dialplan, and Apache httpd logs in /var/log/httpd/error_log or access_log will tell you if PHP is having a problem with the script.