SMS gateway and push notifications
Tags: sms, notifications, gammu
Published: 2019-07-15 21:44:56

---
title: SMS gateway and push notifications
published: true
tags: sms,notifications,gammu
canonical_url: https://jonnev.se/sms-gateway-and-push-notifications/
---

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](https://playsms.org) or [smsgateway](https://github.com/n0r1sk/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](https://wammu.eu/gammu/). I found this [guide](https://andypi.co.uk/2017/05/06/raspberry-pi-sms-to-email-gateway-part-1/) 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](http://www.draisberghof.de/usb_modeswitch/device_reference.txt) for `usb_modeswitch` if it's supported. There's also a [parameter reference](http://www.draisberghof.de/usb_modeswitch/parameter_reference.txt) 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](https://github.com/huginn/huginn) instance and from there to [Pushover](https://pushover.net). 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](https://github.com/andy-pi/rpi-sms-gateway/blob/master/receivesms.py).

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](https://github.com/huginn/huginn/wiki/Using-a-Webhook-Agent-with-external-software). 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](https://github.com/huginn/huginn/wiki/Agent-Types-&-Descriptions#post-agent).

If you have any questions drop me an email or tweet me.