smtplib and gmail - python script problems

52,653

Solution 1

I think that the GMail SMTP server does a reverse DNS lookup on the IP address that you connect from, and refuses the connection if no domain can be found. This is to avoid spammer from using their SMTP server as an open relay.

Solution 2

Some self-promotion here, but I feel on a valid ground.

You would literally only need this code to do exactly what you wrote:

import yagmail
yag = yagmail.SMTP('[email protected]')
yag.send('[email protected]', subject = None, contents = 'Hello')

Or a one liner:

yagmail.SMTP('[email protected]').send('[email protected]', None, 'Hello world.')

What is nice is that I propose to use keyring to store your password, so you never have a risk of people seeing your password in your script.

You can set this up by running once in your interpreter:

import yagmail
yagmail.register("[email protected]", "mypassword")

and exit. Then you can just use:

import yagmail
yagmail.SMTP("[email protected]") # without password

If you add .yagmail with "[email protected]" in your home dir, then you can just do: yagmail.SMTP(), but that's rather pointless by now.

Warning: If you get serious about sending a lot of messages, better set up OAuth2, yagmail can help with that.

yagmail.SMTP("[email protected]", oauth2_file="/path/to/save/creds.json")

The first time ran, it will guide you through the process of getting OAuth2 credentials and store them in the file so that next time you don't need to do anything with it. Do you suspect someone found your credentials? They'll have limited permissions, but you better invalidate their credentials through gmail.

For the package/installation please look at git or readthedocs, available for both Python 2 and 3.

Solution 3

Have you tried constructing a valid message?

from email.MIMEText import MIMEText

msg = MIMEText('body')
msg['Subject'] = 'subject'
msg['From'] = "..."
msg['Reply-to'] = "..."
msg['To'] = "..."

Solution 4

I don't know if OP still cares about this answer, but having found myself here in an effort to troubleshoot a similar problem, hopefully someone else might find this useful. As it turns out, Google has changed the way that they allow their SMTP server to be used. You will want to check a couple of things:

  1. That you are using the same address you used to authenticate as the 'from' address. If I am not mistaken it used to be the case that you could put pretty much whatever you wanted in the from field, but for security purposes many SMTP host sites (including google) now restrict this to the address that has authenticated with them.

  2. Allow your account to be accessed by 'less secure apps' (read: apps we do not generate revenue from). To do that log into your account and navigate here: https://www.google.com/settings/security/lesssecureapps

  3. Use port 587 with tls. Not really sure why but I could never get port 465 to play nice.

Hope this helps somebody else out.

Solution 5

save yourselves some headaches and use this:

http://mynthon.net/howto/-/python/python%20-%20logging.SMTPHandler-how-to-use-gmail-smtp-server.txt

Python SMTPHandler with GMail

Ss

Share:
52,653

Related videos on Youtube

spencewah
Author by

spencewah

Technical Director for Dreamworks Animation

Updated on February 07, 2021

