How to know if an SMS sending is failed or successful? - python

I' creating a SMS gateway from GSM Modem port. I need to verify if an SMS sending is failed or successful. So I think the ways to check failed or success is to check the message storage called outbox if success and failed to draft.But, if I try to issue AT commands to check storage by index or to print the messages contained in all indexes, it returns nothing.
Response after sending a message:
+CMGS: 170
as I read we can read the message with AT+CMGR command
modem = serial.Serial('COM5', 9600, timeout=0)
modem.write(b'AT+CMGR=170\r')
while True:
print(modem.read(100))
input('Type to see response')
I tried also with the command AT+CMGR="ALL" to print out anything in storage, but, no messages are printed out.

Command AT+CMGS directly sends SMSs without storing them. In its command response
+CMGS: 170
number 170 is just a progressive number counting successful sends (it is incremented up to 255 and the restarts from 0) and it is completely unrelated to SMS memory location in which it is stored.
But fortunately that response is sent by the modem only when the SMS is successfully transmitted, otherwise an ERROR response is returned. What does "sent" mean? Just that is has been successfully delivered to SMS service center. Actual delivery to SMS recipient is usually immediate, but it might also be delayed by network congestion or by recipient unavailability.
Just for completeness, AT+CMGR=<index> and AT+CMGL=ALL can actually show also sent messages, but only for those stored with AT+CMGW before sending them. For example with +CMGL you may have N rows, each one reporting:
+CMGL: <index>,<stat>,...
in which can have the following values:
"REC UNREAD" - new incoming message
"REC READ" - already read incoming message
"STO UNSENT" - stored message not yet sent
"STO SENT" - stored message already sent <-- this one is relevant for you

Related

Test of sending & receiving message for Azure Service Bus Queue

I would like to write an integration test checking connection of the Python script with Azure Service Bus queue. The test should:
send a message to a queue,
confirm that the message landed in the queue.
The test looks like this:
import pytest
from azure.servicebus import ServiceBusClient, ServiceBusMessage, ServiceBusSender
CONNECTION_STRING = <some connection string>
QUEUE = <queue name>
def send_message_to_service_bus(sender: ServiceBusSender, msg: str) -> None:
message = ServiceBusMessage(msg)
sender.send_message(message)
class TestConnectionWithQueue:
def test_message_is_sent_to_queue_and_received(self):
msg = "test message sent to queue"
expected_message = ServiceBusMessage(msg)
servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONNECTION_STRING, logging_enable=True)
with servicebus_client:
sender = servicebus_client.get_queue_sender(queue_name=QUEUE)
with sender:
send_message_to_service_bus(sender, expected_message)
receiver = servicebus_client.get_queue_receiver(queue_name=QUEUE)
with receiver:
messages_in_queue = receiver.receive_messages(max_message_count=10, max_wait_time=20)
assert any(expected_message == str(actual_message) for actual_message in messages_in_queue)
The test occassionally works, more often than not it doesn't. There are no other messages sent to the queue at the same time. As I debugged the code, if the test does not work, the variable messages_in_queue is just an empty list.
Why doesn't the code work at all times and what should be done to fix it?
Are you sure you don't have another process that receive your messages ? Maybe you are sharing your queue connections strings with other colleagues, build machines...
To troubleshoot you need to keep an eye on the Queue monitoring on Azure Portal. Debug your test and look at incoming messages if it increment by 1. Then continue your debug and check if it decrement by 1.
Also, are you sure that this unit test is useful? It looks like you are testing your infra instead of testing your code

Script from cron sends >50 mails on errors, 1 on success

I have an issue which I really cannot figure out.
The following snippets from my Python script zips a directory and sends a mail on success. It also sends a mail if an error occured. And here is the issue:
When I execute the script manually, everything works fine.
1 mail on success, 1 mail if an error occured.
If the script is run from cron though, I reveive over 50 emails if an error occures (on success only one)! All mails have the same content (the error message), and all mails are sent at the same time (exact as "hh:mm").
This is the script snippet:
def backup(pathMedia, pathZipMedia):
[...]
try:
createArchive(pathMedia, pathZipMedia)
except Exception as e:
sendMail('Error in zipping the media dir: ' + str(e))
sys.exit()
sendMail('Backup successfully created!')
def sendMail(msg):
sent = 0
SMTPserver = '[...]'
sender = '[...]'
destination = ['...']
USERNAME = '[...]'
PASSWORD = '[...]'
text_subtype = 'plain'
subject='Backup notification'
content=msg
try:
msg = MIMEText(content, text_subtype)
msg['Subject'] = subject
msg['From'] = sender
conn = SMTP(SMTPserver)
conn.set_debuglevel(False)
conn.login(USERNAME, PASSWORD)
try:
if (sent == 0):
conn.sendmail(sender, destination, msg.as_string())
sent = 1
finally:
conn.quit()
except Exception as e:
sys.exit()
My crontab is the following:
## run the backup script every 3 days at 4am
* 4 */3 * * /root/backup.py >/dev/null 2>&1
I fixed the orrucring errors now, but it still might happen again.
And I'm really curious about why this issue occurs!
Thanks!
The * at the beginning of your crontab line says "run this job every minute".
Presumably a successful run of the first job at 4:00 causes the following 59 runs to find that no work needs to be done, therefore they don't attempt to create a backup and they exit quietly without sending email. But an unsuccessful run at 4:00 will leave work to be done by the next job at 4:01, and again the minute after that, and so on until 4:59. All of those jobs try to create a backup and all of them fail, so you get something like 60 failure emails. (Or fewer if one of the jobs manages to succeed, breaking the chain of failures.)
To fix the crontab line to run the job only one time at 4:00am, change the first * to a 0.
I don't know why your failure emails all have the same timestamp. Are you certain that they're all exactly the same? If so, perhaps they're being batched by your mail system and are assigned a Date header at the time the batch is processed. Or perhaps all of the jobs are started by cron and then they all wait, blocked until some system timeout or other event occurs, and then they all experience the failure simultaneously and all send emails at the same time.

Always Open Publish Channel RabbitMQ

I am trying to integrate snmptrapd and RabbitMQ for delivering traps notifications to an exterior system.
My system is composed of 3 components:
A Linux virtual machine with snmptrapd and RabbitMQ (Publisher);
A Linux virtual machine with RabbitMQ (Consumer);
A Linux bare metal with docker so I can have a lot of containers sending traps (using nping)
The snmptrapd part is simple:
authCommunity execute mycom
traphandle default /root/some_script
In my first attempts the some_script was written in Python, but the performance was not perfect (20 containers sending 1 trap per second during 10 seconds, I only received 160 messages in the consumer).
#!/usr/bin/env python
import pika
import sys
message = ""
for line in sys.stdin :
message += (line)
credentials = pika.PlainCredentials('test', 'test')
parameters = pika.ConnectionParameters('my_ip', 5672, '/', credentials)
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
channel.queue_declare(queue='snmp')
channel.basic_publish(exchange='',
routing_key='snmp',
body=message)
connection.close()
I switched to Perl and now I can get 200 traps/messages.
My Perl script uses Net::AMQP::RabbitMQ
#!/usr/bin/perl
use Net::AMQP::RabbitMQ;
foreach my $line ( <STDIN> ) {
chomp( $line );
$message = "$message\n$line";
}
my $mq = Net::AMQP::RabbitMQ->new();
$mq->connect("my_ip", {
user => "test",
password => "test",
vhost => "/"
});
$mq->channel_open(1);
$mq->publish(1, "snmp", $message);
$mq->disconnect();
But I want better. I tried 200 containers sending 1 trap per second and it failed miserably, receiving only around 10% of messages in the consumer.
I think this has to do with the overhead of always have to open, publish and close the channel in RabbitMQ per trap received, because at the network level I receive all the messages (checked trough a tcpdump).
Is there a way to keep an always-open publish channel so I don't have to reopen/create a connection to the queue?
Asking if you can talk to RabbitMQ server without connecting to it first is like asking if you can talk to someone on the telephone without connecting to their phone first (by dialing and answering).
You really should reuse your connection if you're going to send multiple messages, but you do need a connection first!
Anyway, the problem isn't with the publisher. It's the consumer that's buggy if it's losing messages.

Notification cannot be received on IOS for the first time with apnsclient for python

I use apns-client package in python to push notification to IOS devices
self.con = self.session.get_connection("push_production", cert_file=PRO_PEM_FILE, passphrase=PASS_PHRASE)
self.srv = APNs(self.con)
message = Message([token], badge = badge, alert = alert)
res = self.srv.send(message)
for token, reason in res.failed.items():
code, errmsg = reason
print "Device failed: {0}, reason: {1}".format(token, errmsg)
for code, errmsg in res.errors:
print "Error:", errmsg
if res.needs_retry():
retry_message = res.retry()
With the code above,I can receive notification most of the time.
However,if several hours has passed since the last notification is received,I can not receive notification without any exception at server side.
I can tell the code self.srv.send(message) did excute without any response,according to the apns-client document,no response means sending notification successfully.
What can I do to make sure client does receive server's notification?
Any help will be appreciated!
Push Notification is not 100% reliable and it will not guaranteed that you will receive it 100% of the time.
See: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
Quality of Service
Apple Push Notification service includes a default Quality of Service
(QoS) component that performs a store-and-forward function.
If APNs attempts to deliver a notification but the device is offline,
the notification is stored for a limited period of time, and delivered
to the device when it becomes available.
Only one recent notification for a particular application is stored.
If multiple notifications are sent while the device is offline, each
new notification causes the prior notification to be discarded. This
behavior of keeping only the newest notification is referred to as
coalescing notifications.
If the device remains offline for a long time, any notifications that
were being stored for it are discarded.
If you have any important message that you want the user to receive, I would like to suggest you to try Local Notification.

sending a period to end a mail DATA telnet session in python

im using a telnetlib in python to connect to a simple mail server and send out an email; everything works fine until the very end after i enter the DATA command, you submit the body of your message and in order to submit the email in the server's queue, you need to type a period "." on a new line by itself so my end transaction snippet looks like so
self.tnet.write("\n.\n")
self.tnet.read_until("250")
where self.tnet is my telnet session var and read_until waits for the 250 Ok response saying the email has been sent to the queue of the email server and on its way for delivery; however, i do not get that 250 Ok response back and the connection times out to my 10sec timeout flag and no email is received in my inbox... any ideas? ive also tried
self.tnet.write(raw_input()+"\n")
and ive also tried grabbing the raw socket
self.sock=self.tnet.get_socket()
self.sock.send(".\n")
print self.sock.recv(1024)
no response... :/
ive also tried the return carriage "\r" in combination with "\n" and on it own to no avail
any ideas?
thank you,
~george
you need the <CR><LF> newline-squence try:
self.tnet.write("\r\n.\r\n")
hope that helps

Categories

Resources