def to_gammu(message, msgclass=1): """ converts NoSMS message to Gammu msg """ # important to know length and type of message try: text = message.text.decode('utf-8') except (UnicodeEncodeError, UnicodeDecodeError): text = message.text number = message.identity is_unicode = msg_is_unicode(text) length = text.__len__() #logger.info(u"OUTGOING [%d] %s message: %s" \ print(u"INFO: OUTGOING [%d] %s message: %s" \ % (length, u"unicode" \ if is_unicode \ else u"ascii", \ text)) # single ascii SMS # max_length of 160 chars. if not is_unicode and length <= 160: encoded = [{'Number': number, 'Text': text}] # multipart, ascii SMS. # will be split in 153 chars long SMS. elif not is_unicode and length > 160: smsinfo = {'Class': msgclass, \ 'Unicode': False, \ 'Entries': [{'ID': 'ConcatenatedTextLong', \ 'Buffer': text}]} encoded = gammu.EncodeSMS(smsinfo) # single unicode SMS. # max_length of 70 chars. elif is_unicode and length <= 70: smsinfo = {'Class': msgclass, \ 'Unicode': True, \ 'Entries': [{'ID': 'ConcatenatedTextLong', \ 'Buffer': text}]} encoded = gammu.EncodeSMS(smsinfo) # multipart unicode SMS # will be split in 63 chars long SMS. else: smsinfo = {'Class': msgclass, \ 'Unicode': True, \ 'Entries': [{'ID': 'ConcatenatedTextLong', \ 'Buffer': text}]} encoded = gammu.EncodeSMS(smsinfo) # loop on parts for msg in encoded: msg['SMSC'] = {'Location': 1} msg['Number'] = number return msg
def post(self): ''' Send a SMS''' json_data = request.json message = json_data["message"] numbers = json_data["recipients"] results = [] for number in numbers: # Create SMS info structure smsinfo = { 'Class': -1, 'Unicode': True, 'Entries': [{ 'ID': 'ConcatenatedTextLong', 'Buffer': message }] } # Encode messages encoded = gammu.EncodeSMS(smsinfo) for sms in encoded: # Fill in numbers sms['SMSC'] = {'Location': 1} sms['Number'] = number msg_id = smsd.InjectSMS(encoded) results.append({"DestinationNumber": number, "smsID": msg_id}) return {'results': results}, 200
async def async_send_message(self, message="", **kwargs): """Send SMS message.""" smsinfo = { "Class": -1, "Unicode": False, "Entries": [{ "ID": "ConcatenatedTextLong", "Buffer": message }], } try: # Encode messages encoded = gammu.EncodeSMS(smsinfo) # pylint: disable=no-member except gammu.GSMError as exc: # pylint: disable=no-member _LOGGER.error("Encoding message %s failed: %s", message, exc) return # Send messages for encoded_message in encoded: # Fill in numbers encoded_message["SMSC"] = {"Location": 1} encoded_message["Number"] = self.number try: # Actually send the message await self.gateway.send_sms_async(encoded_message) except gammu.GSMError as exc: # pylint: disable=no-member _LOGGER.error("Sending to %s failed: %s", self.number, exc)
def send_sms(text, number): # Create SMS info structure smsinfo = { 'Class': 1, 'Unicode': True, 'Entries': [{ 'ID': 'ConcatenatedAutoTextLong', 'Buffer': text }] } # Encode messages encoded = gammu.EncodeSMS(smsinfo) # Send messages for message in encoded: message['SMSC'] = {'Location': 1} message['Number'] = number # Actually send the message try: sm.SendSMS(message) except gammu.ERR_GETTING_SMSC as e: weechat.prnt('', "%s%s" % (weechat.prefix("error"), e)) except gammu.ERR_TIMEOUT as e: weechat.prnt('', "%s%s" % (weechat.prefix("error"), e))
def test_sendsms_long(self): state_machine = self.get_statemachine() text = ('Very long python-gammu testing message sent ' 'from example python script. ') * 10 smsinfo = { 'Class': -1, 'Unicode': False, 'Entries': [{ 'ID': 'ConcatenatedTextLong', 'Buffer': text }] } # Encode messages encoded = gammu.EncodeSMS(smsinfo) self.assertEqual(len(encoded), 5) # Send messages for message in encoded: # Fill in numbers message['SMSC'] = {'Location': 1} message['Number'] = '123456' # Actually send the message state_machine.SendSMS(message)
def send_SMS(self, content, targetnr): # Check if String holds only ASCII characters or is Unicode try: content.encode('ascii') isUnicode = False except UnicodeEncodeError: isUnicode = True smsgwglobals.pidlogger.debug("MODEM: isUnicode = " + str(isUnicode)) # if content fits in a short sms send a standard Text message else # send a ConcatenatedTextLong message lencontent = len(content) if (isUnicode and lencontent <= 70): whichID = 'Text' elif (not isUnicode and lencontent <= 160): whichID = 'Text' else: whichID = 'ConcatenatedTextLong' # Fixes issue #43 - changing to not setting a SMS Class smsinfo = { 'Class': -1, 'Unicode': isUnicode, 'Entries': [{ 'ID': whichID, 'Buffer': content }] } # Encode message encoded = gammu.EncodeSMS(smsinfo) # Replace + with country exit code of Modem tonr = self.transform_targetnr(targetnr) # Send message for message in encoded: message['SMSC'] = {'Location': 1} message['Number'] = tonr try: msgref = self.__statemachine.SendSMS(message) status = True status_code = 1 except gammu.GSMError as e: status_code = e.args[0]["Code"] msgref = str(e) status = False except Exception as e: msgref = str(e) status = False smsgwglobals.pidlogger.debug("MODEM: send_SMS to " + str(targetnr) + " has status: " + str(status) + " and " + "msgref (" + str(msgref) + ")") return status, status_code
def on_mqtt_message(client, userdata, msg): try: logging.info(f'MQTT received : {msg.payload}') payload = msg.payload.decode("utf-8") data = json.loads(payload, strict=False) except Exception as e: feedback = {"result":f'error : failed to decode JSON ({e})', "payload":payload} client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False)) logging.error(f'failed to decode JSON ({e}), payload: {msg.payload}') return for key, value in data.items(): if key.lower() == 'number': number=value if key.lower() == 'text': text=value if 'number' not in locals() or not isinstance(number, str) or not number: feedback = {"result":'error : no number to send to', "payload":payload} client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False)) logging.error('no number to send to') return False if 'text' not in locals() or not isinstance(text, str): feedback = {"result":'error : no text body to send', "payload":payload} client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False)) logging.error('no text body to send') return False for num in (number.split(";")): num = num.replace(' ','') if num == '': continue smsinfo = { 'Class': -1, 'Entries': [{ 'ID': 'ConcatenatedAutoTextLong', 'Buffer' : text }] } try: logging.info(f'Sending SMS To {num} containing {text}') encoded = gammu.EncodeSMS(smsinfo) for message in encoded: message['SMSC'] = {'Location': 1} message['Number'] = num gammusm.SendSMS(message) feedback = {"result":"success", "datetime":time.strftime("%Y-%m-%d %H:%M:%S"), "number":num, "text":text} client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False)) logging.info(f'SMS sent to {num}') except Exception as e: feedback = {"result":f'error : {e}', "datetime":time.strftime("%Y-%m-%d %H:%M:%S"), "number":num, "text":text} client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False)) logging.error(feedback['result'])
def construct_gammu_multipart_messages(self, message): smsinfo = { 'Class': 1, 'Unicode': not self.is_gsm_charset(message['content']), 'Entries': [{ 'ID': 'ConcatenatedTextLong', 'Buffer': message['content'], }] } return gammu.EncodeSMS(smsinfo)
async def send_message_async(state_machine, number, message): smsinfo = { 'Class': -1, 'Unicode': False, 'Entries': [ { 'ID': 'ConcatenatedTextLong', 'Buffer': message } ]} # Encode messages encoded = gammu.EncodeSMS(smsinfo) # Send messages for message in encoded: # Fill in numbers message['SMSC'] = {'Location': 1} message['Number'] = number # Actually send the message await state_machine.send_sms_async(message)
def sendSMS(phone, text): smsinfo = { 'Class': -1, 'Unicode': True, 'Entries': [ { 'ID': 'ConcatenatedTextLong', 'Buffer': text } ]} encoded = gammu.EncodeSMS(smsinfo) for message in encoded: # Fill in numbers message['SMSC'] = {'Location': 1} message['Number'] = phone # Actually send the message sm.SendSMS(message)
async def async_send_message(self, message="", **kwargs): """Send SMS message.""" if SMS_GATEWAY not in self.hass.data[DOMAIN]: _LOGGER.error("SMS gateway not found, cannot send message") return gateway = self.hass.data[DOMAIN][SMS_GATEWAY][GATEWAY] targets = kwargs.get(CONF_TARGET) if targets is None: _LOGGER.error("No target number specified, cannot send message") return is_unicode = kwargs.get(CONF_UNICODE, True) smsinfo = { "Class": -1, "Unicode": is_unicode, "Entries": [{ "ID": "ConcatenatedTextLong", "Buffer": message }], } try: # Encode messages encoded = gammu.EncodeSMS(smsinfo) except gammu.GSMError as exc: _LOGGER.error("Encoding message %s failed: %s", message, exc) return # Send messages for encoded_message in encoded: # Fill in numbers encoded_message["SMSC"] = {"Location": 1} for target in targets: encoded_message["Number"] = target try: # Actually send the message await gateway.send_sms_async(encoded_message) except gammu.GSMError as exc: _LOGGER.error("Sending to %s failed: %s", target, exc)
def test_link(self): # SMS info about message smsinfo = { 'Entries': [{ 'ID': 'ConcatenatedTextLong', 'Buffer': MESSAGE }] } # encode SMS sms = gammu.EncodeSMS(smsinfo) # link SMS linked = gammu.LinkSMS([[sms[0]], [sms[1]]], True) # decode back SMS decodedsms = gammu.DecodeSMS(linked[0]) # compare results self.assertTrue(decodedsms['Entries'][0]['Buffer'], MESSAGE)
def pduencode(request): pdu = None if request.method == "POST": form = PDUEncodeForm(request.POST) if form.is_valid(): # Prepare message data smsinfo = { "Class": form.cleaned_data["cls"], "Unicode": form.cleaned_data["unicode"], "Entries": [{ "ID": "ConcatenatedTextLong", "Buffer": form.cleaned_data["text"], }], } # Encode SMS encoded = gammu.EncodeSMS(smsinfo) # Fill in remaining data for msg in encoded: msg["SMSC"] = { "Location": 0, "Number": form.cleaned_data["smsc"], "Validity": "Max", } msg["Number"] = form.cleaned_data["number"] msg["Class"] = form.cleaned_data["cls"] # Encode PDU pdu = enumerate( gammu.EncodePDU(e, "Submit").hex() for e in encoded) else: form = PDUEncodeForm() return render( request, "tools/pduencode.html", { "form": form, "pdu": pdu, }, )
def do_smstest(self, smsinfo, expected): # encode SMSes sms = gammu.EncodeSMS(smsinfo) # decode back SMSes decodedsms = gammu.DecodeSMS(sms) # compare text self.assertEqual(decodedsms['Entries'][0]['Buffer'], expected) # do conversion to PDU pdu = [gammu.EncodePDU(s) for s in sms] # Convert back pdusms = [gammu.DecodePDU(p) for p in pdu] # decode back SMS from PDU decodedsms = gammu.DecodeSMS(pdusms) # compare PDU results self.assertEqual(decodedsms['Entries'][0]['Buffer'], expected)
def Preview(self, evt): if len(self.entry['SMSInfo']['Entries']) == 0: dlg = wx.MessageDialog(self, _('Nothing to preview, message is empty.'), _('Message empty!'), wx.OK | wx.ICON_WARNING) else: self.StoreEdited() msg = gammu.EncodeSMS(self.entry['SMSInfo']) info = gammu.DecodeSMS(msg) result = {} result['SMS'] = msg if info is not None: result['SMSInfo'] = info Wammu.Utils.ParseMessage(result, (info is not None)) dlg = MessagePreview( self, ('<i>%s</i><hr>' % (_('Message will fit into %d SMSes') % len(msg))) + Wammu.MessageDisplay.SmsToHtml(self.cfg, result)) dlg.ShowModal() del dlg
def pduencode(request): pdu = None if request.method == 'POST': form = PDUEncodeForm(request.POST) if form.is_valid(): # Prepare message data smsinfo = { 'Class': form.cleaned_data['cls'], 'Unicode': form.cleaned_data['unicode'], 'Entries': [{ 'ID': 'ConcatenatedTextLong', 'Buffer': form.cleaned_data['text'], }] } # Encode SMS encoded = gammu.EncodeSMS(smsinfo) # Fill in remaining data for msg in encoded: msg['SMSC'] = { 'Location': 0, 'Number': form.cleaned_data['smsc'], 'Validity': 'Max', } msg['Number'] = form.cleaned_data['number'] msg['Class'] = form.cleaned_data['cls'] # Encode PDU pdu = enumerate([ binascii.hexlify(gammu.EncodePDU(e, 'Submit')) for e in encoded ]) else: form = PDUEncodeForm() return render(request, 'tools/pduencode.html', { 'form': form, 'pdu': pdu, })
# Create SMS info structure smsinfo = { 'Class': -1, 'Unicode': False, 'Entries': [{ 'ID': 'ConcatenatedTextLong', 'Buffer': 'Very long python-gammu testing message ' 'sent from example python script. ' 'Very long python-gammu testing message ' 'sent from example python script. ' 'Very long python-gammu testing message ' 'sent from example python script. ' }] } # Encode messages encoded = gammu.EncodeSMS(smsinfo) # Send messages for message in encoded: # Fill in numbers message['SMSC'] = {'Location': 1} message['Number'] = sys.argv[1] # Actually send the message state_machine.SendSMS(message)
# -*- coding: UTF-8 -*- # Simple test for testing SMS decoding/encoding # This passes unicode string which can be transferet to GSM charset # to Gammu and expects it to be unchanged in the SMS import gammu # text of sms txt = u'.........1$........2..Ø......3...åÅ....4....Λ....5....Æ....6....ñ....7.........8.........9........0.........1.........2.........3.........4.........5.........6.........7.........8.........9........0.........1.........2.........3.........4.........5.........6.........7.........8.........9....¥€..0' # SMS info about message smsinfo = {'Entries': [{'ID': 'ConcatenatedTextLong', 'Buffer': txt}]} # encode SMSes sms = gammu.EncodeSMS(smsinfo) # decode back SMSes decodedsms = gammu.DecodeSMS(sms) # show results print "Text:", repr(decodedsms['Entries'][0]['Buffer']) print "Comparsion:", (decodedsms['Entries'][0]['Buffer'] == txt) # do conversion to PDU pdu = [gammu.EncodePDU(s) for s in sms] # Convert back pdusms = [gammu.DecodePDU(p) for p in pdu] # decode back SMS from PDU
def encode_sms(smsinfo): return gammu.EncodeSMS(smsinfo)
def run(self): self.sm.Init() while not self.kill.is_set(): # sending outgoing messages try: # retrieve a message from outgoing queue msg = to_modem.get_nowait() except Empty: pass else: # important to know length and type of message text = msg['Text'].decode('utf-8') number = msg['Number'] is_unicode = self.msg_is_unicode(msg) length = text.__len__() logger.info(u"OUTGOING [%d] %s message: %s" \ % (length, u"unicode" \ if is_unicode \ else u"ascii", \ text)) # single ascii SMS # max_length of 160 chars. if not is_unicode and length <= 160: encoded = [msg] # multipart, ascii SMS. # will be split in 153 chars long SMS. elif not is_unicode and length > 160: smsinfo = {'Class': 1, \ 'Unicode': False, \ 'Entries': [{'ID': 'ConcatenatedTextLong', \ 'Buffer': text}]} encoded = gammu.EncodeSMS(smsinfo) # single unicode SMS. # max_length of 70 chars. elif is_unicode and length <= 70: smsinfo = {'Class': 1, \ 'Unicode': True, \ 'Entries': [{'ID': 'ConcatenatedTextLong', \ 'Buffer': text}]} encoded = gammu.EncodeSMS(smsinfo) # multipart unicode SMS # will be split in 63 chars long SMS. else: smsinfo = {'Class': 1, \ 'Unicode': True, \ 'Entries': [{'ID': 'ConcatenatedTextLong', \ 'Buffer': text}]} encoded = gammu.EncodeSMS(smsinfo) # loop on parts for msg in encoded: msg['SMSC'] = {'Location': 1} msg['Number'] = number try: logger.debug(u"Sending SMS: %s" % msg) self.sm.SendSMS(msg) except gammu.ERR_UNKNOWN: pass # receiving incoming messages try: # get first SMS from Modem msg = self.sm.GetNextSMS(0, True)[0] except gammu.ERR_EMPTY: pass else: logger.debug(u"Received SMS: %s" % msg) # remove SMS from modem and move-on if not in white-list if not self.regex.match(msg['Number']): self.delete(msg) else: # if SMS is a part of a multipart SMS # store the part and remove SMS from Modem. if self.msg_is_multipart(msg): self.msg_store_part(msg) self.delete(msg) # if SMS is a single message or was last part of a # multipart message if self.msg_is_complete(msg): # builf concatenated multipart if required if self.msg_is_multipart(msg): msg = self.msg_unified(msg) try: logger.info(u"INCOMING [%d] from %s: %s" \ % (msg['Text'].__len__(), \ msg['Number'], msg['Text'])) # submit message to application res = urlopen('%s?%s' \ % (SENDING_URL, \ urlencode({'from': msg['Number'], \ 'text': msg['Text']\ .encode('utf-8')}))) except IOError: # we don't do anything so modem will find # the SMS again next time pass else: if res.code == 202: # application received the SMS # delete multipart from internal store if self.msg_is_multipart(msg): self.msg_delete_multipart(msg) else: # delete SMS from modem self.delete(msg) # main loop 500ms self.kill.wait(.5) try: # close modem connection properly self.sm.Terminate() except: pass