Mails not being sent to people in CC - python

I have the following script for sending mails using python
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import os
FROMADDR = "myaddr#server.com"
PASSWORD = 'foo'
TOADDR = ['toaddr1#server.com', 'toaddr2#server.com']
CCADDR = ['ccaddr1#server.com', 'ccaddr2#server.com']
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = 'Test'
msg['From'] = FROMADDR
msg['To'] = ', '.join(TOADDR)
msg['Cc'] = ', '.join(CCADDR)
# Create the body of the message (an HTML version).
text = """Hi this is the body
"""
# Record the MIME types of both parts - text/plain and text/html.
body = MIMEText(text, 'plain')
# Attach parts into message container.
msg.attach(body)
# Send the message via local SMTP server.
s = smtplib.SMTP('server.com', 587)
s.set_debuglevel(1)
s.ehlo()
s.starttls()
s.login(FROMADDR, PASSWORD)
s.sendmail(FROMADDR, TOADDR, msg.as_string())
s.quit()
When I use the script, I see that the mail gets delivered to both toaddr1 and toadd2
However ccaddr1 and ccaddr2 does not receive the mail at all.
Interestingly, when I check the mails received by toaddr1 and toadd2, it shows that
ccaddr1 and ccaddr2 are present in CC.
Is there any error in the script? Initially I thought that this might be an issue with my mail server. I tried it with Gmail and saw the same result. That is, no matter whether its an account in my current mail server or my Gmail account in the CC, the recipient will not receive the mail, even though the people in the 'To' field receive it properly and have the correct addresses mentioned in the CC field

I think that you will need to put the CCADDR with the TOADDR when sending the mail:
s.sendmail(FROMADDR, TOADDR+CCADDR, msg.as_string())
You're correctly adding the addresses to your message, but you will need the cc addresses on the envelope too.
From the docs:
Note The from_addr and to_addrs parameters are used to construct the message envelope used by the transport agents.

You specified the CC entries in the message, but not in the envelope. It's your job to make sure that the message is also sent to the CC and BCC entries.

I got below error with TOADDR+CCADDR =>
TypeError: can only concatenate str (not "list") to str
I did below changes and it worked for me.
It sends email with attachment to - "To", "Cc" & "Bcc" successfully.
toaddr = ['mailid_1','mailid_2']
cc = ['mailid_3','mailid_4']
bcc = ['mailid_5','mailid_6']
subject = 'Email from Python Code'
fromaddr = 'sender_mailid'
message = "\n !! Hello... !!"
msg['From'] = fromaddr
msg['To'] = ', '.join(toaddr)
msg['Cc'] = ', '.join(cc)
msg['Bcc'] = ', '.join(bcc)
msg['Subject'] = subject
s.sendmail(fromaddr, (toaddr+cc+bcc) , message)

Related

Sending an Email from a python script without a from address

So I have seen lots of great info on here about sending automated emails using python. However, my task is slightly different. The script im working on needs to send an automated email when some condition is true then the email contains the printed output. But since this is for work the file is stored on a shared server and therefore, I cannot be the one to "send" the email, it needs to send automatically from the file. My question is therefore how this email can be sent with no "from" address, or if this is even possible.
Additionally, how can I make sure that the email contains the printed output? Below is the attached code im using. The variables stored in the list are dataframes.
mylist = [right_branchcode, right_branchname, right_sellingcode, right_advcorp, right_childparent, \
right_eliteCategoryId, right_partyid, right_retailmga]
flag = True
for item in mylist:
if len(item) > 0:
print(item)
flag = True
else:
pass
def send_email(audit):
fromaddr = " >"
toaddr = "recip#mail, recip2#mail"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "Alert: Audit Mismatch For DimAdvisor"
body = "Current mismatch in dimAdvisor found on : " + temperature
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp-mail.outlook.com', 587)
server.starttls()
server.login(fromaddr, "password")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
Any help would be great. Thanks!
This is how you can send email using Python:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
recipients = ['john.doe#example.com', 'john.smith#example.co.uk']
msg = MIMEMultipart()
msg['From'] = "Can be any string you want, use ASCII chars only " # sender name
msg['To'] = ", ".join(recipients) # for one recipient just enter a valid email address
msg['Subject'] = "Subject"
body = "message body"
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587) # put your relevant SMTP here
server.ehlo()
server.starttls()
server.ehlo()
server.login('jhon#gmail.com', '1234567890') # use your real gmail account user name and password
server.send_message(msg)
server.quit()
Please note this line:
msg['From'] = "Can be any string you want, use ASCII chars only " # sender name
You can write any string in the From field regardless of any real email address. I didn't try to leave it empty but I guess you can try it yourself :-)

