Telegram SMS gateway/bridge II

Having had the script running for a while, some points for improvement emerged:

  1. multi-sim support (I got two prepaid cards, that might be cancelled if not being used every now and then and it might be clever, to receive the warning messages 😉 )
  2. unicode – there are some messages coming in, that kill the script for encoding problem (need to look into telepot exception handling)
  3. storage (why not keeping messages copies in the database?)
  4. longer messages – I ceceived one from t-mobile which again killed the script

so, for a starter lets have a look at Nr 1 and 2:

I have created a dual-model environment following this post: smstools forum

To ensure the umts-sticks will have the correct (fixed) device name I modified the udev-rules as described here: debian handbook on udev

short version: I created udev-rules to create links to the devices as modem1, modem2…


root@tefrod:/home/greaman# cat /etc/udev/rules.d/99-usb-serial.rules
SUBSYSTEM=="tty",ACTION=="add", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1436", SYMLINK+="modem1"
SUBSYSTEM=="tty",ACTION=="add", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1001", SYMLINK+="modem2"

and of course modified the script:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import time
import telepot
import re
import string
import random
import os

class smsbot(telepot.Bot):

    def __init__ (self, uid, token, spooldir):
        super(smsbot, self).__init__(token)
        self._mode = 0
        self._recipient = ""
        self._active = 1
        self._user = uid
        self._spooldir = spooldir
        self._queues = {1:"GSM1",2:"GSM2"}
        self._modem  = 1

    def handle (self, msg):
        chat_id = msg['chat']['id']
        command = msg['text']
        if chat_id != self._user:
            self.sendMessage( chat_id, "unauthorized user")
            return 0
        res = re.match(r'^\\(\w+)\s?([\w\d]*)$', command, flags=0)
        if res:
            if == "status":
            elif == "setrcpt":
                self._recipient =
                self.sendMessage( chat_id, "recipient set to: %s" % self._recipient)
            elif == "open":
                if self._recipient != "":
                    self._mode = 1
                    self.sendMessage( chat_id, "relay active")
                    self.sendMessage( chat_id, "set recipient first!")
            elif == "close":
                self.sendMessage( chat_id, "relay deactived")
                self._mode = 0
            elif == "mdmselect":
                self._modem = int(
                self.sendMessage( chat_id, "modem set")
            elif == "terminate":
                self._active = 0
                self.sendMessage( chat_id, "unrecognized command!")
            if self._mode == 1 and self._recipient != "":
                self.sendsm ( command )
                self.sendMessage( chat_id, "relay not enabled")

    def id_generator(self, size=8, chars=string.ascii_uppercase + string.digits):
        return ''.join(random.choice(chars) for _ in range(size))

    def status (self):
        self.sendMessage( self._user , "recipient: %s, relay status: %d" % (self._recipient, self._active))

    def sendsm (self, msg):
        # add function to handle longer messages
        output = "To: %s \n\n%s" % (self._recipient, msg)
        outlst = []
        if self._modem == 0:
          for key in self._queues:
        for rcpt in outlst:
          filename = os.path.join (self._spooldir, rcpt, self.id_generator())
          fh = open (filename, "w")
          fh.write (output)

    def recvsm (self ):
        for x in os.listdir(self._spooldir+"incoming/"):
            f = open(self._spooldir+"incoming/"+x, 'r',encoding='ISO-8859-15')
            cont = []
            for line in f:
            self.sendMessage(self._user, cont[0]+"\n"+cont[3]+"\n"+cont[12])

    def checkerr ( self ):
        for x in os.listdir(self._spooldir+"failed/"):
            self.sendMessage(self._user, "FAILED:")
            f = open(self._spooldir+"failed/"+x, 'r')
            for line in f:
                self.sendMessage(self._user, str(ln)+line)

    def run (self ):
        while self._active == 1:
            self.recvsm ()
            self.checkerr ()

mybot = smsbot (000000, "#token here", "/var/spool/sms/")

so the system will now receive short messages from two simcard (or more), send messages via those sims individually or simultaniously (just set modem to 0).

Having done that… I will look into the other topics… 😉