I wrote a code to send a confirmation email with Python and it works, but when I put it in the function, sending the code has a problem. Please help me.
code :
import smtplib
import random
verify_code=str(random.randint(1111,9999))
sent_from = 'code#r*****'
password='*******'
to = ['re******#gmail.com']
subject = 'verify code'
body = ('your code is :'+str(code))
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
smtp_server = smtplib.SMTP_SSL('mx2.ta*******.com', 465)
smtp_server.ehlo()
smtp_server.login(sent_from, password)
smtp_server.sendmail(sent_from, to, email_text)
smtp_server.close()
print ("Email sent successfully!")
and When I put in the function :
def mail(code):
import smtplib
import random
code=str(random.randint(1111,9999))
sent_from = 'code#r****'
password='*******'
to = ['re*******#gmail.com']
subject = 'verify code'
body = ('your code is :'+str(code))
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
smtp_server = smtplib.SMTP_SSL('mx2.tal*****.com', 465)
smtp_server.ehlo()
smtp_server.login(sent_from, password)
smtp_server.sendmail(sent_from, to, email_text)
smtp_server.close()
print ("Email sent successfully!")
Error while executing the function:
This message was created automatically by mail delivery software.
A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:
reza*****#gmail.com
host gmail-smtp-in.l.google.com [108.177.126.27]
SMTP error from remote mail server after end of data:
550-5.7.1 [185.51..] Our system has detected that this message is not RFC
550-5.7.1 5322 compliant:
550-5.7.1 'From' header is missing.
550-5.7.1 To reduce the amount of spam sent to Gmail, this message has been
550-5.7.1 blocked. Please visit
550-5.7.1 https://support.google.com/mail/?p=RfcMessageNonCompliant
550 5.7.1 and review RFC 5322 specifications for more information.
Attempt 1 : ratelimit number of emails sent
You are probably sending too many emails at once. Try waiting a few seconds between each email. Since you are using a Gmail account to send emails, you might want to have a look at the email quotas imposed by Google.
Also if you are calling your function in a loop, you are sending multiple emails to the same recipient. The parameter of your function should the email of the recipient instead of code.
import smtplib
import random
import time
def mail(recipient):
code = str(random.randint(1111, 9999))
sent_from = 'code#r****'
password = '*******'
to = [recipient]
subject = 'verify code'
body = ('your code is :'+str(code))
email_text = """From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
smtp_server = smtplib.SMTP_SSL('mx2.tal*****.com', 465)
smtp_server.ehlo()
smtp_server.login(sent_from, password)
smtp_server.sendmail(sent_from, to, email_text)
smtp_server.close()
print("Email sent successfully!")
recipient_list = ['aaa#gmail.com', 'bbb#gmail.com']
for recipient in recipient_list:
mail(recipient)
time.sleep(1) # wait 1s before sending next email
Attempt 2 : use CRLF character directly in email_text
The format of the From field field as required by RFC 5322 is :
"From:" mailbox-list CRLF
In Python the CRLF character is \r\n so lets use it directly in email_text as shown below :
email_text = (
"""From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s"""
% (sent_from, ", ".join(to), subject, body))
This ensures that the correct line breaks are inserted at the right place. (we don't have to rely on the line breaks inserted by Enter key)
full code with function :
import smtplib
import random
def mail():
code = str(random.randint(1111, 9999))
sent_from = 'code#r****'
password = '*******'
to = ['re*******#gmail.com']
subject = 'verify code'
body = ('your code is :'+str(code))
email_text = (
"""From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s"""
% (sent_from, ", ".join(to), subject, body))
print(email_text)
smtp_server = smtplib.SMTP_SSL('mx2.tal*****.com', 465)
smtp_server.ehlo()
smtp_server.login(sent_from, password)
smtp_server.sendmail(sent_from, to, email_text)
smtp_server.close()
print("Email sent successfully!")
mail()
Related
I wanted to try to send emails with python and found some barebone code to do so online
import smtplib
gmail_user = 'myaddress#gmail.com'
gmail_pw = 'myPassword'
sent_from = gmail_user
to = ['mailAdrr1#domain.com', 'mailAdrr2#domain.com']
subject = 'Some Subject'
body = 'Some body'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
try:
smtp_server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
smtp_server.ehlo()
smtp_server.login(gmail_user, gmail_pw)
smtp_server.sendmail(sent_from, to, email_text)
smtp_server.close()
print("Success")
except Exception as ex:
print("Error: ", ex)
Now I wanted to send an email to every target separately so I added a foreach loop within the code. This resulted in the Email headers being messed up and all the headers were interpreted as the From header. Although when I printed them out, they looked fine
After being very confused as to why this happens I decided to try to wrap the entire code in a for loop with one iteration which - according to my understanding - should change nothing at all. But in fact it does produce the same issue as described above. This is how I wrapped the code in a loop:
import smtplib
for i in range(1):
gmail_user = 'myaddress#gmail.com'
gmail_pw = 'myPassword'
sent_from = gmail_user
to = ['mailAdrr1#domain.com', 'mailAdrr2#domain.com']
subject = 'Some Subject'
body = 'Some body'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
try:
smtp_server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
smtp_server.ehlo()
smtp_server.login(gmail_user, gmail_pw)
smtp_server.sendmail(sent_from, to, email_text)
smtp_server.close()
print("Success")
except Exception as ex:
print("Error: ", ex)
Why does a for loop with one iteration change anything about the workings of the code if literally everything is done within it?
this is the code you would want I suspect:
import smtplib
gmail_user = 'MyEmail#gmail.com'
gmail_pw = 'MyPassword'
sent_from = gmail_user
to = ['PersonA#gmail.com', 'PersonB#gmail.com']
subject = 'Some Subject for multiple people'
body = 'Some body for a few'
smtp_server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
smtp_server.ehlo()
smtp_server.login(gmail_user, gmail_pw)
for email in to:
email_text = 'Subject:{}\n\n{}'.format(subject, body)
try:
smtp_server.sendmail(sent_from, email, email_text)
print("Success")
except Exception as ex:
print("Error: ", ex)
smtp_server.close()
You had 2 main problems with how you were approaching it. For whatever reason, if you logged in inside of a loop, it would fail. I've moved this to the start and called close() at the end to prevent logging in multiple times as well.
The second issue you had was to do with how you were formatting the email data itself. I used this answers example to assist with making this work, so see this for more: How to add a subject to an email being sent with gmail?
Hopefully, this solves your issue!
Many thanks, GhostDog
Im trying to write a simple script which has to send a simple email in some cases.
I have the following script which works well if im using just only this script.
import smtplib
mail_user = '123#123.com'
mail_password = 'password'
sent_from = mail_user
to = ['reciever#address.com']
subject = 'My subject'
body = 'Hello mail.'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
try:
server = smtplib.SMTP_SSL('mail.123.com', 465)
server.ehlo()
server.login(mail_user, mail_password)
server.sendmail(sent_from, to, email_text)
server.close()
print 'Email sent!'
except:
print 'Something went wrong...'
The problem is when im trying to put this code into a def and call from outside the e-mail is missing headers, i mean the email is arriving without sender and without subject. Sender empty and subject empty, but i have only the body.
I also can not get the mail when im sending to another domain, but i think this is because the another domain is rejecting the mail without headers, when using only the script the mail arrives also to other domains.
import smtplib
def sendMail():
mail_user = '123#123.com'
mail_password = 'password'
sent_from = mail_user
to = ['reciever#address.com']
subject = 'My subject'
body = 'Hello mail.'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
try:
server = smtplib.SMTP_SSL('mail.123.com', 465)
server.ehlo()
server.login(mail_user, mail_password)
server.sendmail(sent_from, to, email_text)
server.close()
print 'Email sent!'
except:
print 'Something went wrong...'
sendMail();
What is the diffenerece when i put this code into a def? Why this happening? What im doing wrong?
Thanks for help.
In your function version, your email headers have become indented
email_text = """\
From: %s
To: %s
Subject: %s
%s
...
In this string, the To: and Subject: are now indented.
def sendMail():
call it with:
sendMail()
not SendMail()
I am trying to send an email using Pythion smtp library. I have got below code but somehow when I get an email, it doesn't have "To", "Subject" and "Body" contents as they are missing. I believe something is wrong with the way message string is constructed.
import smtplib
import socket
FROM = "from#host.com"
TO = ["to#host.com"]
def send_email():
hostname = socket.getfqdn()
text = "Hello"
subject = "Error on %s " % (hostname)
print subject
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), subject, text)
smtp_server = ""
if ".dev" not in hostname:
smtp_server = "abc.host.com"
else:
smtp_server = "pqr.host.com"
# Send the mail
server = smtplib.SMTP(smtp_server)
server.sendmail(FROM, TO, message)
server.quit()
send_email()
But when I use exact same below code, it works fine without any issues so I am sure something is wrong with my above code when I put everything in a method. I believe indentation is causing issues with the way message string is contructed or something else which I am not able to figure out.
import smtplib
import socket
SERVER = "abc.host.com"
FROM = "from#host.com"
TO = ["to#host.com"]
SUBJECT = "Test! %s " % (socket.getfqdn())
TEXT = "Testing."
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join( TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()
Here is what I see with first code. If you see closely it has lot of spaces in front of each tag as compared to what gets printed out with second code:
From: from#host.com
To: to#host.com
Subject: Error on machineA
Hello
This is what I see with second code:
From: from#host.com
To: to#host.com
Subject: Test! machineA
Testing.
How do I fix this in first code when I am putting it in a method?
Update:
I tried with below code but it gives me error about indentation is wrong on print message.
import smtplib
import socket
FROM = "from#host.com"
TO = ["to#host.com"]
def send_email():
hostname = socket.getfqdn()
text = "Hello"
subject = "Error on %s " % (hostname)
print subject
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), subject, text)
print message
smtp_server = ""
if ".dev" not in hostname:
smtp_server = "abc.host.com"
else:
smtp_server = "pqr.host.com"
# Send the mail
server = smtplib.SMTP(smtp_server)
server.sendmail(FROM, TO, message)
server.quit()
send_email()
Use the stdlib emailpackage to help you building your mail as correct SMTP payloads (headers, encoding, parts, ...). https://docs.python.org/3/library/email.html#module-email
There are tons of examples in the standard doc or in stackoverflow.
You are allowed to remove the indents:
def send_email():
# stuff ...
# Prepare actual message
message = """\
From: %s
- other stuff...
""" % (FROM, ", ".join(TO), subject, text)
smtp_server = ""
# more stuff...
server.sendmail(FROM, TO, message)
server.quit()
Also, not sure you need the back slash?
message = ''' < == no backslash
stuff
'''
I'm using Gmail SMTP to send emails in Python, however sometimes the application may stay idle for an extended period of time.
How do I make sure that the session hasn't expired? Here's my code:
def send_email(user, pwd, recipient, subject, body):
import smtplib
gmail_user = user
gmail_pwd = pwd
FROM = user
TO = recipient if type(recipient) is list else [recipient]
SUBJECT = subject
TEXT = body
# Prepare actual message
message = """\From: %s\nTo: %s\nSubject: %s\n\n%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(gmail_user, gmail_pwd)
server.sendmail(FROM, TO, message)
server.close()
print 'successfully sent the mail'
except:
print "failed to send mail"
Can I always reuse the server session, or can it expire after let's say 5 hours?
I have been trying to send a mail from python to Outlook. The body does not appear in the mail. The mail gets send, with the subject. The body is blank. What could be the issue?
Here is my code:
import smtplib
username = "neooooo#example.com"
password = "#death123"
print("Logged in ")
vtext = "nihjdoiwjadv#example.com"
message = "this is the message to be sent"
msg = """From: %s
To: %s
Subject: Hi
Body:%s""" % (username, vtext, message)
print("Connecting to server")
server = smtplib.SMTP('smtp.office365.com',587)
server.starttls()
server.login(username,password)
server.sendmail(username, vtext, msg)
server.quit()
print("Done")
The body is not part of the headers, especially there is no header called Body. The body of a mail comes after the headers, separated by a blank line.
Try this code. It works for me.
import smtplib,getpass,os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
os.system('clear')
msg=MIMEMultipart()
print "---------Python Mail Sender--------\n---------ONLY GMAIL Sender---------"
frm=raw_input("From : ")
to=raw_input("To : ")
msg['From']=frm
msg['To']=to
msg['Subject']=raw_input("Enter Subnject of mail : ")
text=raw_input("Enter text to send in mail : ")
msg.attach(MIMEText(text))
try :
mailserver=smtplib.SMTP("smtp.gmail.com",587)
mailserver.ehlo()
mailserver.starttls()
mailserver.ehlo()
mailserver.login(frm,getpass.getpass("Enter you password(Will not be visible as you Enter) : "))
mailserver.sendmail(frm,to,msg.as_string())
except Exception,e:
print "ERROR : ",e
finally:
mailserver.quit()