12

I'm having some trouble sending a message to multiple addresses using the Gmail API. I've successfully sent a message to only one address, but get the following error when I include multiple comma-separated addresses in the 'To' field:

An error occurred: <HttpError 400 when requesting
https://www.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Invalid to header">

I'm using the CreateMessage and SendMessage methods from this Gmail API guide: https://developers.google.com/gmail/api/guides/sending

That guide states that the Gmail API requires messages that are RFC-2822 compliant. I again didn't have much luck using some of these addressing examples in the RFC-2822 guide: https://www.rfc-editor.org/rfc/rfc2822#appendix-A

I'm under the impression that 'mary@x.test, jdoe@example.org, one@y.test' should be a valid string to pass into the 'to' parameter of CreateMessage, but the error that I received from SendMessage leads me to believe otherwise.

Please let me know if you can recreate this problem, or if you have any advice on where I may be making a mistake. Thank you!

Edit: Here is the actual code that yields an error...

def CreateMessage(sender, to, subject, message_text):
    message = MIMEText(message_text)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    return {'raw': base64.urlsafe_b64encode(message.as_string())}

def SendMessage(service, user_id, message):
    try:
        message = (service.users().messages().send(userId=user_id, body=message)
           .execute())
        print 'Message Id: %s' % message['id']
        return message
    except errors.HttpError, error:
        print 'An error occurred: %s' % error

def ComposeEmail():
    # build gmail_service object using oauth credentials...
    to_addr = 'Mary Smith <mary@x.test>, jdoe@example.org, Who? <60one@y.test>'
    from_addr = 'me@address.com'
    message = CreateMessage(from_addr,to_addr,'subject text','message body')
    message = SendMessage(gmail_service,'me',message)
Community
  • 1
  • 1
Jordan Hawkins
  • 141
  • 1
  • 8
  • Have you tried passing the addresses as a list? Can you provide a example of your code that works for one recipient? – mnjeremiah Aug 22 '14 at 02:18
  • Yes, I tried passing the addresses as a list, but got the same result. I edited my post and included my code. Please let me know if you would like me to provide any more context. – Jordan Hawkins Aug 22 '14 at 04:29
  • I fiddled around with this for a while today, as I'm also building an app that will need to send out emails. I wasn't able to find anything in the documents that covered it. It made me wonder if that's how it's even supposed to be done or if I'm supposed to loop through the recipients and send the emails one at a time kind of a thing. If you figure it out I'd be interested in the answer too. Best of luck. :) – mnjeremiah Aug 22 '14 at 19:25
  • 1
    The API is just broken. It's in beta. I spent all day trying to figure out what was wrong with my to field, read through the rfc2822 docs, and there was nothing wrong. Ended up switching back to SMTP and all is fine and good with the world again. Bummer though. – James Aug 22 '14 at 21:46

3 Answers3

2

Getting "Invalid to header" when sending with multiple recipients (comma delimited) in a single header was a regression that was fixed on 2014-08-25.

Eric D
  • 6,901
  • 1
  • 15
  • 26
1

As James says in its comment, you shouldn't waste time trying to use Gmail API when Python has excellent documented support for using SMTP : email module can compose message including attachements, and smtplib sends them. IMHO you could use Gmail API for what works out of the box but should use the robust modules form Python Standard Library when things go wrong.

It looks like you want to send a text only message : here is a solution adapted from the email module documentation and How to send email in Python via SMTPLIB from Mkyong.com:

# Import smtplib for the actual sending function
import smtplib

# Import the email modules we'll need
from email.mime.text import MIMEText

msg = MIMEText('message body')
msg['Subject'] = 'subject text'
msg['From'] = 'me@address.com'
msg['To'] = 'Mary Smith <mary@x.test>, jdoe@example.org, "Who?" <60one@y.test>'

# Send the message via Gmail SMTP server.
gmail_user = 'youruser@gmail.com'
gmail_pwd = 'yourpassword'smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver = smtplib.SMTP('smtp.gmail.com')smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
smtpserver.login(gmail_user, gmail_pwd)
smtpserver.send_message(msg)
smtpserver.quit()
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thank you for the helpful info! My application does not acquire the user's password, but otherwise this answer would have been a useful workaround if the Gmail API had not been fixed. I up-voted your response so that others will know how to proceed if/when the Gmail API's out-of-the-box functionality fails to meet their needs. – Jordan Hawkins Aug 25 '14 at 15:36
  • The python email module is great and I would definitely recommend using it. smtplib may work as well for some users (if you can make SMTP connections in your environment) but not others. For a script on a server may be fine, for a browser extension maybe not... – Eric D Aug 25 '14 at 16:15
  • @EricDeFriez I really cannot understand your comment : I use email module for what it can do, composing the email message. And I use smtplib for what it can do and email module cannot : sending the message. – Serge Ballesta Aug 26 '14 at 07:02
  • The email module is great, it's great for composing emails (creating the RFC822 formatted string) and parsing them. smtplib is good if you can make raw TCP connections to an smtp server, many environments don't allow that such as: browsers, cloud platforms and home/hosted providers that block outbound port 25 due to spamming concerns. – Eric D Aug 26 '14 at 15:55
  • That's the reason why in my example I use port 587 wich is reserved for client authenticated SMTP with security provided via starttls. This port is normally not blocked by providers and is the correct way to configure SMTP clients (Thunderbird, etc.) when you use them on public networks. What would you propose as an alternative for *sending* mail ? – Serge Ballesta Aug 26 '14 at 16:34
0

See also User.drafts reference - error"Invalid to header"

Apparently this bug was recently introduced in Gmail API.