Thanks to Greig Sheridan (@greiginsydney) I now feel pressured into posting my latest home project.

I am working on a mobile app that will be released very soon, the details of which I cannot share right now, but safe to say it involves sending an SMS or two as part of its functions. When researching SMS gateways, I looked at Twilio being the most obvious, but their pricing structure scared me, especially if the worst best thing to happen is my app goes viral – I could be left with a massive bill for SMSs. Twilio charge 4cents per SMS, Suppose my app sends 100,000 messages in its first week, that’s $4,000 I need to pony upfront as its PAYG.

So there must be a cheaper way of doing this, at least to get me started. Make no mistake, I am fully expecting the Cell carrier to shut me down, but until that day, its fair game 🙂 . So I thought well all I need is a computer, a USB dongle, a SIM card and some basic API coding to string it altogether and make my own gateway.  I wanted something that was cheap, silent running, and simple. The Raspberry Pi was the device that came to the front of my mind.

The Bits

1 x Raspberry Pi 3 Starter Kit from Amazon £49.99 with prime delivery (

1 x Huawei E3531 3G Dongle Unlocked £22.37 on Amazon with Prime Delivery (

1 x Regular SIM from Three (

Total Basket £72.36 including delivery

The Concept

I want to be able to post JSON data to my Raspberry Pi from another app that will include the phone number and message I want to send. I then want the Pi to send that message via the 3G dongle. Simple? Turns out extremely


The starter kit comes with Raspbian, a port of the popular debian linux distro. Must admit never used linux before so the fact this came with Noob OS ticked a lot of boxes for me being a Windows guy.

I have a bit of PHP knowledge from back in the day, so figured I could use that as my web API language, so for this I would need Apache and PHP installed on my Pi. Being web accessible I should probably do this over https with an SSL certificate, so decided to use LetsEncrypt as they offer free 90 days certificates.

I also needed a program that is capable of sending SMS. One thing I learned about linux real quick, is there are like 200 options for anything you want to do. But finally settled on a program called gammu as it seemed the most simple to use.

So now my concept is beginning to take shape SSL –> Apache –> PHP API –> Gammu –> Send SMS

Here is how I did it

Step1 – Give the Pi a static IP so I can NAT 443 from my internet router

sudo nano /etc/dhcpcd.conf

Edit the eth0 profile with the static IP of your choice

Step 2 – Update my Pi

sudo apt-get update

Step 3 – Install Apache

sudo apt-get install apache2 -y

Set permissions on the webroot for the web user

sudo chown -R pi:www-data /var/www/html
sudo chmod -R 770 /var/www/html

Step 4 – Install PHP

sudo apt-get install php php-mbstring

Step 5 – Install Gammu

sudo apt-get install gammu -y

Step 5 – Find USB Dongle


Here is where I found my first problem. Dongles are formatted to work on Windows and usually have a partition between software and modem. When connected to the Pi I saw that the software partition was loaded, and the modem partition inaccessible. If we were to use this dongle I needed to find a way to switch partitions.

After much googling, I found a program called usb_modeswitch, so installed that

sudo apt-get install usb-modeswitch

This was supposed to automatically switch dongles from software to modem mode. However, this particular dongle device was not part of the default library. So a custom configuration file was needed

From the output of lsusb you can get the device ID:Mode, for this modem its 12d1:14dc. I now can create a configuration file specific to this device

sudo nano /etc/usb_modeswitch.d/12d1:1f01

In the file enter the following information


Hit CTRL+O to save the file.

Now shutdown your Pi and uplug it. Then turn on with dongle connected

running lsusb again should now the modem

Now we need to find the port we can use to access the modem.

ls /dev/tty*

We can see 3 new USB ports opened ttyUSB0, ttyUSB1 and ttyUSB2

Step 6 – Configure Gammu to use the required USB port – in my case ttyUSB0

sudo gammu-config

Change the Port to /dev/ttyUSB0 and Save, OK to exit

Step 7 – Test Gammu

Run the following command to send a SMS

sudo gammu sendsms TEXT +447123456789 -text "Your message here"

You should receive your first SMS!

Step 8 – Install LetsEncrypt and Assign a Certificate to Apache

sudo apt-get install certbot

Now make sure your Pi is accessible by the domain FQDN you want as certbot requires your site to be accessible for verification. Do this now

Now request the certificate

sudo certbot certonly --webroot /var/www/html -d

If successful the new certs should be available at this location /etc/letsencrypt/live/

Step 9 – Configure Apache for HTTPS

sudo nano /etc/apache2/sites-available/default-ssl.conf

Comment out the default certs and add in the following

SSLCertficateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/
SSLCertificateChainFile /etc/letsencrypt/live/

Save the file and restart apache

sudo service apache2 restart

Step 10 –  Allow PHP to run Shell Exec

By default PHP will not be allowed to run gammu as shell_exec() as www-data user does not have permission to use the USB device. The following command grants the rights

sudo adduser www-data dialout

Step 11 – Create Your PHP API

Create a file in /var/www/html called sms.php

paste the following code to create a simple API


$content = trim(file_get_contents("php://input"));

$api = $_SERVER['HTTP_X_API_KEY'];

$match = "<api-key here>";

if($api == $match){

$decoded = json_decode($content, true);

Foreach ($decoded as $sms){

$number = $sms["number"];
$message = $sms["message"];

$number = filter_var($number, FILTER_SANITIZE_NUMBER_INT);
$cmd = sprintf('gammu sendsms TEXT %s -textutf8 %s', $number, escapeshellarg($message));


header('HTTP/1.1/ 200');
header('Content-Type: application/json');
$response = [
'Result'=> "SMS Sent to Carrier"

echo json_encode($response); 
header('HTTP/1.1/ 401');
header('Content-Type: application/json');
$response = [
'Result'=> 'API Mismatch - Unauthorized'

echo json_encode($response);



Step 12 – Test Your API use

That’s it, your SMS gateway is built




3 thoughts on “SMS Gateway for Under £73 with Raspberry Pi”

Leave a Reply

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