Sending emails in python via loop - python

Is there a way to send emails to all the email addresses in the database via for loops? I'm not very sure on for loops and needs help.
I followed this page for email sample. SQL statement would be select email from table name
import smtplib
SERVER = "localhost"
FROM = "sender#example.com"
TO = ["user#example.com"]
SUBJECT = "Hello!"
TEXT = "This message was sent with Python's smtplib."
# 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()

You will have to download and import the correct Database interface. (MySQL or SQL Server etc.)
Then do something like this:
import smtplib
import MySQLdb
SERVER = "localhost"
FROM = "sender#example.com"
TO = ["user#example.com","another#user.com","many#users.com"]
#SQL data access part
db = MySQLdb.connect(host='localhost', user='root', passwd='$$', db='emaildatabase')
cursor = db.cursor()
cursor.execute('select email from tablename where email is not null')
db.commit()
rows = cursor.fetchall()
for item in rows:
TO.append(item)
SUBJECT = "Hello!"
TEXT = "This message was sent with Python's smtplib."
# 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()
Let me know if you don't understand.

Related

Error when executing email send code in Python function

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()

Python send simple mail

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()

Hey I want to send email to more than one person with python

Hey i want to send an email to a bunch of people but for some reason even if the output of print is more than one email the program sending the email only to first person of the text what can i do ?
# Import Python Packages
import smtplib
# Set Global Variables
gmail_user = 'your#gmail.com'
gmail_password = 'password'
# Create Email
mail_from = gmail_user
for i in range(2):
with open('C:\\email.txt', 'r', encoding="utf8") as f
mail_to = f.read().rstrip()
mail_subject = 'subject'
mail_message_body = 'body'
mail_message = '''\
From: %s
To: %s
Subject: %s
%s
''' % (mail_from, mail_to, mail_subject, mail_message_body)
# Sent Email
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.login(gmail_user, gmail_password)
server.sendmail(mail_from, mail_to, mail_message)
print(mail_to)
server.close()
Send_to must be a string object having addresses separated by ", ".
example :
send_to='xyz1#gmail.com,hhdasn#yahoo.com'
The line that performs sending of email is server.sendmail(mail_from, mail_to, mail_message). You are calling it once. You can check it by placing print(mail_to) statement next to it.
You need to call sendmail in loop if you want to send email multiple times.

indentation is causing issues while sending email in a method

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
'''

python sending email with text and attachment

I wrote a script for backing up my Neo4J DB.
At the end of the backup process and email is sent to the DB Administrator
The email received without the message_body.
This is the code:
message = MIMEMultipart('alternative')
message['To'] = "Database Admin <%s>" % _receiver
message['From'] = "Pico.buzz Graph Database <%s>" % _sender
if not log.is_error():
message['Subject'] = "Graph DB Backup Finished Successfully"
message_body = 'Successfully backup email. Please see review log file'
else:
message['Subject'] = "ATTENTION: ERROR! Graph DB Backup Failed"
message_body = 'An error occur during backup. please review log'
instance_name = aws.get_instance_name()
instance_details = "Instance Id: %s\nPrivate IP Address: %s" % (aws.get_instance_id(), aws.get_instance_ip())
if instance_name is not None:
instance_details = """Instance Name: %s\n%s""" % (instance_name, instance_details)
message_body = "%s\n\n%s" % (message_body, instance_details)
content = MIMEText(message_body, 'plain')
message.attach(content)
message.attach(_get_log_file())
smtp = smtplib.SMTP('localhost')
smtp.sendmail(_sender, _receiver, message.as_string())
log.info(__name__, "Successfully sent email to: %s" % _receiver)
Any idea why?
MIMEMultipart takes as a parameter to the constructor a multipart subtype.
You were using the subtype 'alternative'. The alternative subtype allows the email to be sent with HTML and text.
You wanted to submit an email with text and an attachment, so you need to construct MIMEMultipart with the subtype 'mixed'.
For more details about these subtypes, you can look at the MIME Wikipedia entry on Multipart messages.

Categories