When sending large count email response this error 554, Transaction failed: Duplicate header subject. I'm use smtplib + aws SES. For all messages, the header must be the same. How can I fix this error? If send message without subject, all working.
import smtplib
import json
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
args = []
msg = MIMEMultipart('alternative')
msg['From'] = 'noreply#example.com'
html = open('mail.html').read()
EMAIL_HOST = 'email-smtp...'
EMAIL_HOST_USER = 'sss'
EMAIL_HOST_PASSWORD = 'ssssss'
EMAIL_PORT = 587
def lambda_handler(event, context):
body = event['Records'][0]['Sns']['Message']
global args
args = json.loads(body)['args']
set_worker(json.loads(body)['method'])()
return 'success'
def set_worker(method):
return {
'email' : email
}.get(method, 'Not found')
def email():
global msg, html
name = args[0]
title = args[1]
msg_body = args[2]
email = args[3]
url = args[4]
subject = "Test"
msg['Subject'] = subject
msg['To'] = email
html = html.format(title, community_name, title, msg_body, community_name)
mime_text = MIMEText(html, 'html')
msg.attach(mime_text)
send_message()
def send_message():
mail = smtplib.SMTP(EMAIL_HOST, EMAIL_PORT)
mail.ehlo()
mail.starttls()
mail.login(EMAIL_HOST_USER, EMAIL_HOST_PASSWORD)
mail.sendmail(msg['From'], msg['To'], msg.as_string())
When working with aws-lambda cannot be used global variables . The error was in the fact that duplicate messages were written to the variable msg.
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")
import smtplib
import mechanize
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
def sem():
if not os.path.isfile('key.txt'):
print('below details are req to send report')
gmail_user = input('enter your email=')
gmail_app_password = input('enter your email password=')
print('pls accept the login in your gmail account ')
ke = open('key.txt',mode="w+")
ke.write(gmail_user)
ke.write(':')
ke.write(gmail_app_password)
ke.close()
if not os.path.isfile('sto.txt'):
gmai = input('enter the email to send report=')
ke = open('sto.txt',mode="w+")
ke.write(gmai)
ke.close()
with open('key.txt',mode="r")as f:
ds=f.readlines()
d=''.join(ds)
r=d.split(':')
with open('sto.txt',mode="r")as f:
ds=f.readlines()
f=ds
print(f)
gmail_user = r[0]
gmail_app_password = r[1]
sent_from = gmail_user
sent_to = ds
sent_subject = "hey amo lio ,how are ?"
sent_body = ("Hey, what's up? friend!")
email_text = """\
To: %s
Subject: %s
%s
""" % (", ".join(sent_to), sent_subject, sent_body)
mail = MIMEMultipart()
mail["Subject"] = sent_subject
mail["From"] = sent_from
mail["To"] = sent_to
mail.attach[MIMEText(sent_body,'html')]
ctype, encoding = mimetypes.guess_type(_file)
maintype, subtype = ctype.split('/', 1)
fp = open("./data/mood.txt")
msg = MIMEText(fp.read(), _subtype=subtype)
fp.close()
filename = os.path.basename(_file)
msg.add_header('Content-Disposition', 'attachment', filename=filename)
mail.attach(msg)
print('done')
server.sendmail(sent_from, sent_to, mail.as_string())
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_app_password)
server.sendmail(sent_from, sent_to, email_text)
server.close()
print('Email sent!')
except Exception as exception:
print("Error: %s!\n\n" % exception)
sem()
How can I attach the helloword.txt file in this email? This code is working fine, I just want to send an attachment along with it. This code lets me me send the body without any attachment. Also, how do I encrypt the key.txt file which store email address and password, and to send email it it requires the password to be entered (diff pass)?
You need to use the 'MIMEMultipart' module to attach files.
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
mail = MIMEMultipart()
mail["Subject"] = sent_subject
mail["From"] = sent_from
mail["To"] = sent_to
mail.attach(MIMEText(sent_body,'html'))
ctype, encoding = mimetypes.guess_type(_file)
maintype, subtype = ctype.split('/', 1)
fp = open("/path/to/attachment/file.txt")
# If file mimetype is video/audio use respective email.mime module.
# Here assuming 'maintype' == 'text' we will use MIMEText
msg = MIMEText(fp.read(), _subtype=subtype)
fp.close()
filename = os.path.basename(_file)
msg.add_header('Content-Disposition', 'attachment', filename=filename)
mail.attach(msg)
server.sendmail(sent_from, sent_to, mail.as_string())
import smtplib
import mechanize
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import mimetypes
import pdb
def email:
sender_address = gmail_user
#make it input
receiver_address = gmail_user
#Setup the MIME
fromaddr = gmail_user
sendto = gmail_app_password
sender_pass = gmail_app_password = input('enter your email password')
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = sendto
msg['Subject'] = 'This is cool'
body = "this is the body of the text message"
msg.attach(MIMEText(body, 'plain'))
filename = 'mood.txt'
attachment = open('./data/mood.txt', 'rb')
part = MIMEBase('application', "octet-stream")
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename= %s' % filename)
msg.attach(part)
smtpObj = smtplib.SMTP('smtp.gmail.com', 587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login(gmail_user, gmail_app_password)
text = msg.as_string()
smtpObj.sendmail(fromaddr, sendto , text)
smtpObj.quit() # attach the instance 'p' to instance 'msg'
here is perfect working code for sending email
I have a basic python code that sends out an email to addresses from a list in Google sheet.
I want to count the number of times an email is sent to a particular email address by the python script. I tried researching on it. I didn't find anything related to it. And being a complete beginner hasn't helped me make much progress.
If anyone can point me to a particular direction that would be super helpful. Thanks so much in advance.
Below is the code
import smtplib
import ssl
from email.mime.text import MIMEText # New line
from email.utils import formataddr # New line
# User configuration
sender_email = 'email ID'
sender_name = 'name'
password = "password"
receiver_emails = [RECEIVER_EMAIL_1, RECEIVER_EMAIL_2, RECEIVER_EMAIL_3]
receiver_names = [RECEIVER_NAME_1, RECEIVER_NAME_2, RECEIVER_NAME_3]
# Email text
email_body = '''
This is a test email sent by Python. Isn't that cool?
'''
for receiver_email, receiver_name in zip(receiver_emails, receiver_names):
print("Sending the email...")
# Configurating user's info
msg = MIMEText(email_body, 'plain')
msg['To'] = formataddr((receiver_name, receiver_email))
msg['From'] = formataddr((sender_name, sender_email))
msg['Subject'] = 'Hello, my friend ' + receiver_name
try:
# Creating a SMTP session | use 587 with TLS, 465 SSL and 25
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
# Encrypts the email
context = ssl.create_default_context()
server.starttls(context=context)
# We log in into our Google account
server.login(sender_email, password)
# Sending email from sender, to receiver with the email body
server.sendmail(sender_email, receiver_email, msg.as_string())
print('Email sent!')
except Exception as e:
print(f'Oh no! Something bad happened!n {e}')
finally:
print('Closing the server...')
server.quit()
I would suggest you to create a list of successful emails, which will be populated on each iteration and then, use Counter from collections module, which receives an iterable and returns an object with number of occurrences of each element in the iterable.
You can try the following code:
from collections import Counter
import json
counter_file_path = "counter.json"
try:
with open(counter_file_path, "r") as f:
email_stats = json.load(f)
except FileNotFoundError as ex:
email_stats = {}
successful_emails = []
for receiver_email, receiver_name in zip(receiver_emails, receiver_names):
print("Sending the email...")
# Configurating user's info
msg = MIMEText(email_body, 'plain')
msg['To'] = formataddr((receiver_name, receiver_email))
msg['From'] = formataddr((sender_name, sender_email))
msg['Subject'] = 'Hello, my friend ' + receiver_name
try:
# Creating a SMTP session | use 587 with TLS, 465 SSL and 25
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
# Encrypts the email
context = ssl.create_default_context()
server.starttls(context=context)
# We log in into our Google account
server.login(sender_email, password)
# Sending email from sender, to receiver with the email body
server.sendmail(sender_email, receiver_email, msg.as_string())
print('Email sent!')
if receiver_email in email_stats:
email_stats[receiver_email] += 1
else:
email_stats[receiver_email] = 1
except Exception as e:
print(f'Oh no! Something bad happened!n {e}')
finally:
print('Closing the server...')
server.quit()
print(email_stats) # output - all occurrences for each email
with open(counter_file_path, "w") as f:
json.dump(email_stats, f)
You can use this code to store/print success mail count into a JSON format.
import smtplib
import SSL
import json
import os
from email.mime.text import MIMEText # New line
from email.utils import formataddr # New line
fileName = "sendMail_count.json"
# To store data into json file.
# It will create file in datetime format.
def store_data_to_file(jsonStr):
jsonFile = open(fileName, "w")
json.dump(jsonStr, jsonFile)
print("data stored successfully")
# User configuration
sender_email = 'email ID'
sender_name = 'name'
password = "password"
receiver_emails = [RECEIVER_EMAIL_1, RECEIVER_EMAIL_2, RECEIVER_EMAIL_3]
receiver_names = [RECEIVER_NAME_1, RECEIVER_NAME_2, RECEIVER_NAME_3]
# To store the count of successful mail received by receiver with their respective email.
if not os.path.exists(fileName) or os.stat(fileName).st_size == 0:
print("File is empty or not found")
print("Creating a JSON file to store the data")
jsonFile = open(fileName, "w+")
print("a JSON file has been created with name: " + str(fileName))
success_mail_count = {}
else:
with open(fileName) as jsonFile:
success_mail_count = json.load(jsonFile)
print(success_mail_count)
# Email text
email_body = '''
This is a test email sent by Python. Isn't that cool?
'''
for receiver_email, receiver_name in zip(receiver_emails, receiver_names):
count = 0
print("Sending the email to..." + receiver_email)
# Configurating user's info
msg = MIMEText(email_body, 'plain')
msg['To'] = formataddr((receiver_name, receiver_email))
msg['From'] = formataddr((sender_name, sender_email))
msg['Subject'] = 'Hello, my friend ' + receiver_name
try:
# Creating a SMTP session | use 587 with TLS, 465 SSL and 25
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
# Encrypts the email
context = ssl.create_default_context()
server.starttls(context=context)
# We log in into our Google account
server.login(sender_email, password)
# Sending email from sender, to receiver with the email body
server.sendmail(sender_email, receiver_email, msg.as_string())
# Check if recevier is already present in the dict,
# then add 1 to its current count
if receiver_email in success_mail_count:
success_mail_count[receiver_email] = str(int(success_mail_count[receiver_email]) + 1)
# If reciever isn't present in map then create new entry for receiver and
# Update the count with one for successfull mail sent.
else:
success_mail_count[receiver_email] = str(count + 1)
print('Email sent!')
except Exception as e:
print(f'Oh no! Something bad happened!n {e}')
finally:
print('Closing the server...')
server.quit()
print(success_mail_count)
store_data_to_file(success_mail_count)
run this code and it will create data into file and then it will read data from file itself.
i need help for send a mail in the Lotus Notes using python, appear that the win32com can do it, but i don't found any complete example or tutorial. My idea is a simple function like it:
from win32com.client import Dispatch
import smtplib
def SendMail(subject, text, user):
session = Dispatch('Lotus.NotesSession')
session.Initialize('???')
db = session.getDatabase("", "")
db.OpenMail();
Some suggestion? Thanks!
Below is some code that I have used for this purpose for several years:
from __future__ import division, print_function
import os, uuid
import itertools as it
from win32com.client import DispatchEx
import pywintypes # for exception
def send_mail(subject,body_text,sendto,copyto=None,blindcopyto=None,
attach=None):
session = DispatchEx('Lotus.NotesSession')
session.Initialize('your_password')
server_name = 'your/server'
db_name = 'your/database.nsf'
db = session.getDatabase(server_name, db_name)
if not db.IsOpen:
try:
db.Open()
except pywintypes.com_error:
print( 'could not open database: {}'.format(db_name) )
doc = db.CreateDocument()
doc.ReplaceItemValue("Form","Memo")
doc.ReplaceItemValue("Subject",subject)
# assign random uid because sometimes Lotus Notes tries to reuse the same one
uid = str(uuid.uuid4().hex)
doc.ReplaceItemValue('UNIVERSALID',uid)
# "SendTo" MUST be populated otherwise you get this error:
# 'No recipient list for Send operation'
doc.ReplaceItemValue("SendTo", sendto)
if copyto is not None:
doc.ReplaceItemValue("CopyTo", copyto)
if blindcopyto is not None:
doc.ReplaceItemValue("BlindCopyTo", blindcopyto)
# body
body = doc.CreateRichTextItem("Body")
body.AppendText(body_text)
# attachment
if attach is not None:
attachment = doc.CreateRichTextItem("Attachment")
for att in attach:
attachment.EmbedObject(1454, "", att, "Attachment")
# save in `Sent` view; default is False
doc.SaveMessageOnSend = True
doc.Send(False)
if __name__ == '__main__':
subject = "test subject"
body = "test body"
sendto = ['abc#def.com',]
files = ['/path/to/a/file.txt','/path/to/another/file.txt']
attachment = it.takewhile(lambda x: os.path.exists(x), files)
send_mail(subject, body, sendto, attach=attachment)
If your company is set up such a way that a host IP address and Port is sufficient to send an email, then use the following:
import smtplib
from email.mime.base import MIMEBase
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def emailReport(attach_path,file_name,From,to,cc=None):
msg = MIMEMultipart()
msg['Subject'] = file_name
msg['From'] = From
msg['To'] = ", ".join(to)
msg['CC'] = ", ".join(cc)
msg.attach(MIMEText("****Body of your email****\n"))
#For multiple attachments repeat/loop the following:
part = MIMEBase('application', "octet-stream")
part.set_payload(open(attach_path.format(file_name), "rb").read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename=%s' % file_name)
msg.attach(part)
#Repeat stops here....
s = smtplib.SMTP(host='xxx.xxx.xx.x',port=xx) #Enter your IP and port here
s.sendmail(From,to+cc,msg.as_string())
s.quit()
to=['Person1#email.com', 'Person2#email.com']
cc=['Person3#email.com', 'Person4#email.com']
From='Your#email.com'
attach_path=r'C:\Users\Desktop\Temp'
file_name='Test.xlsx'
emailReport(attach_path,file_name,From,to,cc)
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()