I'm trying to send emails to people in a distribution list in my company using python. My company uses outlook.
When I send to individual users specifying their email, it works perfectly. However I need to use the distribution list, since the recipients are updated by my IT department and I cant keep updating the email list whenever it changes.
Whomever has used outlook, you might recall that the distribution list starts with an exclamation mark like so: !groupdept#company.com
I am using the following method to send emails using python:
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from smtplib import SMTP
import smtplib
import sys
subject = "Group Email"
fromm = 'me#company.com'
recipients = ['someone#company.com, someonelse#company.com']
emaillist = [elem.strip().split(',') for elem in recipients]
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = fromm
html = """\
<html>
<head>
</head>
<body style="font-size:18px;">
{0}
</body>
</html>
""".format(df2.style
.set_properties(**{'border': '2.5pt solid green', 'color': 'magenta', 'font-size': '15pt'})
.hide_index()
.hide_columns()
.render()
)
message = MIMEText(html, 'html')
msg.attach(message)
server = smtplib.SMTP('00.0.0.00', 25)
server.sendmail(msg['From'], emaillist , msg.as_string())
The above method works well for comma separated recipients. However if I use !groupdept#company.com it doesn't work, which I can understand since that is an MS Outlook functionality.
Has anyone achieved this before?
I am trying to send an email in Python and the reference is a Perl script. So I have the following code:
my $msg = MIME::Lite->new(
From =>'myEmail#Domain',
To =>'someone#Domain',
Subject =>"Test",
Type =>'multipart/related'
);
$msg->attach(Type => 'text/html',
Data => qq{
<body>
<h1> any text here </h1>
</body> }
);
$msg->send();
}
Then I wanted to do the same thing in Python, so I got to use the SMTPLib and chose the Outlook's SMTP server. So I got the following Python code:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
email = 'myEmail#Domain'
password = 'myPassword'
send_to = 'myEmail#Domain'
subject = 'test'
message = '''<body>
<h1>any text here</h1>
</body>
'''
msg = MIMEMultipart()
msg['From'] = email
msg['To'] = send_to
msg['Subject'] = subject
msg.attach(MIMEText(message, 'html'))
server = smtplib.SMTP('smtp-mail.outlook.com', 587)
server.starttls()
server.login(email, password)
text = msg.as_string()
server.send_message(msg)
But the point is that I couldn't find a MIME::Lite like module for Python that didn't need to login in the sender's email.
Is there a module where I could just send an email without authentication or am I forgetting something?
I am trying to send emails from the Cpanel email but everything I try I face the same error
[Errno 11001] getaddrinfo failed
this is my code, I tried it with Google domain and it works fine but the Cpanel is not working ? is there a way around it to use python for sending emails ?
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from email.mime.image import MIMEImage
email_user = 'something#Mydomain.com'
email_password = 'password'
email_send = "someemail#gmail.com"
subject = "Testing 2"
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
h = str("Holder")
c = str("course")
t = str("trainer")
html = """\
<html>
<head></head>
<body>
<p >Hello {h} This {t} we need your conf. on {c} </p>
</body>
</html>
""".format(h=h , c=c , t=t)
msg.attach(MIMEText(html,'html'))
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,email_password)
server.sendmail(email_user,email_send,msg.as_string())
server.quit()
So what do you think?
yes you have to change server = smtplib.SMTP('yourDomain.com',25)
I am using pd.to_html for sending my pandas dataframe over email, the emails are opening fine in Gmail browser with all the tables in the email body. But they are not opening in Outlook all the tables are going as an HTML attachment in outlook.
Using the following code for converting my dataframe to HTML.
df_1 = df_1.to_html(index=False,header= True,border=4,justify = 'left',col_space =9)
from IPython.core.display import display, HTML
display(HTML(df_1))
This is how I am sending the Email:-
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
email_user = 'xyz#x.com'
email_password = '*********'
email_send = 'xyz#x.com'
subject = 'ABCDEF'
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
body_1 = """ Hey All,
Please find the data:
"""
msg.attach(MIMEText(body_1,'plain'))
msg.attach(MIMEText(df_1,'html'))
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,email_password)
server.sendmail(email_user,email_send.split(','),text)
server.quit()
There are no error's email is opening in Gmail properly. But in outlook tables are coming as an attachment.
You can make a single attachment as html.That worked for me.
df_1 = df_1.to_html(index=False,header= True,border=4,justify = 'left',col_space =9)
mailBody= """<p> Hi All, <br><br>
Please find the data: </p> <br><br>
""" + df_1 + """<br> Thanks. """
msg.attach(MIMEText(mailBody,'html'))
How to send HTML content in email using Python? I can send simple texts.
From Python v2.7.14 documentation - 18.1.11. email: Examples:
Here’s an example of how to create an HTML message with an alternative plain text version:
#! /usr/bin/python
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# me == my email address
# you == recipient's email address
me = "my#email.com"
you = "your#email.com"
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
msg['From'] = me
msg['To'] = you
# Create the body of the message (a plain-text and an HTML version).
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org"
html = """\
<html>
<head></head>
<body>
<p>Hi!<br>
How are you?<br>
Here is the link you wanted.
</p>
</body>
</html>
"""
# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
# Send the message via local SMTP server.
s = smtplib.SMTP('localhost')
# sendmail function takes 3 arguments: sender's address, recipient's address
# and message to send - here it is sent as one string.
s.sendmail(me, you, msg.as_string())
s.quit()
Here is a Gmail implementation of the accepted answer:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# me == my email address
# you == recipient's email address
me = "my#email.com"
you = "your#email.com"
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
msg['From'] = me
msg['To'] = you
# Create the body of the message (a plain-text and an HTML version).
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org"
html = """\
<html>
<head></head>
<body>
<p>Hi!<br>
How are you?<br>
Here is the link you wanted.
</p>
</body>
</html>
"""
# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
# Send the message via local SMTP server.
mail = smtplib.SMTP('smtp.gmail.com', 587)
mail.ehlo()
mail.starttls()
mail.login('userName', 'password')
mail.sendmail(me, you, msg.as_string())
mail.quit()
You might try using my mailer module.
from mailer import Mailer
from mailer import Message
message = Message(From="me#example.com",
To="you#example.com")
message.Subject = "An HTML Email"
message.Html = """<p>Hi!<br>
How are you?<br>
Here is the link you wanted.</p>"""
sender = Mailer('smtp.example.com')
sender.send(message)
Here is a simple way to send an HTML email, just by specifying the Content-Type header as 'text/html':
import email.message
import smtplib
msg = email.message.Message()
msg['Subject'] = 'foo'
msg['From'] = 'sender#test.com'
msg['To'] = 'recipient#test.com'
msg.add_header('Content-Type','text/html')
msg.set_payload('Body of <b>message</b>')
# Send the message via local SMTP server.
s = smtplib.SMTP('localhost')
s.starttls()
s.login(email_login,
email_passwd)
s.sendmail(msg['From'], [msg['To']], msg.as_string())
s.quit()
for python3, improve #taltman 's answer:
use email.message.EmailMessage instead of email.message.Message to construct email.
use email.set_content func, assign subtype='html' argument. instead of low level func set_payload and add header manually.
use SMTP.send_message func instead of SMTP.sendmail func to send email.
use with block to auto close connection.
from email.message import EmailMessage
from smtplib import SMTP
# construct email
email = EmailMessage()
email['Subject'] = 'foo'
email['From'] = 'sender#test.com'
email['To'] = 'recipient#test.com'
email.set_content('<font color="red">red color text</font>', subtype='html')
# Send the message via local SMTP server.
with smtplib.SMTP('localhost') as s:
s.login('foo_user', 'bar_password')
s.send_message(email)
Here's sample code. This is inspired from code found on the Python Cookbook site (can't find the exact link)
def createhtmlmail (html, text, subject, fromEmail):
"""Create a mime-message that will render HTML in popular
MUAs, text in better ones"""
import MimeWriter
import mimetools
import cStringIO
out = cStringIO.StringIO() # output buffer for our message
htmlin = cStringIO.StringIO(html)
txtin = cStringIO.StringIO(text)
writer = MimeWriter.MimeWriter(out)
#
# set up some basic headers... we put subject here
# because smtplib.sendmail expects it to be in the
# message body
#
writer.addheader("From", fromEmail)
writer.addheader("Subject", subject)
writer.addheader("MIME-Version", "1.0")
#
# start the multipart section of the message
# multipart/alternative seems to work better
# on some MUAs than multipart/mixed
#
writer.startmultipartbody("alternative")
writer.flushheaders()
#
# the plain text section
#
subpart = writer.nextpart()
subpart.addheader("Content-Transfer-Encoding", "quoted-printable")
pout = subpart.startbody("text/plain", [("charset", 'us-ascii')])
mimetools.encode(txtin, pout, 'quoted-printable')
txtin.close()
#
# start the html subpart of the message
#
subpart = writer.nextpart()
subpart.addheader("Content-Transfer-Encoding", "quoted-printable")
#
# returns us a file-ish object we can write to
#
pout = subpart.startbody("text/html", [("charset", 'us-ascii')])
mimetools.encode(htmlin, pout, 'quoted-printable')
htmlin.close()
#
# Now that we're done, close our writer and
# return the message body
#
writer.lastpart()
msg = out.getvalue()
out.close()
print msg
return msg
if __name__=="__main__":
import smtplib
html = 'html version'
text = 'TEST VERSION'
subject = "BACKUP REPORT"
message = createhtmlmail(html, text, subject, 'From Host <sender#host.com>')
server = smtplib.SMTP("smtp_server_address","smtp_port")
server.login('username', 'password')
server.sendmail('sender#host.com', 'target#otherhost.com', message)
server.quit()
Actually, yagmail took a bit different approach.
It will by default send HTML, with automatic fallback for incapable email-readers. It is not the 17th century anymore.
Of course, it can be overridden, but here goes:
import yagmail
yag = yagmail.SMTP("me#example.com", "mypassword")
html_msg = """<p>Hi!<br>
How are you?<br>
Here is the link you wanted.</p>"""
yag.send("to#example.com", "the subject", html_msg)
For installation instructions and many more great features, have a look at the github.
Here's a working example to send plain text and HTML emails from Python using smtplib along with the CC and BCC options.
https://varunver.wordpress.com/2017/01/26/python-smtplib-send-plaintext-and-html-emails/
#!/usr/bin/env python
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def send_mail(params, type_):
email_subject = params['email_subject']
email_from = "from_email#domain.com"
email_to = params['email_to']
email_cc = params.get('email_cc')
email_bcc = params.get('email_bcc')
email_body = params['email_body']
msg = MIMEMultipart('alternative')
msg['To'] = email_to
msg['CC'] = email_cc
msg['Subject'] = email_subject
mt_html = MIMEText(email_body, type_)
msg.attach(mt_html)
server = smtplib.SMTP('YOUR_MAIL_SERVER.DOMAIN.COM')
server.set_debuglevel(1)
toaddrs = [email_to] + [email_cc] + [email_bcc]
server.sendmail(email_from, toaddrs, msg.as_string())
server.quit()
# Calling the mailer functions
params = {
'email_to': 'to_email#domain.com',
'email_cc': 'cc_email#domain.com',
'email_bcc': 'bcc_email#domain.com',
'email_subject': 'Test message from python library',
'email_body': '<h1>Hello World</h1>'
}
for t in ['plain', 'html']:
send_mail(params, t)
Here is my answer for AWS using boto3
subject = "Hello"
html = "<b>Hello Consumer</b>"
client = boto3.client('ses', region_name='us-east-1', aws_access_key_id="your_key",
aws_secret_access_key="your_secret")
client.send_email(
Source='ACME <do-not-reply#acme.com>',
Destination={'ToAddresses': [email]},
Message={
'Subject': {'Data': subject},
'Body': {
'Html': {'Data': html}
}
}
Simplest solution for sending email from Organizational account in Office 365:
from O365 import Message
html_template = """
<html>
<head>
<title></title>
</head>
<body>
{}
</body>
</html>
"""
final_html_data = html_template.format(df.to_html(index=False))
o365_auth = ('sender_username#company_email.com','Password')
m = Message(auth=o365_auth)
m.setRecipients('receiver_username#company_email.com')
m.setSubject('Weekly report')
m.setBodyHTML(final_html_data)
m.sendMessage()
here df is a dataframe converted to html Table, which is being injected to html_template
I may be late in providing an answer here, but the Question asked a way to send HTML emails. Using a dedicated module like "email" is okay, but we can achieve the same results without using any new module. It all boils down to the Gmail Protocol.
Below is my simple sample code for sending HTML mail only by using "smtplib" and nothing else.
```
import smtplib
FROM = "....#gmail.com"
TO = "another....#gmail.com"
SUBJECT= "Subject"
PWD = "thesecretkey"
TEXT="""
<h1>Hello</h1>
""" #Your Message (Even Supports HTML Directly)
message = f"Subject: {SUBJECT}\nFrom: {FROM}\nTo: {TO}\nContent-Type: text/html\n\n{TEXT}" #This is where the stuff happens
try:
server=smtplib.SMTP("smtp.gmail.com",587)
server.ehlo()
server.starttls()
server.login(FROM,PWD)
server.sendmail(FROM,TO,message)
server.close()
print("Successfully sent the mail.")
except Exception as e:
print("Failed to send the mail..", e)
```
In case you want something simpler:
from redmail import EmailSender
email = EmailSender(host="smtp.myhost.com", port=1)
email.send(
subject="Example email",
sender="me#example.com",
receivers=["you#example.com"],
html="<h1>Hi, this is HTML body</h1>"
)
Pip install Red Mail from PyPI:
pip install redmail
Red Mail has most likely all you need from sending emails and it has a lot of features including:
Attachments
Templating (with Jinja)
Embedded images
Prettified tables
Send as cc or bcc
Gmail preconfigured
Documentation: https://red-mail.readthedocs.io/en/latest/index.html
Source code: https://github.com/Miksus/red-mail