Skip to content

Instantly share code, notes, and snippets.

@nickoala
Last active April 29, 2024 05:54
Show Gist options
  • Save nickoala/569a9d191d088d82a5ef5c03c0690a02 to your computer and use it in GitHub Desktop.
Save nickoala/569a9d191d088d82a5ef5c03c0690a02 to your computer and use it in GitHub Desktop.
Use Python to send and receive emails

Use Python to:

  • send a plain text email
  • send an email with attachment
  • receive and filter emails according to some criteria
import smtplib
from email.mime.text import MIMEText
smtp_ssl_host = 'smtp.gmail.com' # smtp.mail.yahoo.com
smtp_ssl_port = 465
username = 'USERNAME or EMAIL ADDRESS'
password = 'PASSWORD'
sender = 'ME@EXAMPLE.COM'
targets = ['HE@EXAMPLE.COM', 'SHE@EXAMPLE.COM']
msg = MIMEText('Hi, how are you today?')
msg['Subject'] = 'Hello'
msg['From'] = sender
msg['To'] = ', '.join(targets)
server = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
server.login(username, password)
server.sendmail(sender, targets, msg.as_string())
server.quit()
import os
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
smtp_ssl_host = 'smtp.gmail.com' # smtp.mail.yahoo.com
smtp_ssl_port = 465
username = 'USERNAME or EMAIL ADDRESS'
password = 'PASSWORD'
sender = 'ME@EXAMPLE.COM'
targets = ['HE@EXAMPLE.COM', 'SHE@EXAMPLE.COM']
msg = MIMEMultipart()
msg['Subject'] = 'I have a picture'
msg['From'] = sender
msg['To'] = ', '.join(targets)
txt = MIMEText('I just bought a new camera.')
msg.attach(txt)
filepath = '/path/to/image/file'
with open(filepath, 'rb') as f:
img = MIMEImage(f.read())
img.add_header('Content-Disposition',
'attachment',
filename=os.path.basename(filepath))
msg.attach(img)
server = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
server.login(username, password)
server.sendmail(sender, targets, msg.as_string())
server.quit()
import time
from itertools import chain
import email
import imaplib
imap_ssl_host = 'imap.gmail.com' # imap.mail.yahoo.com
imap_ssl_port = 993
username = 'USERNAME or EMAIL ADDRESS'
password = 'PASSWORD'
# Restrict mail search. Be very specific.
# Machine should be very selective to receive messages.
criteria = {
'FROM': 'PRIVILEGED EMAIL ADDRESS',
'SUBJECT': 'SPECIAL SUBJECT LINE',
'BODY': 'SECRET SIGNATURE',
}
uid_max = 0
def search_string(uid_max, criteria):
c = list(map(lambda t: (t[0], '"'+str(t[1])+'"'), criteria.items())) + [('UID', '%d:*' % (uid_max+1))]
return '(%s)' % ' '.join(chain(*c))
# Produce search string in IMAP format:
# e.g. (FROM "me@gmail.com" SUBJECT "abcde" BODY "123456789" UID 9999:*)
def get_first_text_block(msg):
type = msg.get_content_maintype()
if type == 'multipart':
for part in msg.get_payload():
if part.get_content_maintype() == 'text':
return part.get_payload()
elif type == 'text':
return msg.get_payload()
server = imaplib.IMAP4_SSL(imap_ssl_host, imap_ssl_port)
server.login(username, password)
server.select('INBOX')
result, data = server.uid('search', None, search_string(uid_max, criteria))
uids = [int(s) for s in data[0].split()]
if uids:
uid_max = max(uids)
# Initialize `uid_max`. Any UID less than or equal to `uid_max` will be ignored subsequently.
server.logout()
# Keep checking messages ...
# I don't like using IDLE because Yahoo does not support it.
while 1:
# Have to login/logout each time because that's the only way to get fresh results.
server = imaplib.IMAP4_SSL(imap_ssl_host, imap_ssl_port)
server.login(username, password)
server.select('INBOX')
result, data = server.uid('search', None, search_string(uid_max, criteria))
uids = [int(s) for s in data[0].split()]
for uid in uids:
# Have to check again because Gmail sometimes does not obey UID criterion.
if uid > uid_max:
result, data = server.uid('fetch', uid, '(RFC822)') # fetch entire message
msg = email.message_from_string(data[0][1])
uid_max = uid
text = get_first_text_block(msg)
print 'New message :::::::::::::::::::::'
print text
server.logout()
time.sleep(1)
@XtCode
Copy link

XtCode commented Jan 24, 2018

I am trying to make my own script on sending mail and i use yours as one of my examples. Your script and mine manages to send the text message, yet the massage takes ages to arrive to inbox. Sometimes it doesn't even reach it. Why is that ?

@Gab0
Copy link

Gab0 commented Apr 6, 2018

I've got the same issue as @XtCode, using similar code! Anyone knows what is happening?

