Python Email Notification Not Sending - python

This code is supposed to send an email to a specified address and when I hard code the "TEXT" & "SUBJECT" it seems to send fine but when I create it as a function and call it it never sends the email and never prints the "Notification Sent" message. What am I missing?
Tried hard coding the TEXT and SUBJECT and it sends fine! NOTE: YOU MUST ENABLE LESS SECURE APPS WHEN USING GMAIL!
import smtplib
class email_thing:
def email_notification(self,SUBJECT,TEXT):
TO = 'email#example.com'
self.SUBJECT = SUBJECT
self.TEXT = TEXT
gmail_sender = 'email#example.com'
gmail_passwd = 'examplepassword'
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login(gmail_sender, gmail_passwd)
return self.SUBJECT
return self.TEXT
BODY = '\r\n'.join(['To: %s' % TO,
'From: %s' % gmail_sender,
'Subject: %s' % SUBJECT,
'',TEXT])
try:
server.sendmail(gmail_sender, [TO], BODY)
print ('Notification Sent!')
except:
print ('error sending mail')
server.quit()
test_send = email_thing()
test_send.email_notification(SUBJECT ='Test Email',TEXT = 'This is a test from python!')

Remove
return self.SUBJECT
return self.TEXT
return exits method at once so code after return is never executed.

Related

Send Reply to email thread

I'm trying to reply to an email based on the following criteria:
Scan the inbox for unseen mails with specific Subject content, if there is mails that satisfy those criteria then: send back an reply message to the sender saying "something", if those criteria are not met then: send back an reply message to the sender saying "something".
This is what i came up with so far:
import imaplib
import email
import smtplib
username = 'sample#gmail.com'
password = 'xxxx'
imap_server = imaplib.IMAP4_SSL('smtp.gmail.com')
imap_server.login(username, password)
imap_server.select('INBOX')
result, data = imap_server.search(None, '(UNSEEN)')
email_ids = data[0].split()
for email_id in email_ids:
result, data = imap_server.fetch(email_id, "(RFC822)")
raw_email = data[0][1]
email_message = email.message_from_bytes(raw_email)
subject = email_message["Subject"]
if subject == "SOME SPECIFIC CONTENT":
reply = email.message.EmailMessage()
reply["To"] = email_message["From"]
reply["Subject"] = "Re: " + email_message["Subject"]
reply["In_Reply-To"] = email_message["From"]
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login(username, password)
server.sendmail(username, reply["In_Reply-To"], 'Subject: Criteria met\n\nThank you.')
server.quit()
else:
reply = email.message.EmailMessage()
reply['To'] = email_message['From']
reply['Subject'] = "RE:" + email_message['Subject']
reply["In_Reply-To"] = email_message["From"]
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login(username, password)
server.sendmail(username, reply["In_Reply-To"], 'Subject: Criteria not met\n\Thank you.')
print('Sending email')
server.quit()
imap_server.close()
It sends the email but without the desired thread, just sends a new email and not actually replying back to the sender.
Any suggestion on how to modify the code so it actually send an reply with the desired thread?
Thank you in advance.
Like the comment mentions, you should use the Message-Id of the original message, not the sender address.
Also, you should obey Reply-To: and add References:.
reply = email.message.EmailMessage()
reply["To"] = email_message["Reply-To"] or email_message["From"]
reply["Subject"] = "Re: " + email_message["Subject"]
reply["In_Reply-To"] = email_message["Message-Id"]
reply["References"] = (email_message["References"] or "") + " " + email_message["Message-Id"]
Properly speaking, the References: header should be trimmed from the middle if it's too long.
Some vendors have their own nonstandard threading extensions; in particular, Microsoft's Thread-Id: etc headers are probably best ignored.

How to take a screenshot when except happens and send it in a email? (Python)

