Mailing colored HTML using smtplib in python - python

I have a HTML file which is essentially a table. However some of the cells in the table are highlighted and when I convert my HTML file to text as specified in other stackoverflow answers, the coloring of the cells and other CSS specifications disappear in the mail.
Code :
import smtplib
import csv
from tabulate import tabulate
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
text = open("final.html", 'r').read()
message = MIMEMultipart(
"alternative", None, [MIMEText(text), MIMEText(text,'html')])
server = smtplib.SMTP('smtp.gmail.com', 25)
server.connect("smtp.gmail.com",25)
server.ehlo()
server.starttls()
server.ehlo()
server.login('mail', "password")
server.sendmail('from_mail', 'to_mail', message.as_string())
server.quit()
Finally, the message is converted to string as in message.as_string(). I guess when the message is converted to a string, the CSS formatting options are taken away.
HTML input file :
final.html file
Current output in mail:
Any help would be appreciated. Thanks a lot !

Firstly, most email clients don't support External CSS within the mail. This can be converted to Inline CSS with premailer.
import smtplib
import ssl
import premailer
from email.message import EmailMessage
SERVER_ADDRESS = "smtp.gmail.com"
SERVER_PORT = 587
EMAIL_ADDRESS = 'your email'
EMAIL_PASSWORD = 'your email password'
RECIPIENT_EMAIL = 'recipient's mail'
text = open("final.html", 'r').read()
text = premailer.transform(text)
msg = EmailMessage()
msg['Subject'] = "the subject"
msg['From'] = EMAIL_ADDRESS
msg['To'] = RECIPIENT_EMAIL
msg.set_content('content')
msg.add_alternative(text, subtype='html')
# Create a SSLContext object with default settings.
context = ssl.create_default_context()
with smtplib.SMTP(SERVER_ADDRESS, SERVER_PORT) as smtp:
smtp.ehlo()
smtp.starttls(context=context)
smtp.ehlo()
smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
smtp.send_message(msg)
This github repo was helpful.

Related

How to send email in Python without authentication

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?

How can I send random pdf files in email from a folder using Python?

I am trying to create an email bot that will send me a random pdf file from a folder. Though my code is not showing any error, I am not getting any mail. It'd be helpful if you can show me where I am going wrong and what should I do. Thank you.
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import os
import random
def send():
body = ""
sender_email = "email"
password = "my_password"
receiver_email = "email"
msg = MIMEMultipart()
msg['Subject'] = '[Email Test]'
msg['From'] = sender_email
msg['To'] = receiver_email
msg.attach(MIMEText(body, 'plain'))
path = "C:/Users/Asus/PycharmProjects/messenger_bot/files"
files = os.listdir(path)
index = random.randrange(0, len(files))
print(files[index])
attachment = open(os.path.join(path, random.choice(files)), 'rb')
payload = MIMEBase('application', 'octate-stream')
# payload = MIMEBase('application', 'pdf', Name=pdfname)
payload.set_payload(attachment.read())
# enconding the binary into base64
encoders.encode_base64(payload)
# add header with pdf name
payload.add_header('Content-Decomposition', 'attachment', filename=files)
msg.attach(payload)
# use gmail with port
session = smtplib.SMTP('smtp.gmail.com', 587)
# enable security
session.starttls()
# login with mail_id and password
session.login(sender_email, password)
text = msg.as_string()
session.sendmail(sender_email, receiver_email, text)
session.quit()
print('Mail Sent')
Are you sure that the sender email is correct?
change the sender_email from "email" to your actual email and it should work
From what I gather from official documentation. The issue you are having is because starttls takes a keyfile and a certfile together or a context by itself and you haven't given either.
try adding this:
context = ssl.create_default_context()
and then change your starttls() call to
starttls(context=context)

Python email "from name" customization

