10

I'm having big time problems with this issue-- another question on SO that didn't solve it is here: Send Raw Email (with attachment) to Multiple Recipients

My code (that works) is simple:

def send_amazon_email_with_attachment(html, subject, now, pre):
    dummy = 'test@example.com'
    recipients = ['test1@exampl.ecom', 'test2@example.com', 'test3@example.com']
    connS3 = S3Connection('IDENTIFICATION','PASSWORD')
    b = connS3.get_bucket('BUCKET_NAME')
    key = b.get_key('FILE_NAME.pdf')
    temp = key.get_contents_as_string()

    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    msg['From'] = 'My Name <test@example.com>'        

    msg.preamble = 'Multipart message.\n'

    part1 = MIMEText(u"Attached is the report", 'plain')
    part2 = MIMEText(html, 'html')

    msg.attach(part1)
    msg.attach(part2)

    part = MIMEApplication(temp) #read binary
    part.add_header('Content-Disposition', 'attachment', filename='FILE_NAME.pdf')
    msg.attach(part)

    conn = boto.ses.connect_to_region('us-east-1', aws_access_key_id='AUTH_ID', aws_secret_access_key='AUTH_PW')
    for recipient in recipients:
        print recipient
        msg['To'] = recipient

        result = conn.send_raw_email(msg.as_string(), source=msg['From'], destinations=recipient)

but, there's a caveat... this is looping for each recipient. Any variation of this does not work. Passing a list to msg['Bcc'] or msg['BCC'] will return an error that the list can't be stripped (same exact error as the posted question). Passing a string separated by commas gives an Amazon SES issue saying 'Illegal Email' in the returned XML. Because I only get an error from Amazon in specific situations, I'm led to believe this is an error with the program before it hits their API call.

Any MIMEMultipart experts have some ideas?

Community
  • 1
  • 1
Jared
  • 3,651
  • 11
  • 39
  • 64
  • I believe what you're asking should be possible, though I don't have time to put together a full example at the moment. Check out how the django-ses package [implements send_messages()](https://github.com/hmarr/django-ses/blob/master/django_ses/__init__.py#L157) which is able to quickly send messages to long lists of recipients. Edit: actually, maybe not -- I see that send_messages() there is in fact looping over the list of email_messages. – Josh Kupershmidt Apr 15 '15 at 21:00
  • 3
    You can send to multiple recipients if you list the 'cc' and 'bcc' recipients with the 'to' recipient. See http://stackoverflow.com/questions/9974972/mails-not-being-sent-to-people-in-cc – Ayush Apr 15 '15 at 21:01
  • "now" seem to have no use? – nights Nov 27 '18 at 03:43

2 Answers2

20

Basically you need to specify the email recipients in 2 different places using 2 different formats.

def send_amazon_email_with_attachment(html, subject, now, pre):
    dummy = 'test@example.com'
    recipients = ['test1@exampl.ecom', 'test2@example.com', 'test3@example.com']
    connS3 = S3Connection('IDENTIFICATION','PASSWORD')
    b = connS3.get_bucket('BUCKET_NAME')
    key = b.get_key('FILE_NAME.pdf')
    temp = key.get_contents_as_string()

    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    msg['From'] = 'My Name <test@example.com>' 
    msg['To'] = ', '.join(recipients)


    msg.preamble = 'Multipart message.\n'

    part1 = MIMEText(u"Attached is the report", 'plain')
    part2 = MIMEText(html, 'html')

    msg.attach(part1)
    msg.attach(part2)

    part = MIMEApplication(temp) #read binary
    part.add_header('Content-Disposition', 'attachment', filename='FILE_NAME.pdf')
    msg.attach(part)

    conn = boto.ses.connect_to_region('us-east-1', aws_access_key_id='AUTH_ID', aws_secret_access_key='AUTH_PW')


    result = conn.send_raw_email(msg.as_string(), source=msg['From'], destinations=recipients)
  • 1
    This is redundant as well as confusing. Has anybody figured out why it is this way? – Anomitra Nov 12 '19 at 13:24
  • It's explained in the documentation: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ses.html#SES.Client.send_raw_email – jhuamanchumo Nov 17 '20 at 06:33
0

msg['To'] = ', '.join(recipients) isn't working for me (throws encoding error). Simply comment that line and your 'destinations' in "send_raw_email" should contain a list. That will work like a charm.