15

I have a very simple piece of code (just for testing):

import smtplib
import time

server = 'smtp.myprovider.com'
recipients = ['johndoe@somedomain.com']
sender = 'me@mydomain.com'
message = 'Subject: [PGS]: Results\n\nBlaBlaBla'

session = smtplib.SMTP(server)

session.sendmail(sender,recipients,message);

This works but the problem is that e-mail clients don't display a sender. I want to be able to add a sender name to the e-mail. Suggestions?

TimothyP
  • 21,178
  • 26
  • 94
  • 142

6 Answers6

21

smtplib doesn't automatically include a From: header, so you have to put one in yourself:

message = 'From: me@example.com\nSubject: [PGS]: Results\n\nBlaBlaBla'

(In fact, smtplib doesn't include any headers automatically, but just sends the text that you give it as a raw message)

dF.
  • 74,139
  • 30
  • 130
  • 136
  • Perhaps explaining that smtplib does not automatically include *any* header would be even more helpful. – tzot Feb 12 '09 at 13:59
19

See this answer, it's working for me.

example code:

#send html email
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formataddr

msg = MIMEMultipart('alternative')
msg['From'] = formataddr((str(Header('MyWebsite', 'utf-8')), 'from@mywebsite.com'))
msg['To'] = 'to@email.com'

html = "email contents"

# Record the MIME types of text/html.
msg.attach(MIMEText(html, 'html'))

# Send the message via local SMTP server.
s = smtplib.SMTP('localhost')

# sendmail function takes 3 arguments: sender's address, recipient's address
# and message to send - here it is sent as one string.
s.sendmail('from@mywebsite.com', 'to@email.com', msg.as_string())
s.quit()
sur.la.route
  • 440
  • 3
  • 11
Wei Lu
  • 1,069
  • 9
  • 6
19

You can utilize the email.message.Message class, and use it to generate mime headers, including from:, to: and subject. Send the as_string() result via SMTP.

>>> from email import message
>>> m1=message.Message()
>>> m1.add_header('from','me@no.where')
>>> m1.add_header('to','myself@some.where')
>>> m1.add_header('subject','test')
>>> m1.set_payload('test\n')
>>> m1.as_string()
'from: me@no.where\nto: myself@some.where\nsubject: test\n\ntest\n'
>>> 
gimel
  • 83,368
  • 10
  • 76
  • 104
  • The main reason to prefer this is that you really can't assemble a valid nontrivial email message, like a MIME multipart message, by pasting simple strings together. The libary knows how to handle a number of details which tend to confound beginners, like how to correctly encode non-ASCII data. – tripleee Mar 15 '21 at 20:16
  • Note that since Python 3.6, the preferred interface is the `EmailMessage` class, with a similar but more versatile and logical API. – tripleee Mar 15 '21 at 20:18
12

The "sender" you're specifying in this case is the envelope sender that is passed onto the SMTP server.

What your MUA (Mail User Agent - i.e. outlook/Thunderbird etc.) shows you is the "From:" header.

Normally, if I'm using smtplib, I'd compile the headers separately:

headers = "From: %s\nTo: %s\n\n" % (email_from, email_to)

The format of the From header is by convention normally "Name" <user@domain>

You should be including a "Message-Id" header and a "Reply-To" header as well in all communications. Especially since spam filters may pick up on the lack of these as a great probability that the mail is spam.

If you've got your mail body in the variable body, just compile the overall message with:

message = headers + body

Note the double newline at the end of the headers. It's also worth noting that SMTP servers should separate headers with newlines only (i.e. LF - linfeed). However, I have seen a Windows SMTP server or two that uses \r\n (i.e. CRLF). If you're on Windows, YMMV.

Philip Reynolds
  • 9,364
  • 3
  • 30
  • 37
  • I think there is a colon missing in the `headers` string after `"From`. – Dennis Oct 21 '13 at 12:12
  • The normal form is `From: Real Name
    ` without double quotes around the name. Some software always puts in quotes to be on the safe side (or, in the case of Outlook, probably out of incompetence) but they are only required if the name contains characters which have a special meaning in SMTP address headers, like `@` or `<`.
    – tripleee Mar 15 '21 at 20:12
4

I think you are trying to show some specific name instead of your emailID. You need to change only msg['From'] part in this code

fromName = "Name Which you want to show in reciever Inbox"
fromEmail = "abc@xyz.com"  # Sender's email Id
message['From'] = "{} <{}>".format(fromName,fromEmail)

After this usual in above described link.

Atul6.Singh
  • 221
  • 2
  • 5
0

When just using smtplib to add a from name instaead of displaying your email address just use:

message = """From: whatever-name\nSubject: subject\n\n
body of the message!
""".encode()

Passing this message through .sendmail(TO, FROM, message) will work.

0_o
  • 1
  • 3