smtplib sends blank message if the message contain certain characters

My current script allows me to send emails fine, but there are just some characters it doesn’t like, particularly ':' in this sample.

import smtplib, sys

mensaje = sys.argv[1]
def mailto(toaddrs, msg):
    fromaddr = 'myemailblabla'

    username = 'thisismyemail'
    password = '122344'

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(username, password)
    server.sendmail(fromaddr, toaddrs, msg)
    server.quit()

mailto('<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="691d0c1a1d290e04080005470a0604">[email protected]</a>', mensaje)

If I write a sample message such as, let’s say "Hi theren how are you?" it works fine, but let’s say I try to send a url http://www.neopets.com, the email is sent blank. I believe the ':' causes this issue, so I tried escaping it, but nothing.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The problem is that smtplib is not putting a blank line between the message header and the message body as shown by in the “Show Original” form of my test:

Return-Path: <<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8ae7efcaede7ebe3e6a4e9e5e7">[email protected]</a>>
Received: **REDACTED**
        Fri, 03 Aug 2012 06:56:20 -0700 (PDT)
Message-ID: <<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="586d68693a3c60606c76606d683b6b6a683a183520763f37373f343d763b3735">[email protected]</a>>
Date: Fri, 03 Aug 2012 06:56:20 -0700 (PDT)
From: <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b3ded6f3d4ded2dadf9dd0dcde">[email protected]</a>
http: //www.example.com

Although this is a legal mail header, Mail Transfer Agents and Mail User Agents should ignore apparent header fields they don’t understand. And because the RFC822 header continues until the first blank line and http: looks like a header line, it is parsed as if it were a header. If given a newline:

mensaje = 'nhttp://www.example.com'

Then it works as expected. Although email technically only needs the “envelope” as provided by smtplib the contents of the mail should be more complete if you expect your recipients (and their mailers) to treat the message nicely, you should probably use the email module to generate the body.

added

Based on the doctest in smtplib.py it looks as if this is an intentional feature allowing the caller of sendmail() to append to the header:

     >>> msg = '''\
     ... From: <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e0ad85a08d99ce8f9287">[email protected]</a>
     ... Subject: testin'...
     ...
     ... This is a test '''
     >>> s.sendmail("<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c3aea683aebaedacb1a4">[email protected]</a>", tolist, msg)

Where the From: and Subject: lines are part of the “nice” headers I mentioned above.

Method 2

The proper solution is to use the Python email library to create a valid message, instead of painstakingly learning (or wildly guessing at random) how to construct a valid MIME message structure by joining together pieces of text.

A trivial RFC822 message which contains only ASCII can easily be created with

"From: {0}nTo: {1}nSubject: {2}nn{3}".format(
    fromaddr, toaddr,
    "Hello, I am the exiled prince of Ubandingba",
    "http://clickme.example.net/scam/")

but as soon as you need anything with other character sets, lines longer than some 80 characters, content types other than plain text, or in general anything more advanced than plain text English-language email as it was in 1990, the code should look something like

from email.message import EmailMessage

msg = EmailMessage()
msg["from"] = fromaddr
msg["to"] = toaddr
msg["subject"] = "You have been nominated for the Nobel prize"
msg.set_content("http://scam.example.org/clickme")

which is admittedly slightly more verbose, but also infinitely more versatile, robust, and extensible.

This uses the EmailMessage API which was officially introduced in Python 3.6. New code should probably target this platform rather than the legacy email.Message module from earlier versions, although most online code examples you can find will be for the older Python library. See the Python email examples documentation for some quick examples.

Method 3

I don’t think it is about the colon but it’s about http:// starting the message.

mailto('<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6d19081e192d0a000c0401430e0200">[email protected]</a>', 'http://www.url.com')
mailto('<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fd89988e89bd9a909c9491d39e9290">[email protected]</a>', 'http://www.url.com that is a url')
mailto('<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92e6f7e1e6d2f5fff3fbfebcf1fdff">[email protected]</a>', ' http://www.url.com')

all fail, but:

mailto('<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b9cddccacdf9ded4d8d0d597dad6d4">[email protected]</a>', 'Here is a url http://www.url.com')

comes through fine.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x