SMS gateway and push notifications
Jon Neverland
Posted on July 15, 2019
A lot of services today either require or really want you to provide a cellphone number when signing up. I prefer not sharing my private number with these services and I also prefer not having these texts clog up my inbox.
First I thought I could do this with Twilio but apparently they don't allow receiving texts from short codes like Twitter and Facebook uses. So I decided to build an SMS gateway! You don't really need much to do this
- A 3G/4G modem
- A sim card, preferably prepaid
- A computer :)
There are a few frameworks if you want more advanced features, for example playSMS or smsgateway. I haven't tried any of these myself but they look great! Since I only really wanted to receive texts I went with gammu. I found this guide which explained most of what I had to do.
I had an old Huawei E398 laying around at home. I got it working with the instructions below but after a few hours it would disconnect and I had to reinsert it. I'm not sure if this was due to a faulty modem or something else.. So YMMV!
Now I'm using a Huawei E122 and it worked OOTB. lsusb
for that modem gives
ID 12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem
If you have another modem it might be worth checking out the device reference for usb_modeswitch
if it's supported. There's also a parameter reference for those who don't like man-pages
.
Switching usb mode
Most modems will present themselves as a USB storage when you insert them, mostly for Windows users to they can install drivers. So you need to tell it to switch to modem mode and for this we use usb-modeswitch
.
Instructions for Huawei E398
sudo apt-get install gammu usb-modeswitch
Check what mode we're in, for my modem storage mode looked like this
lsusb
=> Bus 002 Device 019: ID 12d1:1505 Huawei Technologies Co., Ltd. E398 LTE/UMTS/GSM Modem/Networkcard
12d1
above is the vendor ID and 1505
the product ID.
Now you need to find the product ID of the modem mode. Some guides recommended restarting the computer with the modem plugged in but that didn't help for me so I had to google a bit. There are tons of forum posts for different modems and in my case I found the correct ID to be 1506
.
You also need to find the "message-content" to send the modem with the -M
flag.
Switch the modem mode
# -v is current vendor ID
# -p is current product ID
# -V is target vendor ID (usually the same)
# -P is target product ID
# -M is the message
sudo usb_modeswitch -v 12d1 -p 1505 -V 12d1 -P 1506 -M
"55534243123456780000000000000011062000000100000000000000000000"
Check that the modem has switched mode
lsusb
=> Bus 002 Device 005: ID 12d1:1506 Huawei Technologies Co., Ltd. Modem/Networkcard
There should now be one or more devices to use
dmesg | grep tty
# Should give something like
GSM modem (1-port) converter now attached to ttyUSB0
GSM modem (1-port) converter now attached to ttyUSB1
GSM modem (1-port) converter now attached to ttyUSB2
Run the gammu config and set port
to /dev/ttyUSB0
sudo gammu-config
Check if gammu can identify the modem
sudo gammu --identify
Device : /dev/ttyUSB0
Manufacturer : Huawei
Model : unknown (E398)
Firmware : xxx
IMEI : yyy
SIM IMSI : zzz
All good! Now you should be able to send an sms like so
sudo gammu sendsms TEXT [phonenumber] -text "Ohhai"
Automatically switch mode when inserted or after reboot
After a reboot or unplug and reinsert the modem usually switches mode again. To make sure we always are in modem mode you need to create a config for usb_modeswitch
matching the vendor ID and product ID.
sudo nano /etc/usb_modeswitch.d/12d1:1505
DefaultVendor=0x12d1
DefaultProduct=0x1505
TargetVendor=0x12d1
TargetProduct=0x1506
MessageContent="55534243123456780000000000000011062000000100000000000000000000"
Symlink to /dev/sms for consistency
It might be a good idea to create a symlink for your device so your settings for gammu
always works, otherwise sometimes after reboot it might switch to /dev/ttyUSB1
or whatever.
sudo nano /etc/udev/rules.d/999-sms-gateway.rules
# Add this line
SUBSYSTEM=="tty", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1506", SYMLINK+="sms"
# Then
sudo udevadm control --reload
Forward texts with WebHook
I wanted to send all received texts to my Huginn instance and from there to Pushover. Huginn supports a bunch of services so if you prefer Slack or even Twitter that's no problem!
I'm using a modified version of this script.
Install gammu-smsd
and configure it.
sudo apt-get install gammu-smsd
sudo pip install requests
sudo nano /etc/gammu-smsdrc
# Change the port in the [gammu] section to your device
# Add the RunOnReceive in the [smsd] section.
# RunOnReceive = python /opt/gammu/receivesms.py
sudo service gammu-smsd restart
Feel free to change the path of the script, I put in it /opt/gammu
and chown
:ed the dir to gammu.
Modified version of the script
#!/usr/bin/env python
from __future__ import print_function
import os, sys, re, requests
def get_message():
files = [os.path.join('/var/spool/gammu/inbox/', m) for m in sys.argv[1:]]
files.sort() # make sure we get the parts in the right order
number = re.match(r'^IN\d+_\d+_\d+_(.*)_\d+\.txt', os.path.split(files[0])[1]).group(1)
text = ''
for f in files:
text += open(f, 'r').read()
try:
text = text.decode('UTF-8', 'strict')
except UnicodeDecodeError:
text = text.decode('UTF-8', 'replace')
return number, text
number, text = get_message()
request = requests.post('YOUR_HUGINN_URL', data={
'from': number,
'message': text
})
To get the url for Huginn, all you need to do is to create a Webhook Agent. Now try sending a text to your phonenumber and it should show up in Huginn! From there you can forward it to whatever service you prefer, either with one of the built-in Agents or a regular WebHook with Post Agent.
If you have any questions drop me an email or tweet me.
Posted on July 15, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.