@mborus
Copy link

mborus commented Apr 22, 2018

Note that this is Python2 compatible code that does not run on Python 3.

In Python3 you need to decode the bytes with the email content first, which
can cause some nasty crashes.

@masquerader
Copy link

Please can you provide a way to extract the email header from the inbox mail in python 3 !!!
Working on a project stuck here

@Programmer1242
Copy link

Yeah, Can I get The Code For The Third Project, but works in python 3 latest version ? That would be AWESOME !!

@sujith1919
Copy link

Not working for me when i am using it for icloud.com

smtp_ssl_host = 'smtp.mail.me.com'

Sujith-Jayaraj:~$ python sendmail1.py
Traceback (most recent call last):
File "sendmail1.py", line 20, in
server = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 796, in init
SMTP.init(self, host, port, local_hostname, timeout)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 256, in init
(code, msg) = self.connect(host, port)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 316, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 801, in _get_socket
new_socket = socket.create_connection((host, port), timeout)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 575, in create_connection
raise err
socket.error: [Errno 60] Operation timed out

please suggest

@mrptguitar
Copy link

Hi sujith1919, Apple requires a specific email password for every non-apple email client so, for example, if you have a third-party app on your mac to receive emails then you need to get a specific password from apple for it. Your python program would be the same. This could be the problem. You'll have to do a bit of a web search to find out how to get a 'specific email' password for icloud. Hope this helps you. Cheers PT

@rosscg
Copy link

rosscg commented Nov 20, 2018

Yeah, Can I get The Code For The Third Project, but works in python 3 latest version ? That would be AWESOME !!

Just fix the prints to have brackets, and decode the data:

msg = email.message_from_string(data[0][1].decode("utf-8"))

@SATYANARAYAN-MISHRA
Copy link

not working in my machine i used python3

File "send.py", line 16, in
server = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
File "/usr/lib/python3.5/smtplib.py", line 1021, in init
source_address)
File "/usr/lib/python3.5/smtplib.py", line 251, in init
(code, msg) = self.connect(host, port)
File "/usr/lib/python3.5/smtplib.py", line 335, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python3.5/smtplib.py", line 1027, in _get_socket
self.source_address)
File "/usr/lib/python3.5/socket.py", line 693, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "/usr/lib/python3.5/socket.py", line 732, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Temporary failure in name resolution

@dsl400
Copy link

dsl400 commented Apr 23, 2019

great work,
using this examples I got most of the job done!
can you help us with an example on how to append the mail I`m replying to the reply ?
another thing hard to find would be moving smtp sent mail to sent folder
thanks again !

@chemalle
Copy link

How can I do the same for Sendgrid

Copy link

ghost commented Aug 21, 2019

hi.
adapted to python3 and find undelivered email messages - https://github.com/ibessolitsyn/python_mail_checker/
Hope this will help someone :)

@Aths23
Copy link

Aths23 commented Apr 2, 2020

Hi ,
I am unable to execute the code . I am Getting an Credentials Error . Please Can Anyone Suggest Me The Solutions for this??

@pizzabreath
Copy link

pizzabreath commented Jun 15, 2020

Thank you very much for the examples! I've used sendtext successfully, but now I'm getting (mail.com):

smtplib.SMTPRecipientsRefused: {'<MAIL-ADDRESS>': (550, b'Requested action not taken: mailbox unavailable\nFailure sending mail. Try again later')}

Did anyone else experience this issue?

edit: nevermind, mail.com has a limit of smtp sends per hour and blocked my requests.

@MEXIHACKER
Copy link

MEXIHACKER commented Nov 10, 2021

Estoy tratando de hacer mi propio script sobre el envío de correo y uso el tuyo como uno de mis ejemplos. Su guión y el mío logran enviar el mensaje de texto, sin embargo, el masaje tarda años en llegar a la bandeja de entrada. A veces ni siquiera lo alcanza. ¿Por qué?

Creo que debes poner esto: time.sleep(0)

Espero haberte ayudado

@G-shaft
Copy link

G-shaft commented Nov 12, 2021

It doesn't work when I use it for icloud.com. I get indexes of emails with no content.

result, data = mail.fetch(latest_email_id, "(RFC822)")
data [b'1372 ()']

@G-shaft
Copy link

G-shaft commented Nov 12, 2021

It doesn't work when I use it for icloud.com. I get indexes of emails with no content.

result, data = mail.fetch(latest_email_id, "(RFC822)")
data [b'1372 ()']


result, data = server.uid('search', None, search_string(uid_max, criteria))
print(result, data)

OK [None]

@larsinka
Copy link

I have the same problem with iCloud.com.

When I fetch the email I get the data[0][1] which contains only an integer and can't be decoded by the .message_from_string method.

@SureshbabuAkash1999
Copy link

How do we send an reply email using smtp email. Could you please add a small snippet code example of the same?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment