Python Email send to "Bcc" instead of "To" address - python

I have tried to search many times before I put down this question, but there is no answer for me.
I'm following the book "Automate Boring Stuff With Python" chapter 16.
I'm currently trying to send email to the receivers as the code format in this book.
The problem is all email I sent are put the receivers in the "Bcc" instead of "To" address which I want. How can I change from "Bcc" to "To"? Much appreciate if anyone can help me solve this problem.
Sorry for didn't attach the code. Please review.
import openpyxl, smtplib, sys
wb = openpyxl.load_workbook("listmail.xlsx")
sheet = wb.get_sheet_by_name("Sheet1")
lastCol = sheet.max_column
lastestMonth = sheet.cell(row=1, column=lastCol).value
unpaidMembers = {}
for r in range (2,sheet.max_row+1):
payment = sheet.cell(row=r,column=lastCol).value
if payment != "Paid":
name = sheet.cell(row=r, column=1).value
email = sheet.cell(row=r, column=2).value
unpaidMembers[name] = email
smtpObj = smtplib.SMTP("smtp.gmail.com",587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login("example#gmail.com", sys.argv[1])
for name, email in unpaidMembers.items():
body = "Subject: Dues Unpaid\nDear %s, \n\nThis is test"%(name)
print ("Sending email to %s...." %email)
sendmailstatus = smtpObj.sendmail("example#gmail.com",email, body)
if sendmailstatus != {}:
print ("There was a problem sending email to %s; %s" %(email, sendmailstatus))
smtpObj.quit()

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.

Automating email delivery

I took an example of automation from a book (Automate tasks with Python) which consists of opening and reading a spreadsheet and checking if the fee has been paid, if not, send an email to the client informing him. But when I run the code it doesn't show any error, but also, nothing happens. I would appreciate it if you could help me, and still recommend a library to carry out the process, if necessary.
Follow the code below:
import openpyxl, smtplib, sys
wb = openpyxl.load_workbook('C:/temp/cobranca.xlsx')
sheet = wb['Sheet1']
lastCol = sheet.max_column
latestMonth = sheet.cell(row=1, column=lastCol).value
unpaidMembers = {}
for r in range(2, sheet.max_row + 1):
payment = sheet.cell(row=r, column=lastCol).value
if payment != 'ok':
name = sheet.cell(row=r, column=1).value
email = sheet.cell(row=r, column=2).value
unpaidMembers[name] = email
smtpObj = smtplib.SMTP('mail.omnia.net.br', 465)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('dp.contabil#omnia.net.br', sys.argv[1])
for name, email in unpaidMembers.items():
body = "Subject: %s dues unpaid. \n Dear %s, \n Records show that you have not paid dues for %s. Please make this payment as soon as possible. Thank you!'" % (latestMonth, name, latestMonth)
print('Sending email to %s...' % email)
sendmailStatus = smtpObj.sendmail('dp.contabil#omnia.net.br', email, body)
if sendmailStatus != {}:
print('There was a problem sendind email to %s: %s' % (email, sendmailStatus))
smtpObj.quit()
Here is an example which I used:
import smtplib
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
MY_ADDRESS = 'XYZ#gmail.com'
PASSWORD = 'YourPassword'
def get_contacts(filename):
names = []
emails = []
with open(filename, mode='r', encoding='utf-8') as contacts_file:
for a_contact in contacts_file:
names.append(a_contact.split()[0])
emails.append(a_contact.split()[1])
return names, emails
def read_template(filename):
with open(filename, 'r', encoding='utf-8') as template_file:
template_file_content = template_file.read()
return Template(template_file_content)
def main():
names, emails = get_contacts('C:/Users/xyz/Desktop/mycontacts.txt') # read contacts
message_template = read_template('C:/Users/xyz/Desktop/message.txt')
s = smtplib.SMTP(host='smtp.gmail.com', port=587)
s.starttls()
s.login(MY_ADDRESS, PASSWORD)
for name, email in zip(names, emails):
msg = MIMEMultipart() # create a message
message = message_template.substitute(PERSON_NAME=name.title())
print(message)
msg['From'] = MY_ADDRESS
msg['To'] = email
msg['Subject'] = "Sending mail to all"
msg.attach(MIMEText(message, 'plain'))
s.send_message(msg)
del msg
s.quit()
if __name__ == '__main__':
main()

Python/smtplib - automation for sending email

I am developing an application to automate the sending of emails from the collection department where I work. It consists of accessing an excel spreadsheet, reading the column that is missing the payment and sending an automatic email to the customer. The code works, but it sends the email only to the last person who did not make the payment and not to everyone. can you help me? Follow the code below:
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
from datetime import date
import openpyxl
wb = openpyxl.load_workbook('C:/temp/cobranca.xlsx')
sheet = wb['Sheet1']
lastCol = sheet.max_column
latestMonth = sheet.cell(row=1, column=lastCol).value
unpaidMembers = {}
for r in range(2, sheet.max_row + 1):
payment = sheet.cell(row=r, column=lastCol).value
if payment != 'ok':
name = sheet.cell(row=r, column=1).value
email = sheet.cell(row=r, column=2).value
unpaidMembers[name] = email
print(unpaidMembers)
# create message object instance
msg = MIMEMultipart()
# setup the parameters of the message
password = "example"
msg['From'] = "example#example.com"
msg['To'] = email
msg['Subject'] = "%s - Honorário em aberto." % (name)
for name, email in unpaidMembers.items():
body = "Prezado(a) %s. \n \n Em nosso sistema consta, em sua conta, o honorário referente ao mês %s/2020 em aberto, pedimos sua regularização imediata. \n \n Caso o pagamento já tenha sido efetuado, por favor, desconsidere este e-mail. \n \n \n Att, \n OMNIA Tecnologia" % (
name, latestMonth)
print('Sending email to %s...' % email)
# add in the message body
msg.attach(MIMEText(body))
# create server
server = smtplib.SMTP('stmp.example.net', 587)
server.starttls()
# Login Credentials for sending the mail
server.login(msg['From'], password)
# send the message via the server.
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()
print("successfully sent email to %s:" % (msg['To']))
msg['To'] can be given a list of email addresses. Possibly making a list as shown below is an option.
email=[]
unpaidMembers = {}
for r in range(2, sheet.max_row + 1):
payment = sheet.cell(row=r, column=lastCol).value
if payment != 'ok':
name = sheet.cell(row=r, column=1).value
email.append(sheet.cell(row=r, column=2).value)
unpaidMembers[name] = email
print(unpaidMembers)
then
msg['To'] = email

Python loop not running

can anyone help me fix the following code? After the question is asked, and when I reply "yes", the rest of the program doesn't run. No emails are sent.
Note that I've replaced the login data with 'example' just for this question. The actual code has valid login details
Edited the variable from "x" to "answer"
combo = open("combo.txt", "r")
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
count = str(len(combo.readlines( )))
print ("There are " + count + " amount of combos")
answer = input("Would you like to run this program?: ")
for line in combo:
pieces = line.split(":")
email = pieces[0]
password = pieces[1]
if answer == "yes":
msg = MIMEMultipart()
message = "Dear user, your Spotify account has been hacked\n" + "Your spotify email is: " + email + ", and your password is: " +password + "\n Please change your password ASAP"
passwordEmail = "example"
msg['From'] = "example#gmail.com"
msg['To'] = email
msg['Subject'] = "Spotify Account Hacked"
msg.attach(MIMEText(message, 'plain'))
server = smtplib.SMTP('smtp.gmail.com: 587')
server.starttls()
server.login(msg['From'], passwordEmail)
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()
As pointed out by #Robin Zigmond, you haven't declared x yet.
A useful thing whilst debugging code that is evidently not functioning, I always find, is to use print statements to check what I believe to be true. In this case, you could check immediately before the if statement by doing print(x), to see what the value was - that would have highlighted that the variable didn't exist.

SMTP sent mail to many recipients but doesn't received it

I've written a Python script to automatically send some information to my friends. I used SMTPlib, it works well if I only sent to me or one additional email.
When I try to send to 17 emails, (including my sender email), then it shows in sent mail on web-based Gmail. I saw that the mail was sent but I didn't receive it. Only the first recipient received the email.
If I reply to all from that mail, then everyone got only that reply.
I can't figure out why they didn't receive it when I sent it from script, I ask my friend check spam, but she didn't find anything.
This is my code:
#!/usr/bin/env python
import smtplib
import csv
from datetime import datetime, timedelta
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
sender = 'MYBOT#gmail.com'
password = None
with open('pass', 'rt') as f:
password = f.read().strip('\n')
def send_mail(recipient, subject, body):
"""
Send happy bithday mail
"""
headers = ["From: " + sender,
"Subject: " + subject,
"To: " + recipient,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
smtp = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
smtp.ehlo()
smtp.starttls()
smtp.ehlo
smtp.login(sender, password)
body = "" + body +""
smtp.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
print "Sent to ",
print recipient
smtp.quit()
def send_happybirthday(recipient):
body = """Happy birthday to you!
\n<br/>From C2k8pro with love
"""
subject ='[BirthReminder] Happy birthday to you! from C2k8pro'
send_mail(recipient, subject, body)
def send_notification(all_mails, names):
body = """Tomorrow is birthday of %s""" % names
send_mail(all_mails, body, body)
def test_send_mail():
notify_body = """Tomorrow is birthday of """
recipients = ['MYBOT#gmail.com']
today = datetime.now()
format = "%d-%m-%Y"
print today
today_in_str = datetime.strftime(today, format)
def read_csv():
FILENAME = 'mails.csv'
reader = csv.reader(open(FILENAME, 'rt'), delimiter=',')
today = datetime.now()
one_day = timedelta(days=1)
tomorrow = today + one_day
all_mails = []
str_format = "%d/%m"
str_today = today.strftime(str_format)
str_tomorrow = tomorrow.strftime(str_format)
print 'Today is ', str_today
tomorrow_birth = []
for row in reader:
name = row[1].strip()
dob = row[2]
dmy = dob.split("/")
mail = row[3]
all_mails.append(mail)
#TODO fix dob with only 1 digit
birth_date = dmy[0] + "/" + dmy[1]
if str_today == birth_date:
print 'Happy birthday %s' % name
try:
send_happybirthday(mail)
except Exception, e:
print e
elif str_tomorrow == birth_date:
tomorrow_birth.append(name)
print "Tomorrow is %s's birthday" % name
# Remove empty string
all_mails = filter(None, all_mails)
print 'All mails: ', len(all_mails)
str_all_mails = ', '.join(all_mails)
if tomorrow_birth:
all_tomorrow = ', '.join(tomorrow_birth)
send_notification(str_all_mails, all_tomorrow)
def main():
read_csv()
if __name__ == "__main__":
main()
Can anyone explain this. Thanks!
I found solution from here
Send Email to multiple recipients from .txt file with Python smtplib
I passed a string contain all recipients separated by comma to msg['To'] and sendmail().
It's true for msg['To'] but with sendmail, I have to use a list.

Categories