2

I am currently using Python 2.7 and trying to send a raw email with an attachment (CSV to be exact) to multiple addresses with Boto SES. I can send a normal email with send_email(), but I keep getting an error when trying to send to multiple people via send_raw_email().

This is the error that I get with a comma-separated string of recipients:

Error sending email: SESIllegalAddressError: 400 Illegal address
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
  <Error>
    <Type>Sender</Type>
    <Code>InvalidParameterValue</Code>
    <Message>Illegal address</Message>
  </Error>
  <RequestId>[the request ID]</RequestId>
</ErrorResponse>

That's from using this code:

to_emails = "me@example.com, them@example.com"

# create raw email
msg = MIMEMultipart()
msg['Subject'] = 'Email subject'
msg['From'] = 'me@example.com'
msg['To'] = to_emails

part = MIMEText('Attached is an important CSV')
msg.attach(part)

part = MIMEApplication(open(fname, 'rb').read())
part.add_header('Content-Disposition', 'attachment', filename=fname)
msg.attach(part)
# end create raw email

conn = boto.ses.connect_to_region(
    '[my region]',
    aws_access_key_id=s3_access_key, 
    aws_secret_access_key=s3_secret_key
    )
conn.send_raw_email(msg.as_string(),
    source=msg['From'],
    destinations=msg['To']
    )

Also, here is the error I get from using an array of strings for recipients:

Error sending email: 'list' object has no attribute 'lstrip'

It works fine if I have just one recipient, so it just throws the error when I have an array of recipients and a comma-separated string of recipients. Anyone have any experience with this?

Bryce
  • 248
  • 5
  • 16
  • I'm having this same issue. Can you take a look at your code and tell me if you pass `to_emails` to destinations or `msg['To']`? What is the difference between what you have here (creating an array) vs declaring it that way initially? – Jared Apr 15 '15 at 02:36

4 Answers4

5

I ended it getting it after looking at some docs and some more trial & error. It turns out that I just had to join the array of email strings for the msg['To'], and then I was able to pass in the email array for destinations parameter.

Here's what I did:

to_emails = "me@example.com, them@example.com"

COMMASPACE = ', '

# create raw email
msg = MIMEMultipart()
msg['Subject'] = 'Email subject'
msg['From'] = 'me@example.com'
msg['To'] = COMMASPACE.join(to_emails)  ## joined the array of email strings
# edit: didn't end up using this ^

part = MIMEText('Attached is an important CSV')
msg.attach(part)

part = MIMEApplication(open(fname, 'rb').read())
part.add_header('Content-Disposition', 'attachment', filename=fname)
msg.attach(part)
# end create raw email

conn = boto.ses.connect_to_region(
    '[my region]',
    aws_access_key_id=s3_access_key, 
    aws_secret_access_key=s3_secret_key
    )
conn.send_raw_email(msg.as_string(),
    source=msg['From'],
    destinations=to_emails  ## passed in an array
    )
Bryce
  • 248
  • 5
  • 16
  • I'm having this same issue. Can you take a look at your code and tell me if you pass `to_emails` to destinations or `msg['To']`? What is the difference between what you have here (creating an array) vs declaring it that way initially? – Jared Apr 15 '15 at 02:36
  • Good catch. In my final code, I actually didn't even end up using `msg['To']`, so `to_emails` is just a string of emails separated by commas. – Bryce Apr 16 '15 at 16:10
  • This didn't work for me and getting this error: Exception: An error occurred (InvalidParameterValue) when calling the SendRawEmail operation: Illegal address – Shankar Naru Jun 11 '20 at 18:14
2

I believe instead of a comma separated string with your recipients you have have to use a a list of strings.

Recipients = ['1@email.com', '2@email.com']

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

So something along those lines.

Source: http://boto.readthedocs.org/en/latest/ref/ses.html?highlight=send_raw_email#boto.ses.connection.SESConnection.send_raw_email

The official documentation says a list of strings or simply a string. This is why it works with only one recipient.

Second attempt::

to_emails = ['me@example.com', 'them@example.com']

# create raw email
msg = MIMEMultipart()
msg['Subject'] = 'Email subject'
msg['From'] = 'me@example.com'
msg['To'] = to_emails


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

Am I right in assuming your code now looks like this? If not, try this.

Chronicler
  • 59
  • 3
  • I just tried that exact approach, and it gave me this error: `Error sending email: SESIllegalAddressError: 400 Illegal address Sender InvalidParameterValue Illegal address [the request ID] ` – Bryce Mar 18 '15 at 17:06
  • This didn't work for me and getting this error: Exception: An error occurred (InvalidParameterValue) when calling the SendRawEmail operation: Illegal address – Shankar Naru Jun 11 '20 at 18:14
1

The solution is set a string separated by comma to the header and a list to destinations field.

Something like:

to_emails = ['me@example.com', 'them@example.com']

msg['To'] = ', '.join( to_emails  ) 

and

...
conn.send_raw_email(msg.as_string(),
source=msg['From'],
destinations=to_emails  ## passed in an array
)
0

When sending without attachment just assigning list works. But in other case the below code helped..Thanks @Ezequiel Salas

to_emails = ['me@example.com', 'them@example.com']

or to_emails = some_list

msg['To'] = ', '.join( to_emails  )