I want to take a screenshot using python/selenium when an except happens and send it through an email? How do I do this? I don't want to save it, but I don't mind saving it to a folder but I want to send an email with where the error happened. All examples so far I've seen seem to be saving it to a folder. My code below.
def myfunction(self):
try:
#some code
except NoSuchElementException:
print("error appeared")
#take screenshot here
subject = '')
message = (f"""Here is the screeenshot of the error """)
self.sendEmailBOTS(self.errorReportemail, self.errorReportemailpasswd, self.errorReportemail, subject, message)
for mail in self.ccBots:
self.sendEmailBOTS(self.errorReportemail, self.errorReportemailpasswd, mail, subject, message)
def sendEmailBOTS(self, email, password, send_to, subject, message):
print("Sending email to", send_to)
logging.info("Sending email to")
msg = MIMEMultipart()
msg["From"] = email
msg["To"] = send_to
msg["Subject"] = subject
msg.attach(MIMEText(message, 'plain'))
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(email, password)
text = msg.as_string()
server.sendmail(email, send_to, text)
server.quit()
You can try to take a screen shot like this :
myfunction(self):
try:
# some code
except NoSuchElementException:
print("error appeared")
# take screenshot here
driver.save_screenshot('file name here')
def somefunction(self):
imagepath = os.path.join(root, 'Errorimages\\ERROR')
image_screenshot = imagepath + ".png"
self.driver.save_screenshot(image_screenshot)
subject = '')
message = (f"""Here is the screeenshot of the error """)
self.sendEmailBOTS(self.errorReportemail, self.errorReportemailpasswd, self.errorReportemail, subject, message)
for mail in self.ccBots:
self.sendEmailBOTS(self.errorReportemail, self.errorReportemailpasswd, mail, subject, message)
def filefunction(self):
def sendEmailBOTS(self, email, password, send_to, subject, message):
print("Sending email to", send_to)
logging.info("Sending email to")
msg = MIMEMultipart()
msg["From"] = email
msg["To"] = send_to
msg["Subject"] = subject
msg.attach(MIMEText(message, 'plain'))
filename = "ERROR.png"
locationImages = os.path.join(root, 'Errorimages\\ERROR.png')
attachment = open(locationImages, "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)
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(email, password)
text = msg.as_string()
server.sendmail(email, send_to, text)
server.quit()
This is what I came up with. Its not perfect but it takes the screenshot ,saves it in a folder and then the email sends that picture.

Weird display of 'From' field in smtp email sent in python

I am getting weird display of From field in smtp email.The display is like;
from: test#gmail.com To: test#gmail.com, Subject: Message test#gmail.com
to:
to field is blank but the another 'to' recipient, ie test1#gmail.com received the email successfully.
Below is my code.
import smtplib
def SendEmailScenario1():
gmail_user = "test#gmail.com"
gmail_password = '******'
sent_from = gmail_user
to = ["test1#gmail.com"]
subject = 'Message'
body = "Hi There! Done1"
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(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...')
def SendEmailScenario2():
gmail_user = "test#gmail.com"
gmail_password = '******'
sent_from = gmail_user
to = ["test1#gmail.com"]
subject = 'Message'
body = "Hi There! Done 2"
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(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...')
SendEmailScenario1()
SendEmailScenario2()
How to bring it to normal display without using MIMEText, MIMEMultipart
RFC822 specifies that a header should terminate with '\r\n':
field = field-name ":" [ field-body ] CRLF
Furthermore, the headers should be separated from the body by an empty '\r\n':
[The body] is separated from the headers by a null line (i.e., a
line with nothing preceding the CRLF)
So the message should be constructed like this:
headers = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n"
email_text = headers + body
See also the example in the smtplib docs.

Populate other email fields like Subject in Python mail function

I have tested this piece of code and it sends the email successfully, it tends to leave the subject fields, cc and bcc fields empty as seen in the photo.
import smtplib
gmail_user = 'dummy#gmail.com'
gmail_password = 'password'
sent_from = 'dummy#gmail.com'
to = ['receiver#gmail.com']
subject = 'OMG Super Important Message'
body = "Hey, what's up?\n\n- You"
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
print("establish connection successful")
server.ehlo()
print("identification successful")
server.login(gmail_user, gmail_password)
print("login successful")
server.sendmail(sent_from, to, email_text)
print("send mail successful")
server.close()
print('Email sent!')
except:
print('Something went wrong...')
Does anyone know how I can fill them up through this script?
For the email subject - there is a specific format to the input arg you provide to server.sendmail that should work. Could you try:
subject = 'This is the email subject'
text = 'This is the email body'
message = "Subject: {}\n\n{}".format(subject, text)
server.sendmail(sender, recipient, message)
If you try to open the source of an email you will see something like this:
Received: from ************.net ([***.**.2.17]) by
*****.****.net ([**.***.224.162]) with mapi id **.03.****.***;
Mon, 22 May 2017 09:14:59 +0200
From: *FROMEMAIL* <******#***.com>
To: *TOEMAIL* <********#***.com>
CC: *CCEMAIL* <********#*****.com>
Subject: E-mail - 150633**0686_****.pdf
...
That is the header of the email, so if you try something like this:
import smtplib
gmail_user = 'dummy#gmail.com'
gmail_password = 'password'
sent_from = 'dummy#gmail.com'
to = ['receiver#gmail.com']
subject = 'OMG Super Important Message'
body = "Hey, what's up?\n\n- You"
cc = "****#***.com"
bcc = "******#*****.com"
email_text = """\
From: %s
To: %s
CC: %s
BCC: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), cc, bcc,subject, body)
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
print("establish connection successful")
server.ehlo()
print("identification successful")
server.login(gmail_user, gmail_password)
print("login successful")
server.sendmail(sent_from, to, email_text)
print("send mail successful")
server.close()
print('Email sent!')
except:
print('Something went wrong...')
I think it will work

In python's smtplib why isn't the subject or From field set?

can anyone see why the following code sends emails successfully but it shows up as being from the email address of the sender instead of the name of the sender in the recipients inbox, and the subject shows up as "No Subject" in their inbox. Thanks in advance.
def send_email(destination, subject, message):
from_who = "My Name"
to_send = """\From: %s\nTo: %s\nSubject: %s\n\n%s""" % (from_who, destination, subject, message)
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(my_email_addr, my_pwrd)
server.sendmail(from_who, destination, message)
server.close()
except:
print "failed"
If you want to use SMTP in python, you need to send the data as a dictionary.
from email.parser import Parser
# This will parse out your to-, from-, and subject fields automatically
headers = Parser().parsestr(to_send)
# This will take care of the to- and from-fields for you
server.send_message(headers)
test.py
from email.parser import Parser
from_whom = "hello#example.com"
destination = "world#example.com"
subject = "Foobar!"
message = "Bar bar binks"
to_send = """From: %s\nTo: %s\nSubject: %s\n\n%s""" % (from_whom, destination, subject, message)
print(to_send)
headers = Parser().parsestr(to_send)
print(headers["To"]) # world#example.com
print(headers["From"]) # hello#example.com
print(headers["Subject"]) # Foobar!
EDIT
Alternatively, you could do this:
to_send = string.join((
"From: %s" % from_whom,
"To: %s" % destination,
"Subject: %s" % subject,
"",
message
), "\r\n")
# ...
server.sendmail(from_whom, [destination], to_send)
# ...
I think the other way is cleaner, but this is up to you.

Categories