接收短信并转发至 Telegram

虽然现在已经有一些工具可以实现接收短信并转发至 Telegram 的操作,但是还是没有自己制作的更让自己满意,毕竟自己的一些奇思妙想是其无法直接实现的。

The python exemple is just an exemple, it’s incomplete. It does not read sms in the memory (if you receive a sms before starting the script). And it does not concat multiple parts sms (it will print unordered parts).
Also, as your live read sms script is running, you cannot send sms with another script because the dongle is busy.

Here is my own script to read all kind of SMS and send in same time.

安装依赖

Don’t use python-gsmmodem that is deprecated but python-gsmmodem-new

pip install python-gsmmodem-new
pip install threaded

监听新短信

$> python2.7 python-gsmmodem-advanced-read.py
Initializing modem...
Waiting for new SMS message...

Keep this process running in background, for exemple with screen

Python 文件部分

收到短信时,自动将短信转发至 Telegram

文件名 python-gsmmodem-advanced-read.py

#!/usr/bin/env python

from __future__ import print_function
from datetime import datetime
from gsmmodem.modem import GsmModem, Sms
from gsmmodem.pdu import Concatenation

import logging
import Pyro4.core
import threading

PORT = '/dev/ttyUSB0'
BAUDRATE = 115200
PIN = None  # SIM card PIN (if any)

concat_sms = {}

@Pyro4.expose
class RemoteSMSHandler(object):
    def __init__(self, m):
            self.modem = m
    def sendSMS(self, to, message):
        try:
            self.modem.sendSms(to, message)
            return "Message sent to {0}.\n".format(to)
        except Exception, e:
            return "Failed to send SMS: " + str(e)

def handleSms(sms):
    concat = None
    message = None
    for i in sms.udh:
        if isinstance(i, Concatenation):
            concat = i
            break
    if concat:
        if concat_sms.has_key(concat.reference) == False:
            concat_sms[concat.reference] = {} #numpy.empty(concat.parts, dtype=string)
        concat_sms[concat.reference][concat.number] = sms.text
        print(u'== Partial message received ==\n[{0}/{1}] reference{2}\n'.format(len(concat_sms[concat.reference]), concat.parts, concat.reference))
        if len(concat_sms[concat.reference]) == concat.parts:
            sortedParts = sorted(concat_sms[concat.reference].iteritems())
            message = "".join([x[1] for x in sortedParts])
            del concat_sms[concat.reference]
    else:
        message = sms.text

    if message:
        print(u'== SMS message received ==\nFrom: {0}\nTime: {1}\nMessage:\n{2}\n'.format(sms.number, sms.time, message))
        date = datetime.today().strftime('%Y%m%d%H%M%S%f')
        # Uncomment to save the SMS in a file
        #with open('/path/to/messages/' + date + '.txt', 'w') as the_file:
        #    the_file.write('{0}:{1}'.format(sms.number, sms.text))

def checkStoredSms(modem):
    # print('Processing stored SMS...')
    modem.processStoredSms(False)
    threading.Timer(10.0, checkStoredSms, [modem]).start()

def main():
    print('Initializing modem...')
    # Uncomment the following line to see what the modem is doing:
    #logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
    modem = GsmModem(PORT, BAUDRATE, smsReceivedCallbackFunc=handleSms)
    modem.smsTextMode = False
    modem.connect(PIN)
    threading.Timer(10.0, checkStoredSms, [modem]).start()
    print('Waiting for new SMS message...')

    myRemoteSMSHandler = RemoteSMSHandler(modem)

    daemon = Pyro4.Daemon.serveSimple({
        myRemoteSMSHandler: 'RemoteSMSHandler',
    }, host="127.0.0.1", port=9091, ns=False, verbose=False)
    

    daemon.requestLoop()

if __name__ == '__main__':
    main()

原文

接收短信并转发至 Telegram
Read long SMS with python-gsmmodem (and send SMS with same running script)