17

I am trying to send email with below code.

import smtplib
from email.mime.text import MIMEText

sender = 'sender@sender.com'

def mail_me(cont, receiver):
    msg = MIMEText(cont, 'html')
    recipients = ",".join(receiver)
    msg['Subject'] = 'Test-email'
    msg['From'] = "XYZ ABC"
    msg['To'] = recipients
    # Send the message via our own SMTP server.
    try:
        s = smtplib.SMTP('localhost')
        s.sendmail(sender, receiver, msg.as_string())
        print "Successfully sent email"
    except SMTPException:
        print "Error: unable to send email"
    finally:
        s.quit()


cont = """\
   <html>
     <head></head>
     <body>
       <p>Hi!<br>
          How are you?<br>
          Here is the <a href="http://www.google.com">link</a> you wanted.
       </p>
     </body>
   </html>
   """
mail_me(cont,['xyz@xyzcom'])

I want "XYZ ABC" to appear as the sender's name when the email is received and its email address as 'sender@sender.com'. but when i receive email i am receiving weird details in "from" fields of the email message.

[![from:    XYZ@<machine-hostname-appearing-here>
reply-to:   XYZ@<machine-hostname-appearing-here>,
ABC@<machine-hostname-appearing-here>][1]][1]

I have attached a screenshot of the email that i receive.

how can i fix this according to my need.

cool77
  • 1,086
  • 4
  • 15
  • 31

7 Answers7

42

This should work:

msg['From'] = "Your name <Your email>"

Example below:

import smtplib
from email.mime.text import MIMEText


def send_email(to=['example@example.com'],
               f_host='example.example.com',
               f_port=587,
               f_user='example@example.com',
               f_passwd='example-pass',
               subject='default subject',
               message='content message'):
    smtpserver = smtplib.SMTP(f_host, f_port)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(f_user, f_passwd)  # from email credential
    msg = MIMEText(message, 'html')
    msg['Subject'] = 'My custom Subject'
    msg['From'] = "Your name <Your email>"
    msg['To'] = ','.join(to)
    for t in to:
        smtpserver.sendmail(f_user, t, msg.as_string())  # you just need to add 
                                                         # this in for loop in 
                                                         # your code.
    smtpserver.close()
    print('Mail is sent successfully!!')

    cont = """
    <html>
    <head></head>
    <body>
    <p>Hi!<br>
      How are you?<br>
      Here is the <a href="http://www.google.com">link</a> you wanted.
    </p>
    </body>
    </html>
    """
    try:
        send_email(message=cont)
    except:
        print('Mail could not be sent')
blondelg
  • 916
  • 1
  • 8
  • 25
Matheus Candido
  • 421
  • 4
  • 5
  • 1
    Welcome to Stack Overflow! In general, it is preferable to provide an answer with an explanation, and maybe a full example. – Arian Acosta Dec 14 '17 at 23:54
  • 6
    Works great! thanks. However, I noticed that some email clients (older outlooks for instance) would show the in the inbox as sender. I think that the proper way to do it would be to import `from email.header import Header` and `from email.utils import formataddr` and do: `msg['From'] = formataddr((str(Header('Your name', 'utf-8')), 'your@email.com')).` – noamyg May 12 '19 at 11:57
  • 1
    Just want to add new case. It never passes when I used text like this `"Company Name CO., LTD "`. But it'll work when I write `"(Company Name CO., LTD) "`. `python 3.7` –  Nov 29 '19 at 07:00
  • The for loop is unnecessary here. Based on the official documentation, the 2nd parameter of sendmail function is a list of RFC 822 to-address strings (a bare string will be treated as a list with 1 address). We can just use ```smtpserver.sendmail(f_user, to, msg.as_string())``` instead for code simplicity. – luke77 May 01 '20 at 07:42
  • Also, if you would like to follow the original code example, the indentation of ```smtpserver.close()``` line should be removed in order to be able to send to multiple email addresses. – luke77 May 01 '20 at 07:59
  • This code is sending emails but I have a problem, My google account name is TheGreatKings but this sends email as thegreatkings i.e. without camel case. Any solution ??? – xaif Aug 20 '20 at 08:46
  • @noamyg I've tried your strategy on the `msg['From']` field as per the above, the name appears great, but the email always shows up as the Gmail address. What should the `your@email.com` bit be doing? – fazistinho_ Nov 18 '20 at 17:11
  • @HiFizzle_ please see if this post helps you: https://stackoverflow.com/a/56101240/3367818. – noamyg Nov 19 '20 at 05:34
1

Just tested the following code with gmx.com and it works fine. Although, whether you get the same mileage is a moot point.
I have replaced all references to my email service with gmail

#!/usr/bin/python

#from smtplib import SMTP # Standard connection
from smtplib import SMTP_SSL as SMTP #SSL connection
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

sender = 'example@gmail.com'
receivers = ['example@gmail.com']


msg = MIMEMultipart()
msg['From'] = 'example@gmail.com'
msg['To'] = 'example@gmail.com'
msg['Subject'] = 'simple email via python test 1'
message = 'This is the body of the email line 1\nLine 2\nEnd'
msg.attach(MIMEText(message))

ServerConnect = False
try:
    smtp_server = SMTP('smtp.gmail.com','465')
    smtp_server.login('#name#@gmail.com', '#password#')
    ServerConnect = True
except SMTPHeloError as e:
    print "Server did not reply"
except SMTPAuthenticationError as e:
    print "Incorrect username/password combination"
except SMTPException as e:
    print "Authentication failed"

if ServerConnect == True:
    try:
        smtp_server.sendmail(sender, receivers, msg.as_string())
        print "Successfully sent email"
    except SMTPException as e:
        print "Error: unable to send email", e
    finally:
        smtp_server.close()
Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60
0

This should fix it:

Replace mail_me(cont,['xyz@xyzcom']) with

mail_me(cont,'xyz@xyz.com')
Sreetam Das
  • 3,226
  • 2
  • 22
  • 36
  • nope. that din't solve the issue. more over smtplib accepts recepient's email address as a list. so cannot replace it as a string – cool77 Jun 06 '17 at 09:08
0

The name comes from the FROM header. Refer to this answer please Specify a sender when sending mail with Python (smtplib)

kawadhiya21
  • 2,458
  • 21
  • 34
0

A space is not a valid character in an email address. Special characters are only allowed in the external representation that shall be enclosed in double quotes. Additionaly, most SMTP servers actually use header rewriting to ensure that addresses are in standard format. As yours actually contains a space it is splitted and as it is not enclosed in quotes, the server address is appended to it.

You have just to replace msg['From'] = "XYZ ABC" with

msg['From'] = '"XYZ ABC"'

forcing inclusion of the address in double quotes.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0
import smtplib
from email.mime.text import MIMEText

def send_email(to=['example@example.com'], f_host='example.example.com', f_port=587, f_user='example@example.com', f_passwd='example-pass', subject='default subject', message='content message'):
    smtpserver = smtplib.SMTP(f_host, f_port)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(f_user, f_passwd) # from email credential
    msg = MIMEText(message, 'html')
    msg['Subject'] = 'My custom Subject'
    msg['From'] = "Admin"
    msg['To'] = ','.join(to)
    for t in to:
        smtpserver.sendmail(f_user, t, msg.as_string())  # you just need to add this in for loop in your code.
        smtpserver.close()
    print('Mail is sent successfully!!')


cont = """\
   <html>
     <head></head>
     <body>
       <p>Hi!<br>
          How are you?<br>
          Here is the <a href="http://www.google.com">link</a> you wanted.
       </p>
     </body>
   </html>
   """
try:
    send_email(message=cont)
except:
    print('Mail could not be sent')

above method I have tried to send mail which is worked for me even I am able to send mail to my gmail account(in spam folder). Let me know if you face any other related problem.

Gahan
  • 4,075
  • 4
  • 24
  • 44
0

While the above methods are fine, a more explicit way is to make use of Address from email.headerregistry

The Address class takes 4 parameters: (quoted from docs)

display_name - The display name portion of the address, if any, with all quoting removed. If the address does not have a display name, this attribute will be an empty string.

username - The username portion of the address, with all quoting removed.

domain - The domain portion of the address.

addr_spec - The username@domain portion of the address, correctly quoted for use as a bare address (the second form shown above). This attribute is not mutable.

import smtplib
from email.message import EmailMessage
from email.headerregistry import Address

msg = EmailMessage()
msg.set_content('Hello Stackoverflow!')

msg['Subject'] = 'SO'
msg['From'] = Address(display_name="Name", addr_spec="info@mydomain.com")
msg['To'] = "receiver@domain.com"

# Send the message via our own SMTP server.
server = smtplib.SMTP_SSL('smpt.gmail.net', 465) # place your own host
server.login("info@mydomain.com", "mypassword")
server.send_message(msg)
server.quit()
Art
  • 2,836
  • 4
  • 17
  • 34