I've searched a fair bit on this and couldn't come up with anything satisfactory.
I've been trying to write a python program to listen for email bounce reports and depending on the reason for the bounce resend them at different intervals.
import smtplib
from smtplib import *
sender = 'foo#bar.com'
receivers = ['42#life.com']
message = """From: From Arthur <foo#bar.com>
To: To Deep Thought <42#life.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
try:
smtpObj = smtplib.SMTP('smtp.gmail.com',587)
smtpObj.starttls()
smtpObj.login(sender,'foo#bar.com')
smtpObj.sendmail(sender, receivers, message)
print "Successfully sent email"
except SMTPResponseException:
error_code = SMTPResponseException.smtp_code
error_message = SMTPResponseException.smtp_error
print "Error code:"+error_code
print "Message:"+error_message
if (error_code==422):
print "Recipient Mailbox Full"
elif(error_code==431):
print "Server out of space"
elif(error_code==447):
print "Timeout. Try reducing number of recipients"
elif(error_code==510 or error_code==511):
print "One of the addresses in your TO, CC or BBC line doesn't exist. Check again your recipients' accounts and correct any possible misspelling."
elif(error_code==512):
print "Check again all your recipients' addresses: there will likely be an error in a domain name (like mail#domain.coom instead of mail#domain.com)"
elif(error_code==541 or error_code==554):
print "Your message has been detected and labeled as spam. You must ask the recipient to whitelist you"
elif(error_code==550):
print "Though it can be returned also by the recipient's firewall (or when the incoming server is down), the great majority of errors 550 simply tell that the recipient email address doesn't exist. You should contact the recipient otherwise and get the right address."
elif(error_code==553):
print "Check all the addresses in the TO, CC and BCC field. There should be an error or a misspelling somewhere."
else:
print error_code+": "+error_message
To which I get the following error:
Traceback (most recent call last): File "C:/Users/Varun
Shijo/PycharmProjects/EmailBounce/EmailBounceTest.py", line 20, in
error_code = SMTPResponseException.smtp_code AttributeError: type object 'SMTPResponseException' has no attribute 'smtp_code'
I read somewhere that I should be trying to get the attribute from an instance of the SMTPResponseException class (even though the smtplib documentation says otheriwse) so I tried that too, but I wasn't sure of what arguments to pass its constructor (code,msg).
Could someone please nudge me in the right direction?
Thanks.
try with
except SMTPResponseException as e:
error_code = e.smtp_code
error_message = e.smtp_error
Related
def mail():
server = smtplib.SMTP('smtp-mail.outlook.com',587)
server.starttls()
server.login(env, password)
server.sendmail(env,rec,msg =str(list))
print("Login no servidor efetuado com Sucesso")
print("Email enviado para " + rec)
server.close()
I use this code to send an email but the email comes empty i tryed to swap msg = str(list) to just list tried remove message and type in the third argument just a string and emails always come empty
server.sendmail(env,rec,msg =str(list))
You see what your message contains?
str(list)
Try typing this same thing in a scope in which list is not overwritten (because list is not reassigned in your mail function).
>>> str(list)
"<class 'list'>"
For sure that's not the right way of doing this.
What's more, in the same line of code above I don't see the assignation of env and rec, so I guess there must be some error there.
I am experimenting with smtplib in Python3.
I want to send the content of a variable to an email address. If there is an smtplib.SMTPAuthenticationError, I want to send that variable to an alternative email address. This works (see code below). But what if I want to add a third email address (if the first two fail for some reason)?
I don't think try and except allow me to add another block of the same code (with different email login details).
I know with subprocess, it's possible to acquire the returncode of a variable and then use if.
For example:
result = subprocess.run(["ls", "-al"], capture_output = True)
if result !=0:
do_something_to_list_the_directory
I don't know how this can be done without using subprocess. Can anyone please advise?
Code below:
try:
mail_sending_attempt = smtplib.SMTP("smtp_provider", 587)
mail_sending_attempt.starttls()
mail_sending_attempt.login(send, passinfo) ### this will not work
mail_sending_attempt.sendmail(send, receive, message)
mail_sending_attempt.quit()
except Exception:
mail_sending_attempt = smtplib.SMTP("smtp_provider", 587)
mail_sending_attempt.starttls()
mail_sending_attempt.login(send2, passinfo2) ### this will not work
mail_sending_attempt.sendmail(send2, receive2, message)
mail_sending_attempt.quit()
In case there are more email, you can use following snippet
from dataclasses import dataclass
#dataclass
class EmailData:
send: str
passinfo: str
receive: str
main = EmailData("send1", "passinfo1", "receive1")
backup_1 = EmailData("send2", "passinfo2", "receive2")
...
for data in [main, backup_1, ...]:
try:
mail_sending_attempt = smtplib.SMTP("smtp_provider", 587)
mail_sending_attempt.starttls()
mail_sending_attempt.login(data.send, data.passinfo)
mail_sending_attempt.sendmail(data.send, data.receive, message)
mail_sending_attempt.quit()
break
except Exception:
continue
else:
# the case when we won't encounter break, so every login failed.
raise Exception
We're currently using a super basic Python script that I found online a while ago to send an error report via HTML from out departmental email address. However, as it currently stands, it sends the email from our email address to our email address. I'm hoping there might be some way to send the email from the address of the current user. Here's what we've got:
def sendMail(sender, recipient, subject, html, text):
import MimeWriter, mimetools, cStringIO
import smtplib
out = cStringIO.StringIO()
htmlin = cStringIO.StringIO(html)
txtin = cStringIO.StringIO(text)
writer = MimeWriter.MimeWriter(out)
writer.addheader("From", sender)
writer.addheader("To", recipient)
writer.addheader("Subject", subject)
writer.addheader("MIME-Version", "1.0")
writer.startmultipartbody("alternative")
writer.flushheaders()
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()
subpart = writer.nextpart()
subpart.addheader("Content-Transfer-Encoding", "quoted-printable")
pout = subpart.startbody("text/html", [("charset", 'us-ascii')])
mimetools.encode(htmlin, pout, 'quoted-printable')
htmlin.close()
writer.lastpart()
msg = out.getvalue()
server = smtplib.SMTP('smtp.office365.com',587)
server.ehlo()
server.starttls()
server.ehlo()
server.login("sample#email.com","sample")
server.sendmail(sender, recipient, msg)
server.quit()
Then we're using a simple try/except execfile script to run everything from:
try:
execfile('\\\\path.py')
except:
print 'ATTENTION: An error has been detected in a script process.'
traceback.print_exc(file=sys.stdout)
import sys, cgitb
recipient =
['sample#email.com','sample2#email.com','sample3#email.com','sample4#email.com']
for rec in recipient:
Utils.sendMail('sample#email.com',
rec,
'ATTENTION: An error has been detected in a script process...',
cgitb.html(sys.exc_info()),
cgitb.text(sys.exc_info()))
sys.exit()
It's here where we define the address we're sending to:
for rec in recipient:
Utils.sendMail('sample#email.com',
rec,
'ATTENTION: An error has been detected in a script process...',
cgitb.html(sys.exc_info()),
cgitb.text(sys.exc_info()))
sys.exit()
Is there some kind of AD script we can implement here? We've got about 30 people using our processes so whenever an error pops up all we get is an email with the error and no reference to who it belongs to.
It is not easy to work with AD in Python, and it's even tougher to do without installing any 3rd party modules.
Would adding the username that ran the script in the email body or subject suffice instead?:
import getpass
user = getpass.getuser()
Then in the execfile script:
Utils.sendMail(
'sample#email.com',
rec,
'ATTENTION: %s has run a script which has errored...' % user,
cgitb.html(sys.exc_info()),
cgitb.text(sys.exc_info())
)
It is important to note that this should not be used for any legitimate authentication purposes, as it does not protect against user-spoofing and the likes..
Sounds like you need to group you recipients i.e. you could have a group for engineers, quality assurance, business development, management, etc..
where each group is represented by a list of email addresses.
This way when an error occurs, you may send a human readable email describing the issue to the quality assurance group.
As for the engineers, you may want to send a more technical email that not only contains the human readable error descriptions, but also an additional stack trace. When an engineer is attempting to troubleshoot an error message more, is better.
As for the business development and management group, they probably shouldn't be receiving emails on failures.
hope that helps.
I'm working with the Gmail API in python, getting a request with:
gmail_auth = GmailUserSocialAuth.objects.filter(uid='...')[0]
response = gmail_auth.request('get', '...')
data = response.json()
response - gmail_auth.request('get', '/%s' % data['messages'][0]['id']
message = response.json()
When I print out the message, I get large large objects with all the fields and such. With one of the messages, I get this response:
{
... # a lot of fields
u'sizeEstimate': 10100,
'html_body': '',
'decoded_body': '',
u'snippet': u'Hi —, <content of email>. On Jun 30, 2016..., Ofek Gila <...> wrote: <content of previous email in thread>.',
}
Anyway, the issue is that I know the email was written because it appears in the snippet, but it doesn't show up anywhere else in the message object.
Any idea what could be happening?
Thanks in advance!
Try to use the get method as stated in the Python sample code.
Here's a snippet:
def GetMimeMessage(service, user_id, msg_id):
"""Get a Message and use it to create a MIME Message.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
msg_id: The ID of the Message required.
Returns:
A MIME Message, consisting of data from Message.
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id,
format='raw').execute()
print 'Message snippet: %s' % message['snippet']
msg_str = base64.urlsafe_b64decode(message['raw'].encode('ASCII'))
mime_msg = email.message_from_string(msg_str)
return mime_msg
except errors.HttpError, error:
print 'An error occurred: %s' % error
You may also check this SO thread and this one for additional insight.
I have a python script that has to fetch unseen messages, process it, and mark as seen (or read)
I do this after login in:
typ, data = self.server.imap_server.search(None, '(UNSEEN)')
for num in data[0].split():
print "Mensage " + str(num) + " mark"
self.server.imap_server.store(num, '+FLAGS', '(SEEN)')
The first problem is that, the search returns ALL messages, and not only the UNSEEN.
The second problem is that messages are not marked as SEEN.
Can anybody give me a hand with this?
Thanks!
import imaplib
obj = imaplib.IMAP4_SSL('imap.gmail.com', '993')
obj.login('user', 'password')
obj.select('Inbox') <--- it will select inbox
typ ,data = obj.search(None,'UnSeen')
obj.store(data[0].replace(' ',','),'+FLAGS','\Seen')
I think the flag names need to start with a backslash, eg: \SEEN
I am not so familiar with the imaplib but I implement this well with the imapclient module
import imapclient,pyzmail,html2text
from backports import ssl
context=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
iobj=imapclient.IMAPClient('outlook.office365.com', ssl=True, ssl_context=context)
iobj.login(uname,pwd)# provide your username and password
iobj.select_folder('INBOX',readonly=True)# Selecting Inbox.
unread=iobj.search('UNSEEN')# Selecting Unread messages, you can add more search criteria here to suit your purpose.'FROM', 'SINCE' etc.
print('There are: ',len(unread),' UNREAD emails')
for i in unread:
mail=iobj.fetch(i,['BODY[]'])#I'm fetching the body of the email here.
mcontent=pyzmail.PyzMessage.factory(mail[i][b'BODY[]'])#This returns the email content in HTML format
subject=mcontent.get_subject()# You might not need this
receiver_name,receiver_email=mcontent.get_address('from')
mail_body=html2text.html2text(mcontent.html_part.get_payload().decode(mcontent.html_part.charset))# This returns the email content as text that you can easily relate with.
Let's say I want to just go through the unread emails, reply the sender and mark the email as read. I'd call the smtp function from here to compose and send a reply.
import smtplib
smtpobj=smtplib.SMTP('smtp.office365.com',587)
smtpobj.starttls()
smtpobj.login(uname,pwd)# Your username and password goes here.
sub='Subject: '+str(subject)+'\n\n'# Subject of your reply
msg='Thanks for your email! You're qualified for the next round' #Some random reply :(
fullmsg=sub+new_result
smtpobj.sendmail(uname,test,fullmsg)# This sends the email.
iobj.set_flags(i,['\\Seen','\\Answered'])# This marks the email as read and adds the answered flag
iobj.append('Sent Items', fullmsg)# This puts a copy of your reply in your Sent Items.
iobj.logout()
smtpobj.logout()
I hope this helps