I am sending email with my raspberrypi with python.
I successfully sent and received the message, but the content is missing.
Here is my code
import smtplib
smtpUser = 'myemail#gmail.com'
smtpPass = 'mypassword'
toAdd = 'target#gmail.com'
fromAdd = smtpUser
subject = 'Python Test'
header = 'To: ' + toAdd + '\n' + 'From: ' + fromAdd + '\n' + 'Subject: ' + subject
body = 'From within a Python script'
msg = header + '\n' + body
print header + '\n' + body
s = smtplib.SMTP('smtp.gmail.com',587)
s.ehlo()
s.starttls()
s.ehlo()
s.login(smtpUser,smtpPass)
s.sendmail(fromAdd, toAdd, msg)
s.quit()
Thank you for your attention!
I wrote a wrapper around sending emails in python; it makes sending emails super easy: https://github.com/krystofl/krystof-utils/blob/master/python/krystof_email_wrapper.py
Use it like so:
emailer = Krystof_email_wrapper()
email_body = 'Hello, <br /><br />' \
'This is the body of the email.'
emailer.create_email('sender#example.com', 'Sender Name',
['recipient#example.com'],
email_body,
'Email subject!',
attachments = ['filename.txt'])
cred = { 'email': 'sender#example.com', 'password': 'VERYSECURE' }
emailer.send_email(login_dict = cred, force_send = True)
You can also look at the source code to find how it works.
The relevant bits:
import email
import smtplib # sending of the emails
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
self.msg = MIMEMultipart()
self.msg.preamble = "This is a multi-part message in MIME format."
# set the sender
author = email.utils.formataddr((from_name, from_email))
self.msg['From'] = author
# set recipients (from list of email address strings)
self.msg['To' ] = ', '.join(to_emails)
self.msg['Cc' ] = ', '.join(cc_emails)
self.msg['Bcc'] = ', '.join(bcc_emails)
# set the subject
self.msg['Subject'] = subject
# set the body
msg_text = MIMEText(body.encode('utf-8'), 'html', _charset='utf-8')
self.msg.attach(msg_text)
# send the email
session = smtplib.SMTP('smtp.gmail.com', 587)
session.ehlo()
session.starttls()
session.login(login_dict['email'], login_dict['password'])
session.send_message(self.msg)
session.quit()
Related
When Clicking accept in the email, and viewing it in the calendar it still says "has not accepted invite". Im not quite sure why the response to accept the email is not being updated in the calendar. Please help thanks! I am using outlook as the email service. Thanks again for the help much appreciated
#imports
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import formatdate
from email import encoders
import os,datetime
COMMASPACE = ', '
CRLF = "\r\n"
#Account that creats the Meeting
login = "admin#gmail.com"
password = "Password"
attendees = ["admin#gmail.com", "user1#gmail.com", "user2#gmail.com"]
organizer = "ORGANIZER;CN=Test:mailto:admin"+CRLF+"#gmail.com"
fro = "nickname <admin#gmail.com>"
ddtstart = datetime.datetime.now()
dtoff = datetime.timedelta(days = 1)
dur = datetime.timedelta(hours = 1)
ddtstart = ddtstart +dtoff
dtend = ddtstart + dur
dtstamp = datetime.datetime.now().strftime("%Y%m%dT%H%M%SZ")
dtstart = ddtstart.strftime("%Y%m%dT%H%M%SZ")
dtend = dtend.strftime("%Y%m%dT%H%M%SZ")
description = "DESCRIPTION: test invitation from pyICSParser"+CRLF
attendee = ""
for att in attendees:
attendee += "ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ- PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE"+CRLF+" ;CN="+att+";X-NUM-GUESTS=0:"+CRLF+" mailto:"+att+CRLF
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
eml_body = "Event on Calendar test"
eml_body_bin = "This is the email body in binary - two steps"
msg = MIMEMultipart('mixed')
msg['Reply-To']="admin#gmail.com"
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = "Testing Event"+dtstart
msg['From'] = fro
msg['To'] = ",".join(attendees)
part_email = MIMEText(eml_body,"html")
part_cal = MIMEText(ical,'calendar;method=REQUEST')
msgAlternative = MIMEMultipart('alternative')
msg.attach(msgAlternative)
ical_atch = MIMEBase('application/ics',' ;name="%s"'%("invite.ics"))
ical_atch.set_payload(ical)
encoders.encode_base64(ical_atch)
ical_atch.add_header('Content-Disposition', 'attachment; filename="%s"'%("invite.ics"))
eml_atch = MIMEText('', 'plain')
encoders.encode_base64(eml_atch)
eml_atch.add_header('Content-Transfer-Encoding', "")
msgAlternative.attach(part_email)
msgAlternative.attach(part_cal)
mailServer = smtplib.SMTP('smtp.outlook.com', 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(login, password)
mailServer.sendmail(fro, attendees, msg.as_string())
mailServer.close()
print("Email Sent")
I am trying to send pandas table in python mail.i tried but can't get the result.also convert pandas dataframe to html
here is my code.
please help
code
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import pandas as pd
def sendMail(ID,NAME,MARKS):
dict = {'ID': ID, 'NAME':NAME, 'MARKS': MARKS}
da = pd.DataFrame(dict)
df=da.to_html()
try:
email = "EMAIL#gmail.COM"
password = 'PASSWORD'
send_to_email =["EMAIL#gmail.COM",]
subject = 'Critical Incident'
messageHTML = '{df}'
messagePlain = 'marks of your class'
print(messageHTML)
msg = MIMEMultipart('alternative')
msg['From'] = email
msg['To'] = ', '.join(send_to_email)
msg['Subject'] = subject
msg.attach(MIMEText(messagePlain, 'plain'))
msg.attach(MIMEText(messageHTML, 'html'))
server = smtplib.SMTP("smtp.gmail.com",587)
server.starttls()
server.login(email, password)
text = msg.as_string()
server.sendmail(email, send_to_email, text)
server.quit()
I found the answer
df=da.to_html()
ds=str(df)
messageHTML = 'marks'+ds
I have a code which sends an email that uses HTML for templating.
All of the recipients get the message, but all of them are BCC.
def sendMail(to, cc, bcc, template, bodyParams, subjectParams):
global connection
if not testCurrentConnection(connection):
connect(currentConnectionName)
msg = MIMEMultipart('alternative')
subject, fromEmail, body = templateController.readTemplate(template)
header = 'To: ' + to + '\n' + 'Cc: ' + cc + 'From: ' + fromEmail + '\n' + 'Subject: ' + subject + '\n'
msg.attach(MIMEText(header, 'text'))
if subjectParams:
msg['Subject'] = templateController.replaceTextWithParams(subject, subjectParams)
else:
msg['Subject'] = subject
if bodyParams:
msg['Body'] = templateController.replaceTextWithParams(body, bodyParams)
else:
msg['Body'] = body
msg['From'] = fromEmail
msg['To'] = to
msg['Cc'] = cc
# no need to specify bcc here
msg.attach(MIMEText(msg['Body'], 'html'))
connection.sendmail(msg['From'], [msg['To'], msg['Cc'], bcc], msg.as_string())
del msg
I'm calling the function like this:
smtpController.sendMail("myMail#gmail.com", "ccMail#gmail.com", "", "email.html", None, None)
(The last two variables are actually a dict with key-value mapping used to populate the HTML, but the problem reproduces without them)
I read that I need to add header to my message to prevent it but for some reason, adding the header doesn't change anything (lines 7-8 in the above code).
What am I missing?
OK, I don't know how it makes a difference, but I fixed it by moving msg['To'] = to and msg['Cc'] = cc up, before Subject and Body. I completely removed the header.
def sendMail(to, cc, bcc, template, bodyParams, subjectParams):
global connection
if not testCurrentConnection(connection):
connect(currentConnectionName)
subject, fromEmail, body = templateController.readTemplate(template)
msg = MIMEMultipart('alternative')
msg['From'] = fromEmail
msg['To'] = to
msg['Cc'] = cc
if subjectParams:
msg['Subject'] = templateController.replaceTextWithParams(subject, subjectParams)
else:
msg['Subject'] = subject
if bodyParams:
msg['Body'] = templateController.replaceTextWithParams(body, bodyParams)
else:
msg['Body'] = body
msg.attach(MIMEText(msg['Body'], 'html'))
connection.sendmail(msg['From'], to.split(',') + cc.split(',') + bcc.split(','), msg.as_string())
del msg
This is the code I have running, which is supposedly working totally fine, but it is not actually sending the email to the address I specify. It does not have anything to do with the CSV because I have another script doing the same thing and working just fine. The problem is that the email is being placed in the senders inbox... which is weird.
I would rather use this script since it's nicely object oriented and it has all the proper subject fields, etc.
import smtplib
import pandas as pd
class Gmail(object):
def __init__(self, email, password, recepient):
self.email = email
self.password = password
self.recepient = recepient
self.server = 'smtp.gmail.com'
self.port = 465
session = smtplib.SMTP_SSL(self.server, self.port)
session.ehlo
session.login(self.email, self.password)
self.session = session
print('Connected to Gmail account successfully.')
def send_message(self, subject, body):
headers = [
"From: " + self.email,
"Subject: " + subject,
"To: " + self.recepient,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
self.session.sendmail(
self.email,
self.email,
headers + "\r\n\r\n" + body)
print('- Message has been sent.')
df = pd.read_csv('test.csv', error_bad_lines=False)
for index, row in df.iterrows():
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
comp_name = (row['name'])
print('Email to: ' + comp_name)
rec = (row['email'])
print('Email to: ' + rec)
gm = Gmail('email#gmail.com', 'password', rec)
gm.send_message('email to ' + comp_name, '<b>This is a test<b>')
print('-- Message for ' + rec + ' (' + comp_name + ') is completed.')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
print('*********************************')
print('Finish reading through CSV.')
print('*********************************')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
Let me know if there is something wrong. I would really like this to work.
Just so that you can see it is working, here is the other script I am testing it against (which is poorly formatted) and it is completely functioning properly.
import smtplib
import pandas as pd
df = pd.read_csv('test.csv', error_bad_lines=False)
gmail_user = 'email#gmail.com'
gmail_password = 'password'
for index, row in df.iterrows():
sent_from = gmail_user
to = (row['email'])
subject = 'Important Message'
body = 'Hey, whats up'
rec = (row['email'])
comp_name = (row['name'])
print('Email to: ' + comp_name)
print('Email to: ' + rec)
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, to, subject, body)
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_password)
server.sendmail(sent_from, to, email_text)
server.close()
print ('-- Email sent!')
except:
print ('-- Something went wrong...')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
print('*********************************')
print('Finish reading through CSV.')
print('*********************************')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
You should pass the recipient instead of the sender.
self.session.sendmail(
self.email,
# self.email, <- wrong here
self.recepient,
headers + "\r\n\r\n" + body)
I'm trying to email multiple recipients using the pyton script below. I've searched the forum for answers, but have not been able to implement any of them correctly. If anyone has a moment to review my script and spot/resolve the problem it would be greatly appreciated.
Here's my script, I gather my issue is in the 'sendmail' portion, but can't figure out how to fix it:
gmail_user = "sender#email.com"
gmail_pwd = "sender_password"
recipients = ['recipient1#email.com','recipient2#email.com']
def mail(to, subject, text, attach):
msg = MIMEMultipart()
msg['From'] = gmail_user
msg['To'] = ", ".join(recipients)
msg['Subject'] = subject
msg.attach(MIMEText(text))
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(attach, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition',
'attachment; filename="%s"' % os.path.basename(attach))
msg.attach(part)
mailServer = smtplib.SMTP("smtp.gmail.com", 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to, msg.as_string())
mailServer.close()
mail("recipient1#email.com, recipient2#email.com",
"Subject",
"Message",
"attchachment")
Any insight would be greatly appreciated.
Best,
Matt
It should be more like
mail(["recipient1#email.com", "recipient2#email.com"],
"Subject",
"Message",
"attchachment")
You already have a array of recipients declared,that too globally,You can use that without passing it as an argument to mail.
I wrote this bit of code to do exactly what you want. If you find a bug let me know (I've tested it and it works):
import email as em
import smtplib as smtp
import os
ENDPOINTS = {KEY: 'value#domain.com'}
class BoxWriter(object):
def __init__(self):
pass
def dispatch(self, files, box_target, additional_targets=None, email_subject=None, body='New figures'):
"""
Send an email to multiple recipients
:param files: list of files to send--requires full path
:param box_target: Relevant entry ENDPOINTS dict
:param additional_targets: other addresses to send the same email
:param email_subject: optional title for email
"""
destination = ENDPOINTS.get(box_target, None)
if destination is None:
raise Exception('Target folder on Box does not exist')
recipients = [destination]
if additional_targets is not None:
recipients.extend(additional_targets)
subject = 'Updating files'
if email_subject is not None:
subject = email_subject
message = em.MIMEMultipart.MIMEMultipart()
message['From'] = 'user#domain.com'
message['To'] = ', '.join(recipients)
message['Date'] = em.Utils.formatdate(localtime=True)
message['Subject'] = subject
message.attach(em.MIMEText.MIMEText(body + '\n' +'Contents: \n{0}'.format('\n'.join(files))))
for f in files:
base = em.MIMEBase.MIMEBase('application', "octet-stream")
base.set_payload(open(f, 'rb').read())
em.Encoders.encode_base64(base)
base.add_header('Content-Disposition', 'attachment; filename={0}'.format(os.path.basename(f)))
message.attach(base)
conn = smtp.SMTP('smtp.gmail.com', 587)
un = 'user#gmail.com'
pw = 'test1234'
conn.starttls()
conn.login(un, pw)
conn.sendmail('user#domain.com', recipients, message.as_string())
conn.close()
I was facing the same issue, I fixed this issue now. Here is my code -
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
import datetime
def sendMail():
message = MIMEMultipart()
message["To"] = "xxxxx#xxxx.com,yyyy#yyyy.com"
message["Cc"] = "zzzzzz#gmail.com,*********#gmail.com"
message["From"] = "xxxxxxxx#gmail.com"
message["Password"] = "***************"
server = 'smtp.gmail.com:587'
try:
now = datetime.datetime.now()
message['Subject'] = "cxxdRL Table status (Super Important Message) - "+str(now)
server = smtplib.SMTP(server)
server.ehlo()
server.starttls()
server.login(message["From"], message["Password"])
server.sendmail(message["From"], message["To"].split(",") + message["Cc"].split(","), message.as_string())
server.quit()
print('Mail sent')
except:
print('Something went wrong...')
sendMail()