Отправка SMS кириллицей с AT-модема

от автора

Оперативное информирование клиентов, когда их достаточно много для ручного обзвона, но недостаточно много для подключения массового сервиса, вроде sms.ru (на самом деле сервис хорош, но недавняя политика некоторых мобильных операторов создала определённые финансовые сложности ввиду заградительных тарифов на использование услуг sms-рассылок с/без использования имён) родило потребность в применении независимого инструмента.

Путем продолжительных скитаний по просторам сети, был изучен ряд материалов и некоторые готовые решения. Спасибо dos999 (Ссылка на пост) за отправную точку, но хотелось бы реализовать это «модном» на python3.

Была предпринята попытка адаптировать изложенную логику на основе полученных знаний, но уперся в кириллическую кодировку, т.к. готового кодера в UCS-2 python не имеет, а варианты на основе utf-16 приводили к какому-то такому результату «PÉQ@P>Q£Q$P>P9«.

Но, кто ищет — то находит. Попалась мне готовая реализация на python2 от huh-muh (Ссылка на пост). Адаптировать под python3 труда не составило:

import serial import time import random # процедура для отправки строки в модем и получения ответа def str_send (ser, textline):     print("<<" + textline)     ser.write(bytes(textline, "utf-8"))     out = ''     N = 10     while N > 0:         time.sleep(1)         while ser.inWaiting() > 0:             out += str(ser.read(1))         if ('OK' in out) or ('ERROR' in out) or ('>' in out):             print(">>" + out)             N = 1         N -= 1  # функция преобразования телефонного номера в формат, пригодный для SMS def PhoneNumberToSMS(number):     number += 'F'     result = '0B' + '91'     i = 0     while i < len(number):         result += number[i+1] + number[i]         i += 2     return result  # функция, кодирующая юникодную строку в формат SMS def TextToSMS(text):     b = text     result = ''     i = 0     while i < len(b):         o = ord(b[i])         result += ("%0.2X" % (o//256)) + ("%0.2X" % (o%256))         i += 1     return result  # вводим с консоли сообщение и переводим его в юникод  message = input('Текст сообщения:\n') # message = message.decode('utf-8')  # если сообщение большое - режем его на кусочки для механизма конкатенации SMS chunks = []  if len(message) > 70:     while len(message) > 66:         chunks.append(message[:66])         message = message[66:] if len(message) > 0:     chunks.append(message)  # готовим номер группы сообщений и устанавливаем 6-й бит SMS_SUBMIT_PDU SMS_SUBMIT_PDU = "11" CSMS_reference_number = "" if len(chunks) > 1:     SMS_SUBMIT_PDU = "51"     CSMS_reference_number = "%0.4X" % random.randrange(1,65536)  # связываемся с модемом ser = serial.Serial("COM4", 9600, timeout=1)  # устанавливаем нужный формат передачи данных str_send(ser, 'AT+CMGF=0\r')  # передаем кусочки сообщения i = 1 for chunk in chunks:     emessage = TextToSMS(chunk)     if CSMS_reference_number != "":         emessage = "06" + "08" + "04" + CSMS_reference_number + \         ("%0.2X" % len(chunks)) + ("%0.2X" % i) + emessage     sms = "00" #Накидываем тело сообщения в формате PDU     sms += SMS_SUBMIT_PDU     sms += "00"     sms += PhoneNumberToSMS("7ХХХХХХХХХХ")     sms += "00"     sms += "08"     sms += "AA"     sms += "%0.2X" % (len(emessage)//2)     sms += emessage     str_send(ser, 'AT+CMGS=' + str(len(sms)//2-1) + '\r')     str_send(ser, sms + '\x1A')     i += 1  # отвязываемся от модема ser.close()

В целом, код готов. Теперь можно реализовать массовую рассылку, скармливая скрипту файл с телом сообщения и списком адресатов в формате 79876543210, но это уже другая история


ссылка на оригинал статьи https://habr.com/ru/post/662291/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *