0

Everytime I send an email with this function, it doesn't add the subject and the message to the right fields, but instead of that, it adds it to the 'from:' or something. Here's the image of it. Any idea how this can be fixed? Thanks for answer

import smtplib

## NON-ANONYMOUS EMAIL
def email():
    # Parts of an email
    SERVER = 'smtp.gmail.com'
    PORT = 587
    USER = 'something@gmail.com'
    PASS = 'something'
    FROM = USER
    TO = ['something@riseup.net']
    #SUBJECT = 'Test'
    MESSAGE = 'Test message.'

    # Connects all parts of email together
    message = "From: %s\r\n To: %s\r\n %s" % (FROM, ", ".join(TO), MESSAGE)

    # Sends an email
    email = smtplib.SMTP()
    email.connect(SERVER,PORT)
    email.starttls()
    email.login(USER,PASS)
    email.sendmail(FROM, TO, message)
    email.quit()

email()
Kesi
  • 15
  • 1
  • 8
  • Can you show me an example of what data is being passed into the `TO` variable please? For example, show me what code is calling this `email` function. – Jonathon Ogden Jul 23 '16 at 13:26
  • Yes. I already added them. Thanks for answer – Kesi Jul 23 '16 at 13:32
  • Actually, it doesn't appear to be a problem with `.join` as I first thought. As a test, instead of defining the `message` across multiple lines, change it to the following: `"From: %s\r\n To: %s\r\n Subject: %s\r\n %s" % (FROM, ", ".join(TO), SUBJECT, MESSAGE)`. It's possible \n (newline) does not cause `sendmail` to recognise the different parts of the message. I noticed that `send_message` uses \r\n as the email part separators, whereas `.join(TO)` would generate \n if I am not mistaken. – Jonathon Ogden Jul 23 '16 at 13:46
  • `message = "From: %s\r\n To: %s\r\n Subject: %s\r\n %s" % (FROM, ", ".join(TO), SUBJECT, MESSAGE)` resulted in the same thing. – Kesi Jul 23 '16 at 13:53
  • Okay, can you call `print (message)` and show what the final formatted message looks like please? – Jonathon Ogden Jul 23 '16 at 13:58
  • `From: something@gmail.com To: something@riseup.net Subject: Test Test message.` here you go. – Kesi Jul 23 '16 at 14:03
  • Remove references to _subject_ for me (`"From: %s\r\n To: %s\r\n %s" % (FROM, ", ".join(TO), MESSAGE)` ) and attempt again, including printing and showing me the final formatted message please. – Jonathon Ogden Jul 23 '16 at 14:14
  • [Image](http://imgur.com/a/RWMNp) – Kesi Jul 23 '16 at 14:34
  • Attempt to send that and let me know the results.please. – Jonathon Ogden Jul 23 '16 at 14:35
  • I sent an image. Do you want something else? – Kesi Jul 23 '16 at 14:39
  • When I said _attempt to send that_, I mean send the email without the subject contents and let me know the results i.e. are the fields correct when you open it in an email client. – Jonathon Ogden Jul 23 '16 at 14:40
  • [Image2](http://imgur.com/a/tyVoh) – Kesi Jul 23 '16 at 15:02

3 Answers3

1

You cannot have a space after the \r\n. An email header line is continued by indenting it, so your code is creating a really long From: header with all the data you are trying to put in different fields.

Anyway, manually gluing together snippets of plain text is a really crude and error-prone way to construct an email message. You will soon find that you need the various features of the Python email module anyway (legacy email is 7-bit single part ASCII only; you'll probably want one or more of attachments, content encoding, character set support, multipart messages, or one of the many other MIME features). This also coincidentally offers much better documentation for how to correcty create a trivial email message.

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

Following on from @tripleee suggestion to use the email module, here's a basic example using your current code:

import smtplib
from email.mime.text import MIMEText

## NON-ANONYMOUS EMAIL
def email():
    # Parts of an email
    SERVER = 'smtp.gmail.com'
    PORT = 587
    USER = 'something@gmail.com'
    PASS = 'something'
    FROM = USER
    TO = ['something@riseup.net']
    SUBJECT = 'Test'

    # Create the email
    message = MIMEText('Test message.')
    message['From'] = FROM
    message['To'] = ",".join(TO)
    message['Subject'] = SUBJECT

    # Sends an email
    email = smtplib.SMTP()
    email.connect(SERVER,PORT)
    email.starttls()
    email.login(USER,PASS)
    email.sendmail(FROM, TO, message.as_string())
    email.quit()

Notice how much easier it is to define the parts of the email using keys like message['Subject'] instead of attempting to build a string or 'gluing parts together' as tripleee put it.

The different fields (From, To, Subject, et cetera) you can access are defined in RFC 2822 - Internet Message Format.

These documents are not easy to read, so here's a list of some of the fields' keys you can use: To, From, Cc, Bcc, Reply-To, Sender, Subject.

You cannot have a space after the \r\n. An email header line is continued by indenting it, so your code is creating a really long From: header with all the data you are trying to put in different fields.

As triplee and the RFC-2822 document says, if you are wanting to build the email string manually look at the field definitions in that document which look similar to this example:

from = "From:" mailbox-list CRLF

You can translate this into Python code when building an email string like so:

"From: something@riseup.net \r\n"

Community
  • 1
  • 1
Jonathon Ogden
  • 1,562
  • 13
  • 19
  • Just tried that, but it shows an error: `File "C:\python27\lib\email\quoprimime.py", line 97, in _max_append L.append(s.lstrip()) AttributeError: 'list' object has no attribute 'lstrip'` Any idea how to solve that? **EDIT:** Why is there that `as_string()`? – Kesi Jul 24 '16 at 21:31
  • `as_string()` converts the message into a string. This is because `MIMEText` is an _object structure_ and `sendmail` _`msg`_ parameter is a `string`; you need to convert it. In other words, it is equivalent to what you were doing previously by building the email structure yourself. Call `print (message.as_string())` to see. Regarding that error, are you still using `", ".join(TO)`? – Jonathon Ogden Jul 24 '16 at 21:44
  • (1) No, I deleted the whole previous code, so I am not using `", ".join(TO)`. (2) What is the difference between `message.as_string()` & `str(message)`? – Kesi Jul 24 '16 at 21:55
  • 1
    1. You'll still need the `",".join(TO)` to build your list of receiver email addresses; that doesn't change. Remember, this is the equivalent to what you were doing but removes the need for you to build the email string. 2. both are equivalent. For reference [as_string](https://docs.python.org/3/library/email.message.html#email.message.Message.as_string) – Jonathon Ogden Jul 24 '16 at 22:29
  • Correct. Updated my code earlier to include that for you. Apologies. – Jonathon Ogden Jul 24 '16 at 22:37
  • Oh, ok. And last thing: How do implement this: `",".join(TO)` to the code? Thanks for answer – Kesi Jul 24 '16 at 22:38
  • As I said. Updated code in my answer with that. It was the same as before. – Jonathon Ogden Jul 24 '16 at 22:39
  • Yes. I see that now. I was just writing my previous comment, when you posted yours. :D **EDIT:** It is working now. Thanks for helping me. – Kesi Jul 24 '16 at 22:42
0

I was able to get mine to work using: ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" % (gmail_user, recipient, subject, body))

nikis
  • 1