I have a python script to send email and it works just fine but the problem is when I check my email inbox.
I want that username to be customize username and not the whole email address.
The format you should use for the from address is:
Your Name <username#domain.com>
If you are using multipart message, and render markdown, if you want beautiful messages.
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
multipart_msg = MIMEMultipart("alternative")
multipart_msg["Subject"] = message.splitlines()[0]
multipart_msg["From"] = DISPLAY_NAME + f' <{SENDER_EMAIL}>'
multipart_msg["To"] = receiver
text = message
html = markdown.markdown(text)
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
multipart_msg.attach(part1)
multipart_msg.attach(part2)
server.sendmail(SENDER_EMAIL, receiver,
multipart_msg.as_string())
I got this code at https://en.wikibooks.org/wiki/Python_Programming/Email
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
fromaddr = "youremailid#gmail.com"
toaddr = "target#example.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = ""
body = "This is just a test email. Do not reply to this"
msg.attach(MIMEText(body, 'plain'))
import smtplib
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.ehlo()
server.login("youremailusername", "password")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
Format for from address is
username#server.com
Format for to address is
username#server.com
and smtplib.SMTP accepts 0 or 2 parameters.
The first parameter is type str and the second parameter is type int

Sending email with Python having correct sending time

I'm sending email through an account with the following Python code:
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
def sendMail(target, subject, txt):
fromaddr = 'my#test.com'
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = target
msg['Subject'] = subject
msg.attach(MIMEText("This is my text"))
server = smtplib.SMTP('node01.mailserver.com', '587')
server.ehlo()
server.starttls()
server.ehlo()
server.login(fromaddr, 'mypassword')
server.sendmail(fromaddr, target, msg.as_string())
server.quit()
This works quite well and I can receive the emails.
However, the timestamp which is displayed in my email client shows the time I downloaded the mail from the server and not time the email was actually send.
Is there a way how to correctly add the sending time to the email? I would assume that the sending time is not correctly set and that's the reason why the download time is displayed?
Or do I make other mistakes?
Thanks!
This works for me:
...
import email.utils
...
msg['Date'] = email.utils.formatdate(localtime=True)
...

How to send email with pdf attachment in Python? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to send Email Attachments with python
I would like to edit the following code and send an email with an attachment. Attachment is a pdf file, it is under /home/myuser/sample.pdf, in linux environment. What should I change below?
import smtplib
fromaddr = 'myemail#gmail.com'
toaddrs = 'youremail#gmail.com'
msg = 'Hello'
# Credentials (if needed)
username = 'myemail'
password = 'yyyyyy'
# The actual mail send
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
You create a message with an email package in this case -
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
msg = MIMEMultipart()
msg.attach(MIMEText(open("/home/myuser/sample.pdf").read()))
and then send the message.
import smtplib
mailer = smtplib.SMTP()
mailer.connect()
mailer.sendmail(from_, to, msg.as_string())
mailer.close()
Several examples here - http://docs.python.org/library/email-examples.html
UPDATE
Updating the link since the above yields a 404 https://docs.python.org/2/library/email-examples.html. Thanks #Tshirtman
Update2: Simplest way to attach pdf
To attach the pdf use the pdf flag:
def send_email_pdf_figs(path_to_pdf, subject, message, destination, password_path=None):
## credits: http://linuxcursor.com/python-programming/06-how-to-send-pdf-ppt-attachment-with-html-body-in-python-script
from socket import gethostname
#import email
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
import json
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
with open(password_path) as f:
config = json.load(f)
server.login('me#gmail.com', config['password'])
# Craft message (obj)
msg = MIMEMultipart()
message = f'{message}\nSend from Hostname: {gethostname()}'
msg['Subject'] = subject
msg['From'] = 'me#gmail.com'
msg['To'] = destination
# Insert the text to the msg going by e-mail
msg.attach(MIMEText(message, "plain"))
# Attach the pdf to the msg going by e-mail
with open(path_to_pdf, "rb") as f:
#attach = email.mime.application.MIMEApplication(f.read(),_subtype="pdf")
attach = MIMEApplication(f.read(),_subtype="pdf")
attach.add_header('Content-Disposition','attachment',filename=str(path_to_pdf))
msg.attach(attach)
# send msg
server.send_message(msg)
inspirations/credits to: http://linuxcursor.com/python-programming/06-how-to-send-pdf-ppt-attachment-with-html-body-in-python-script
The recommended way is using Python's email module in order to compose a properly
formatted MIME messages. See docs
For python 2
https://docs.python.org/2/library/email-examples.html
For python 3
https://docs.python.org/3/library/email.examples.html

Categories

Resources