tldr; if you need to send mail from different mailboxes, use smtplib
. If you are automating stuff that you can do manually using outlook, use win32com.client
.
SMTP
Referencing the official python docs for SMTP, the methods described there simply allow you to send a mail. (yes, that's it. You cannot even look at the inbox. You'll need imaplib
or poplib
.)
To me the advantage of smtp is that you can send emails from another person's mailbox if you have his/her credentials. If you were to use win32com.client
, you will need to sign out of your own outlook, sign in to that specific person's outlook, then run the code. And for me, I faced the issue where I had to wait for his/her inbox to finish loading before anything gets sent. This is not feasible if you only need to send mail (and not interested in any other functionality such as read or delete mail) from many mailboxes.
[Update] I've recently used smtplib
and email
(a python builtin package) in a personal project. As it is a personal project, I didn't want to use my office email, hence I decided to use smtplib
instead. While there is a need to setup an initial connection, it is very straightforward. Since there is no way to save the email as a draft before sending, the logical workaround is to send it to your own email addresses (or any other 'safe' emails) to test if it works as intended.
import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg['From'] = 'YOUR_EMAIL@GMAIL.COM'
msg['Subject'] = 'Some subject here'
msg['To'] = ', '.join(['adam@gmail.com','bob@gmail.com','candice@gmail.com'])
msg.set_content('Some text here')
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login('YOUR_EMAIL@GMAIL.COM', 'PASSWORD123')
smtp.send_message(msg)
print('Email sent!')
win32com.client (focusing on the Outlook application)
You should use this library if you want to automate what you can do on outlook mailboxes that you have access to. Syntax tends to be simpler and it allows you to do stuff that is not possible using only smtplib
.
Here are 2 examples to illustrate my point.
Example 1: Automate sending of a calendar invite.
If you were to do it using SMTP, you'll require more code and another library email
, specifically .MIMEMultipart
, .MIMEBase
, .MIMEText
, .Utils
. The syntax looks intimidating, to say the least. Just take a look at the ical
variable of the following stackoverflow answer:
ical = "BEGIN:VCALENDAR"+CRLF+"PRODID:pyICSParser"+CRLF+"VERSION:2.0"+CRLF+"CALSCALE:GREGORIAN"+CRLF
ical+="METHOD:REQUEST"+CRLF+"BEGIN:VEVENT"+CRLF+"DTSTART:"+dtstart+CRLF+"DTEND:"+dtend+CRLF+"DTSTAMP:"+dtstamp+CRLF+organizer+CRLF
ical+= "UID:FIXMEUID"+dtstamp+CRLF
ical+= attendee+"CREATED:"+dtstamp+CRLF+description+"LAST-MODIFIED:"+dtstamp+CRLF+"LOCATION:"+CRLF+"SEQUENCE:0"+CRLF+"STATUS:CONFIRMED"+CRLF
ical+= "SUMMARY:test "+ddtstart.strftime("%Y%m%d @ %H:%M")+CRLF+"TRANSP:OPAQUE"+CRLF+"END:VEVENT"+CRLF+"END:VCALENDAR"+CRLF
win32com.client
is so much easier (phew~). There are code examples all over the internet (here and here), and here's a simple example:
ol = w32.Dispatch('Outlook.Application')
appt = ol.CreateItem(1)
appt.Start = '2021-02-06 15:00'
appt.Save()
Example 2: Saving an email as a draft
I often end up automating work for colleagues and when you are sending emails as a batch, it is highly recommended to test by saving the created mail items as a draft. win32com.client
allows you to save the mail item as a draft (i.e. .Save()
) but smtplib
doesn't allow you to do that (reiterate, it only allows you to send a mail.)
[Disclaimer] I done some automation work on outlook and I've always used win32com.client
and I have only recently started to use smtplib
for a personal project. This question intrigued me and I decided that it is time to at least read a bit more about smtplib
.