How to send emails programmatically and hide the sender address?

I would like to send mail notifications to my customers via python. The problem is the sender mail account needs to be hidden. Just to be clear - this is not for phishing or spamming, only personal use!
I used smtplib and setup a new 'noreply' account in gmail, but even when providing an alias to the message, the 'mail from:' header contains my actual mail.
import smtplib
from email.mime.text import MIMEText
from email.utils import *
email_sender = 'noreply%%#gmail.com'
email_receiver = 'example%%%#gmail.com'
subject = 'Python!'
msg = MIMEText('This is the body of the message.')
msg['To'] = formataddr(('Recipient', 'example%%%#gmail.com'))
msg['From'] = formataddr(('Author', 'author#example.com'))
msg['Subject'] = 'Simple test message'
connection = smtplib.SMTP('smtp.gmail.com', 587)
connection.starttls()
connection.login(email_sender, 'password')
connection.sendmail(msg['From'], email_receiver, msg.as_string())
connection.quit()
I get the mail in to my inbox as expected but when clicking 'more details' the original sender address appears.
The first argument to sendmail is the envelope sender, and should be just the email terminus, not a formatted address; so passing in msg['From'] there is doubly wrong (one, because you don't want to show it; and two, because you are passing in the entire From: header with display name and all).

Outlook stops working after running python email sending script?

I wrote a script to send an email using python. The script worked and the recipient received an email. However, I kept myself in CC and I didn't get an email and moreover, my outlook stopped working after that.
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
def success_email():
sender = 'abhishek_talwar#xyz.com'
recipients = 'GANA_PANGO#xyz.com'
CC = 'abhishek_talwar#xyz.com'
subject = "Load Balance Request Completed"
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = recipients
msg['CC'] = CC
# Create the body of the message (a plain-text and an HTML version).
text = 'Hi this is a test mail'
# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text.encode('utf-8'), 'html')
# Attach parts into message container.
msg.attach(part1)
s = smtplib.SMTP('mail1.xyz.com')
x =s.sendmail(sender, recipients, msg.as_string())
print x
action = 'Success email sent for'
print action
success_email()
You're not sending the email to the CC list. You're adding the address in the head of the message, but not on the envelop.
x =s.sendmail(sender, [recipients, CC], msg.as_string())

Python SMTPlib: Message sending in from header

In Python I'm attempting to send a message via SMTPlib. However, the message is always sending the entire message in the from header, and I have no idea how to fix it. It wasn't doing it before, but now it's always doing it. Here is my code:
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
def verify(email, verify_url):
msg = MIMEMultipart()
msg['From'] = 'pyhubverify#gmail.com\n'
msg['To'] = email + '\n'
msg['Subject'] = 'PyHub verification' + '\n'
body = """ Someone sent a PyHub verification email to this address! Here is the link:
www.xxxx.co/verify/{1}
Not you? Ignore this email.
""".format(email, verify_url)
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login('pyhubverify#gmail.com', 'xxxxxx')
print msg.as_string()
server.sendmail(msg['From'], [email], body)
server.close()
Is there anything wrong with it, and is there a way I can fix it?
This line is the issue:
server.sendmail(msg['From'], [email], body)
You could fix it with:
server.sendmail(msg['From'], [email], msg.as_string())
You were sending the body instead of the whole message; the SMTP protocol expects the message to start with the headers... hence you are seeing the body where the headers is supposed to be.
You also need to remove the newline characters. Per rfc2822 the line-feed characters are undesirable alone:
A message consists of header fields (collectively called "the header
of the message") followed, optionally, by a body. The header is a
sequence of lines of characters with special syntax as defined in
this standard. The body is simply a sequence of characters that
follows the header and is separated from the header by an empty line
(i.e., a line with nothing preceding the CRLF).
Please try the following:
msg = MIMEMultipart()
email = 'recipient#example.com'
verify_url = 'http://verify.example.com'
msg['From'] = 'pyhubverify#gmail.com'
msg['To'] = email
msg['Subject'] = 'PyHub verification'
body = """ Someone sent a PyHub verification email to this address! Here is the link:
www.xxxx.co/verify/{1}
Not you? Ignore this email.
""".format(email, verify_url)
msg.attach(MIMEText(body, 'plain'))
print msg.as_string()

How to send Gmail email with multiple CC:'s

I am looking for a quick example on how to send Gmail emails with multiple CC:'s. Could anyone suggest an example snippet?
I've rustled up a bit of code for you that shows how to connect to an SMTP server, construct an email (with a couple of addresses in the Cc field), and send it. Hopefully the liberal application of comments will make it easy to understand.
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
## The SMTP server details
smtp_server = "smtp.gmail.com"
smtp_port = 587
smtp_username = "username"
smtp_password = "password"
## The email details
from_address = "address1#domain.com"
to_address = "address2#domain.com"
cc_addresses = ["address3#domain.com", "address4#domain.com"]
msg_subject = "This is the subject of the email"
msg_body = """
This is some text for the email body.
"""
## Now we make the email
msg = MIMEText(msg_body) # Create a Message object with the body text
# Now add the headers
msg['Subject'] = msg_subject
msg['From'] = from_address
msg['To'] = to_address
msg['Cc'] = ', '.join(cc_addresses) # Comma separate multiple addresses
## Now we can connect to the server and send the email
s = SMTP_SSL(smtp_server, smtp_port) # Set up the connection to the SMTP server
try:
s.set_debuglevel(True) # It's nice to see what's going on
s.ehlo() # identify ourselves, prompting server for supported features
# If we can encrypt this session, do it
if s.has_extn('STARTTLS'):
s.starttls()
s.ehlo() # re-identify ourselves over TLS connection
s.login(smtp_username, smtp_password) # Login
# Send the email. Note we have to give sendmail() the message as a string
# rather than a message object, so we need to do msg.as_string()
s.sendmail(from_address, to_address, msg.as_string())
finally:
s.quit() # Close the connection
Here's the code above on pastie.org for easier reading
Regarding the specific question of multiple Cc addresses, as you can see in the code above, you need to use a comma separated string of email addresses, rather than a list.
If you want names as well as addresses you might as well use the email.utils.formataddr() function to help get them into the right format:
>>> from email.utils import formataddr
>>> addresses = [("John Doe", "john#domain.com"), ("Jane Doe", "jane#domain.com")]
>>> ', '.join([formataddr(address) for address in addresses])
'John Doe <john#domain.com>, Jane Doe <jane#domain.com>'
Hope this helps, let me know if you have any problems.
If you can use a library, I highly suggest http://libgmail.sourceforge.net/, I have used briefly in the past, and it is very easy to use. You must enable IMAP/POP3 in your gmail account in order to use this.
As for a code snippet (I haven't had a chance to try this, I will edit this if I can):
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
import os
#EDIT THE NEXT TWO LINES
gmail_user = "your_email#gmail.com"
gmail_pwd = "your_password"
def mail(to, subject, text, attach, cc):
msg = MIMEMultipart()
msg['From'] = gmail_user
msg['To'] = to
msg['Subject'] = subject
#THIS IS WHERE YOU PUT IN THE CC EMAILS
msg['Cc'] = cc
msg.attach(MIMEText(text))
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(attach, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition',
'attachment; filename="%s"' % os.path.basename(attach))
msg.attach(part)
mailServer = smtplib.SMTP("smtp.gmail.com", 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to, msg.as_string())
# Should be mailServer.quit(), but that crashes...
mailServer.close()
mail("some.person#some.address.com",
"Hello from python!",
"This is a email sent with python")
For the snippet I modified this

Categories