I'm writing a Python program that generates an invitation. The code below works approximately.
It send the invitation, the invitation is recognized by an Outlook client, but is not treated by Mac OS calendar.
What is missing or what's wrong ?
Thanks
subject = "Mail subject"
sender_email = "someone#domain.com"
to = ["someone_else#domain.com"]
cc = []
# Create the plain-text and HTML version of your message
text = """\
Text message version
"""
html = """\
<!DOCTYPE html><html><head></head><body><p>The HTML message</p></body></html>
"""
# Create a multipart message and set headers
message = MIMEMultipart("mixed")
message["From"] = sender_email
message["To"] = ", ".join(to)
message["Cc"] = ", ".join(cc)
message["Subject"] = subject
message['Date'] = formatdate(localtime=True)
message_alternative = MIMEMultipart('alternative')
message_related = MIMEMultipart('related')
message_related.attach(MIMEText(html, 'html'))
message_alternative.attach(message_related)
#message_alternative.attach((text, 'plain'))
# --- Begin ical integration ---
ical = CreateIcs() # this function return an ICS content
ical_atch = MIMEBase("text", "calendar", method="REQUEST", name="invite.ics")
ical_atch.set_payload(ical)
encoders.encode_quopri(ical_atch)
message_alternative.attach(ical_atch)
# --- END ical integration ---
message.attach(message_alternative)
# convert message to string
text = message.as_string()
# Send mail
host='127.0.0.1'
port=25
context = None
with smtplib.SMTP(host=host, port=port) as server:
server.sendmail(sender_email, message["To"].split(",") + message["Cc"].split(","), text)
print(f"Mail sent TO : {message['To'].split(',')}, CC : {message['Cc'].split(',')}")
Related
When entering a message , the console outputs that the "ms" variable is empty , how can this be fixed ?
def send_mail(id_user, message_topic):
data = read_date_json()
ms = ''
login = data['MyDate'][0]['login']
password = data['MyDate'][0]['password']
mail = data['MyDate'][0]['login'].split('#')[1]
if ('yandex' in mail) or ('ya' in mail):
ms = 'yandex.ru'
elif 'gmail' in mail:
ms = 'gmail.com'
elif 'mail' in mail:
ms = 'mail.ru'
url = data['Mail'][0][ms]
number, topic, message = message_topic.split('$')
toaddr = data['MyFriend'][0]['mail'][int(number)]
msg = MIMEMultipart()
msg['Subject'] = topic
msg['From'] = login
body = message
msg.attach(MIMEText(body, 'plain'))
try:
server = root.SMTP_SSL(url, 465)
except:
print('no connect')
server.login(login, password)
server.sendmail(login, toaddr, msg.as_string())
server.quit()
bot.send_message(id_user, 'Ваше сообщение отправлено')
I tried to overwrite variables and tried to use other mail, but to no avail
I'm wondering which approach is better for sending mail with different body using Python:
send each mail using separate functions
using one function and select body message with if-else statement
First case:
FROM = *from_email_address*
def send_mail_notify():
SUBJECT = *some_subject_for_notification_event*
TEXT = *any_text*
msg = EmailMessage()
msg['From'] = FROM
msg['To'] = *to_email_address*
msg['Subject'] = SUBJECT
msg.set_content(TEXT)
...(initialize connection to mail server, etc.)
FROM = *from_email_address*
def send_mail_error():
SUBJECT = *some_subject_for_error_event*
TEXT = *any_text*
msg = EmailMessage()
msg['From'] = FROM
msg['To'] = *email_address*
msg['Subject'] = SUBJECT
msg.set_content(TEXT)
...(initialize connection to mail server, etc.)
Second case:
FROM = *from_email_address*
def send_mail(param):
if param == "notify":
SUBJECT = *some_subject_for_notification_event*
TEXT = *any_text*
elif param == "error":
SUBJECT = *some_subject_for_error_event*
TEXT = *any_text*
msg = EmailMessage()
msg['From'] = FROM
msg['To'] = *email_address*
msg['Subject'] = SUBJECT
msg.set_content(TEXT)
...(initialize connection to mail server, etc.)
You can create an unlimited functions for different types of subject and text and you don't need to check the condition with if-else statement:
FROM = *from_email_address*
def notify():
return {"SUBJECT":"notification", "TEXT": "new message"}
def error():
return {"SUBJECT":"error: message dont send", "TEXT": "error message text"}
def send_mail(param):
msg = EmailMessage()
msg['From'] = FROM
msg['To'] = *email_address *
msg['Subject'] = globals().get(param)()["SUBJECT"]
msg.set_content(globals().get(param)()["TEXT"])
The param value must be the same as the name of the function.
I have to sendmail at the end of my code with csv attached containing a dataframe.
Im doing it at AWS Lambda using boto3 to call SES as it follows.
def sendMail1(value, df):
subject = "Comission"
client = boto3.client("ses")
body = f"""
Comission value is {value}.
"""
message = {"Subject": {"Data": subject}, "Body": {"Html": {"Data": body}}}
attachment = df.to_csv(f"Comission.csv", index=False)
response = client.send_email(Source = "myemail#gmail.com", Destination = {"ToAddresses": ["youremail#gmail.com"]}, Message = message, Attachment = attachment)
I had no ideia how to do it, I tried df.to_csv method and include it as attachment. Did not work.
The rest of the code works without the attachment parts, but I need to attach my df to the e-mail.
Do you guys have any idea how to do it?
df.to_csv(f"Comission.csv", index=False)
to_emails = [target_email1, target_email2]
ses = boto3.client('ses')
msg = MIMEMultipart()
msg['Subject'] = 'weekly report'
msg['From'] = from_email
msg['To'] = to_emails[0]
# what a recipient sees if they don't use an email reader
msg.preamble = 'Multipart message.\n'
# the message body
part = MIMEText('Howdy -- here is the data from last week.')
msg.attach(part)
# the attachment
part = MIMEApplication(open('Comission.csv', 'rb').read())
part.add_header('Content-Disposition', 'attachment', filename='Comission.csv')
msg.attach(part)
result = ses.send_raw_email(
Source=msg['From'],
Destinations=to_emails,
RawMessage={'Data': msg.as_string()})
# and send the message
print result
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()
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()