Receive and Send Emails in Python

Receive and send emails in python

Here is a very simple example:

import smtplib

server = 'mail.server.com'
user = ''
password = ''

recipients = ['user@mail.com', 'other@mail.com']
sender = 'you@mail.com'
message = 'Hello World'

session = smtplib.SMTP(server)
# if your SMTP server doesn't need authentications,
# you don't need the following line:
session.login(user, password)
session.sendmail(sender, recipients, message)

For more options, error handling, etc, look at the smtplib module documentation.

How to send an email with Python?

I recommend that you use the standard packages email and smtplib together to send email. Please look at the following example (reproduced from the Python documentation). Notice that if you follow this approach, the "simple" task is indeed simple, and the more complex tasks (like attaching binary objects or sending plain/HTML multipart messages) are accomplished very rapidly.

# Import smtplib for the actual sending function
import smtplib

# Import the email modules we'll need
from email.mime.text import MIMEText

# Open a plain text file for reading. For this example, assume that
# the text file contains only ASCII characters.
with open(textfile, 'rb') as fp:
# Create a text/plain message
msg = MIMEText(fp.read())

# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you

# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()

For sending email to multiple destinations, you can also follow the example in the Python documentation:

# Import smtplib for the actual sending function
import smtplib

# Here are the email package modules we'll need
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

# Create the container (outer) email message.
msg = MIMEMultipart()
msg['Subject'] = 'Our family reunion'
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = me
msg['To'] = ', '.join(family)
msg.preamble = 'Our family reunion'

# Assume we know that the image files are all in PNG format
for file in pngfiles:
# Open the files in binary mode. Let the MIMEImage class automatically
# guess the specific image type.
with open(file, 'rb') as fp:
img = MIMEImage(fp.read())
msg.attach(img)

# Send the email via our own SMTP server.
s = smtplib.SMTP('localhost')
s.sendmail(me, family, msg.as_string())
s.quit()

As you can see, the header To in the MIMEText object must be a string consisting of email addresses separated by commas. On the other hand, the second argument to the sendmail function must be a list of strings (each string is an email address).

So, if you have three email addresses: person1@example.com, person2@example.com, and person3@example.com, you can do as follows (obvious sections omitted):

to = ["person1@example.com", "person2@example.com", "person3@example.com"]
msg['To'] = ",".join(to)
s.sendmail(me, to, msg.as_string())

the ",".join(to) part makes a single string out of the list, separated by commas.

From your questions I gather that you have not gone through the Python tutorial - it is a MUST if you want to get anywhere in Python - the documentation is mostly excellent for the standard library.

Sending Email to outlook using gmail server in python

You need to use the proper MIME type to specify the type of content. Replace plain with text/plain for the body and image with image/png for the image. That way outlook (or any mail client for that matter) will know how to present the body and how to preview the attachment.

How to listen for incoming emails in python 3?

Have you check below script (3_emailcheck.py) from here posted by git user nickoala? Its a python 2 script and in Python3 you need to decode the bytes with the email content first.

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)

How to trigger a python script on receiving email on outlook with a specific subject?

Which version of Outlook are you using? Office 365 Outlook have built in "Trigger" & "Event" function

I don't use Outlook so I don't know how it would call your script, but you could attach to "When new email arrive" trigger.

What is the proper way to ACTUALLY SEND mail from (Python) code?

Thanks to these answers, to my additional questions: 1, 2, 3, as well as these two questions (and answers) of other people: one, two — I think I am now ready to answer the questions I have posted, on my own.


I will address the questions one by one:

  1. Yes, as a general picture, sending of an email can be portrayed like this:
    My improved understanding

  2. MX lookup returns address(es) of server(s) which receive email destined to the specified domain.

    • As to "Why smtp-relay.gmail.com, smtp.gmail.com, aspmx.l.google.com are not returned by host -t mx gmail.com command?". This point is, pretty much, covered in another answer to this question. The main points to grasp here are:

      • servers returned by MX lookup are responsible for receiving of emails for the domain (gmail, in this particular case)
      • servers listed in gmail docs are meant for the mail sending (i.e. mails that gmail user wants to send, to other gmail user or otherwise, are submitted to those servers)
  3. Authentication is not needed, for servers receiving emails (i.e. the ones returned by MX lookup).

    • There are a couple things that prevent such servers from being abused:

      • many ISPs block outbound connections to port 25 (which is default port for mail receiving servers), to prevent such "direct" mail sending
      • there are numerous measures taken on the side of receiving servers, which are, mainly, intended to prevent spamming, but as a result will, likely, prevent such "direct" mail sending, as well (some examples are: DNSBL — list of blocked IPs, DKIM — is an email authentication method designed to detect forged sender addresses in emails (if you do not have your own, legitimate, mail server, you will use someone other's domain for From field, that is where you might be hit by DKIM)
  4. Code snippet is OK. The error is produced, in all probability, due to the blocking on the ISP's side.


With all that being said, code snippet:

import smtplib

from email.message import EmailMessage

message = EmailMessage()
message.set_content('Message content here')
message['Subject'] = 'Your subject here'
message['From'] = 'me@example.com'
message['To'] = 'user@example.com'

smtp_server = smtplib.SMTP('smtp.server.address:25')
smtp_server.send_message(message)
smtp_server.quit()

will actually send an email (see this question, for real-world, working example) given that smtp.server.address:25 is legitimate server and there are no blockings on ISP's and/or smtp.server.address side.

Send Outlook Email Via Python?

For a solution that uses outlook see TheoretiCAL's answer.

Otherwise, use the smtplib that comes with python. Note that this will require your email account allows smtp, which is not necessarily enabled by default.

SERVER = "smtp.example.com"
FROM = "yourEmail@example.com"
TO = ["listOfEmails"] # must be a list

SUBJECT = "Subject"
TEXT = "Your Text"

# Prepare actual message
message = """From: %s\r\nTo: %s\r\nSubject: %s\r\n\

%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)

# Send the mail
import smtplib
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()

EDIT: this example uses reserved domains like described in RFC2606

SERVER = "smtp.example.com"
FROM = "johnDoe@example.com"
TO = ["JaneDoe@example.com"] # must be a list

SUBJECT = "Hello!"
TEXT = "This is a test of emailing through smtp of example.com."

# Prepare actual message
message = """From: %s\r\nTo: %s\r\nSubject: %s\r\n\

%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)

# Send the mail
import smtplib
server = smtplib.SMTP(SERVER)
server.login("MrDoe", "PASSWORD")
server.sendmail(FROM, TO, message)
server.quit()

For it to actually work with gmail, Mr. Doe will need to go to the options tab in gmail and set it to allow smtp connections.

Note the addition of the login line to authenticate to the remote server. The original version does not include this, an oversight on my part.



Related Topics



Leave a reply



Submit