Skip to content

Instantly share code, notes, and snippets.

@nickoala
Last active March 2, 2026 05:58
Show Gist options
  • Select an option

  • Save nickoala/569a9d191d088d82a5ef5c03c0690a02 to your computer and use it in GitHub Desktop.

Select an option

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

XtCode commented Jan 24, 2018

Copy link
Copy Markdown

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

Gab0 commented Apr 6, 2018

Copy link
Copy Markdown

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

@mborus

mborus commented Apr 22, 2018

Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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

@sujith1919

Copy link
Copy Markdown

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
Copy Markdown

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

rosscg commented Nov 20, 2018

Copy link
Copy Markdown

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
Copy Markdown

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

dsl400 commented Apr 23, 2019

Copy link
Copy Markdown

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
Copy Markdown

How can I do the same for Sendgrid

ghost commented Aug 21, 2019

Copy link
Copy Markdown

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

@Aths23

Aths23 commented Apr 2, 2020

Copy link
Copy Markdown

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

@pizzabreath

pizzabreath commented Jun 15, 2020

Copy link
Copy Markdown

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

MEXIHACKER commented Nov 10, 2021

Copy link
Copy Markdown

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

G-shaft commented Nov 12, 2021

Copy link
Copy Markdown

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

G-shaft commented Nov 12, 2021

Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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

@titanism

titanism commented Sep 3, 2024

Copy link
Copy Markdown

Instead of using Gmail, you can use or self-host https://forwardemail.net (coupon code GITHUB for 100% off).

It is completely open-source and privacy-focused (unlike Sendgrid, Postmark, Gmail, Proton Mail, Office 365, and others).

See their GitHub at @forwardemail

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