0

I am trying to send a message in Python with smtplib. I have a sendEmail(message) function:

def sendEmail(message)
    server = smtplib.SMTP_SSL('mailserver.example.com', 465)
    server.ehlo()
    server.login("username", "password")
    print message
    msg = message
    fromaddr = "myaddr@someplace.com"
    toaddr = "theiraddr@someotherplace.com"
    server.sendmail(fromaddr, toaddr, msg)
    server.quit()

I am trying to do something like this:

myMessage = "A String Literal" + someString
sendEmail(myMessage)

But when I do that I sometimes receive an empty email message. someString is a unicode string pulled from sqlite. I have tried various string concatenations combining literals with literals, sqlite strings with sqlite strings, sqlite strings with literals, each by themselves. I have used + and .join and anything else I can think of to join the strings. It seems like everything works sometimes but nothing works every time.

The "print message" inside sendEmail function always prints the string I expect. smtplib always sends the email message to the correct email address without complaining, it is just sometimes an empty message.

Since I have had everything work and also not work, I don't really trust any solution I come up with if I don't fully understand what is going on. Can anybody help me understand what is happening with these strings so I can construct my message in the most appropriate way and be confident that my application will work reliably?

Here is a more detailed example of what I am trying to do:

#connect to the database
dbconn = sqlite3.connect(config["database"])
dbconn.row_factory = sqlite3.Row
dbc = dbconn.cursor()

while true:
    #step 1: Check the things and set alarm status in the alarms table
    #this step reads from and writes to the database

    #step 2: Check each alarm and send a message if necessary
    dbc.execute('SELECT * FROM alarms')
    theAlarms = dbc.fetchall()

    for theAlarm in theAlarms:
        if bool(theAlarm['alertShouldBeSent'):
            sendEmail('ALARM!!: ' + theAlarm['message'])
            dbc.execute('UPDATE alarms SET alertShouldBeSent=0 WHERE id=?',(theAlarm['id']),)
        elif bool(theAlarm['allClearShouldBeSent']):
            sendEmail('NORMAL: ' + theAlarm['message'])
            dbc.execute('UPDATE alarms SET allClearShouldBeSent=0 WHERE id=?',(theAlarm['id'],))

    dbconn.commit()

Each row in the alarm table defines a condition that should trigger an alarm and has a field that indicates whether the alarm condition is met making the alarm active

theAlarm['message'] from the database is something like "The batteries are on fire" or "Somebody left the door open." There are currently only 4 or 5 rows in the alarms table. The logic that determines theAlarm['alertShouldBeSent'] makes sure an alert is only sent once per alarm condition and won't be continuously sent if the alarm doesn't first reset. The same is true for theAlarm['allClearShouldBeSent']. The loop runs continuously but emails are sent infrequently. In testing, I set one row into an alarm state. I can verify that the code to send the email is triggered when it should be.

1 Answers1

0

Had the same problem as you, so I went googling and I found your post. As I was reading I realised it must be the damn parser smtplib is using. It doesn't know how to parse ":".

There may be other characters it can't parse, but I haven't found any.