Comments

  • spencewah
    spencewah about 3 years

    Here's my script:

    #!/usr/bin/python
    
    import smtplib
    msg = 'Hello world.'
    
    server = smtplib.SMTP('smtp.gmail.com',587) #port 465 or 587
    server.ehlo()
    server.starttls()
    server.ehlo()
    server.login('[email protected]','mypass')
    server.sendmail('[email protected]','[email protected]',msg)
    server.close()
    

    I'm just trying to send an email from my gmail account. The script uses starttls because of gmail's requirement. I've tried this on two web hosts, 1and1 and webfaction. 1and1 gives me a 'connection refused' error and webfaction reports no error but just doesn't send the email. I can't see anything wrong with the script, so I'm thinking it might be related to the web hosts. Any thoughts and comments would be much appreciated.

    EDIT: I turned on debug mode. From the output, it looks like it sent the message successfully...I just never receive it.

    send: 'ehlo web65.webfaction.com\r\n'
    reply: '250-mx.google.com at your service, [174.133.21.84]\r\n'
    reply: '250-SIZE 35651584\r\n'
    reply: '250-8BITMIME\r\n'
    reply: '250-STARTTLS\r\n'
    reply: '250-ENHANCEDSTATUSCODES\r\n'
    reply: '250 PIPELINING\r\n'
    reply: retcode (250); Msg: mx.google.com at your service, [174.133.21.84]
    SIZE 35651584
    8BITMIME
    STARTTLS
    ENHANCEDSTATUSCODES
    PIPELINING
    send: 'STARTTLS\r\n'
    reply: '220 2.0.0 Ready to start TLS\r\n'
    reply: retcode (220); Msg: 2.0.0 Ready to start TLS
    send: 'ehlo web65.webfaction.com\r\n'
    reply: '250-mx.google.com at your service, [174.133.21.84]\r\n'
    reply: '250-SIZE 35651584\r\n'
    reply: '250-8BITMIME\r\n'
    reply: '250-AUTH LOGIN PLAIN\r\n'
    reply: '250-ENHANCEDSTATUSCODES\r\n'
    reply: '250 PIPELINING\r\n'
    reply: retcode (250); Msg: mx.google.com at your service, [174.133.21.84]
    SIZE 35651584
    8BITMIME
    AUTH LOGIN PLAIN
    ENHANCEDSTATUSCODES
    PIPELINING
    send: 'AUTH PLAIN *****\r\n'
    reply: '235 2.7.0 Accepted\r\n'
    reply: retcode (235); Msg: 2.7.0 Accepted
    send: 'mail FROM:<[email protected]> size=12\r\n'
    reply: '250 2.1.0 OK 4sm652580yxq.48\r\n'
    reply: retcode (250); Msg: 2.1.0 OK 4sm652580yxq.48
    send: 'rcpt TO:<[email protected]>\r\n'
    reply: '250 2.1.5 OK 4sm652580yxq.48\r\n'
    reply: retcode (250); Msg: 2.1.5 OK 4sm652580yxq.48
    send: 'data\r\n'
    reply: '354  Go ahead 4sm652580yxq.48\r\n'
    reply: retcode (354); Msg: Go ahead 4sm652580yxq.48
    data: (354, 'Go ahead 4sm652580yxq.48')
    send: 'Hello world.\r\n.\r\n'
    reply: '250 2.0.0 OK 1240421143 4sm652580yxq.48\r\n'
    reply: retcode (250); Msg: 2.0.0 OK 1240421143 4sm652580yxq.48
    data: (250, '2.0.0 OK 1240421143 4sm652580yxq.48')
    
    • rohanlatimer
      rohanlatimer about 15 years
      You can send the mail via your normal SMTP relay, instead of calling gmail directly.
    • trusktr
      trusktr about 11 years
      How do you turn on debug mode to get those output messages?
    • hd1
      hd1 almost 10 years
      smtplib.set_debuglevel(True) will sort you, @trusktr
    • Charlie Parker
      Charlie Parker about 6 years
      I don't understand, how does the accepted answer solve your problem? What piece of code do I copy paste so that I can send an e-mail?
  • hwiechers
    hwiechers about 13 years
    I think it's the ISP. I tried the code and it worked fine for me.
  • Piotr Findeisen
    Piotr Findeisen over 12 years
    If GMail did reverse DNS lookup and refused connections, then how could i use my desktop email client, like thunderbird, to send mails via gmail's smtp?
  • PascalVKooten
    PascalVKooten about 9 years
    Thanks for the upvote, I'm really trying to get more attention to the package!
  • Amit Tripathi
    Amit Tripathi over 8 years
    SMTPAuthenticationError: Please log in via your web browser and\n5.7.14 then try again.\n5.7.14 Learn more at\n5.7.14 https://support.google.com/mail/answer/78754 vl1sm48001045pbc.31 - gsmtp')
  • PascalVKooten
    PascalVKooten over 8 years
    @Death-Stalker Seems like you made a mistake with writing your password?
  • Amit Tripathi
    Amit Tripathi over 8 years
    no. I tested it like 4-5 times and I am sure my password is right.
  • O. Edholm
    O. Edholm almost 7 years
    Answer, where have you been?!
  • Charlie Parker
    Charlie Parker about 6 years
    I'm confused, where are there a clear set of instructions for how to send an e-mail within python?
  • Charlie Parker
    Charlie Parker about 6 years
    not that I am against your library or anything but why is it so difficult to send an e-mail in python?
  • Charlie Parker
    Charlie Parker about 6 years
    can you explain in more details how to actually make it work? especially the part "What is nice is that I propose to use keyring to store your password, so you never have a risk of people seeing your password in your script."
  • PascalVKooten
    PascalVKooten about 6 years
    @CharlieParker it's optional though. You can also just have it in your script if you are too lazy to read the documentation. Or you can set up OAuth2. It's all in the docs: yagmail.readthedocs.io
  • PascalVKooten
    PascalVKooten about 6 years
    I guess this was one of my earlier posts on stackoverflow. I'll add specifically the keyring part in the answer.
  • krayzk
    krayzk almost 6 years
    @CharlieParker the instructions can be found in the original question, my answer was to point out possible reasons that what OP was doing wasn't working.
  • sh37211
    sh37211 over 2 years
    @PascalVKooten Looks neat. Unfortunately running yagmail.register line produces NameError: name 'keyring' is not defined. I see your post is 6 years old so probably something changed.
  • PascalVKooten
    PascalVKooten over 2 years
    @sh37211 I would recommend to set up an application specific password in gmail and just use that