First of all, in Python 2 there is no problem.
In trying to send a message with a service instance (as in this example), by
service.users().messages().send('me', message)
it requires message to be in bytes format, which it tries to serialize with json.dumps. However, in Python 3 this is not possible.
To reproduce run this gist in python2 and python3.
I currently don't know what the solution to this would be.
Can you give the full stacktrace?
python new.py --noauth_local_webserver
Traceback (most recent call last):
File "new.py", line 92, in <module>
send_message(message)
File "new.py", line 82, in send_message
message = service.users().messages().send(userId='me', body=message).execute()
File "/Users/basnijholt/anaconda/lib/python3.5/site-packages/googleapiclient/discovery.py", line 764, in method
actual_path_params, actual_query_params, body_value)
File "/Users/basnijholt/anaconda/lib/python3.5/site-packages/googleapiclient/model.py", line 151, in request
body_value = self.serialize(body_value)
File "/Users/basnijholt/anaconda/lib/python3.5/site-packages/googleapiclient/model.py", line 260, in serialize
return json.dumps(body_value)
File "/Users/basnijholt/anaconda/lib/python3.5/json/__init__.py", line 230, in dumps
return _default_encoder.encode(obj)
File "/Users/basnijholt/anaconda/lib/python3.5/json/encoder.py", line 198, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Users/basnijholt/anaconda/lib/python3.5/json/encoder.py", line 256, in iterencode
return _iterencode(o, 0)
File "/Users/basnijholt/anaconda/lib/python3.5/json/encoder.py", line 179, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: b'Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJ1cy1hc2NpaSIKTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogN2JpdAp0bzogYmFzbmlqaG9sdEBnbWFpbC5jb20KZnJvbTogYmFzbmlqaG9sdEBnbWFpbC5jb20Kc3ViamVjdDogVGVzdAoKVGV4dA==' is not JSON serializable
you can probably just do message = message.decode('utf-8') and be fine.
@jonparrott indeed!
This works:
base64.urlsafe_b64encode(message.as_string().encode('utf-8')).decode('utf-8')
I ran into this as well, and google is erroring for me.
Trace:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/my/amazing/path", line 36, in _send_message
message = (self.service.users().messages().send(userId=email, body=body)
File "/path/to/venv/python3.8/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper
return wrapped(*args, **kwargs)
File "/path/to/venv/python3.8/site-packages/googleapiclient/http.py", line 907, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://www.googleapis.com/gmail/v1/users/email%40gmail.com/messages/send?alt=json returned "Bad Request">
Relevant code:
userID = 'my email'
message = MIMEMultipart('alternative')
message['to'] = to
message['from'] = sender
message['subject'] = subject
part1 = MIMEText(message_text, 'plain')
part2 = MIMEText(message_html, 'html')
message.attach(part1)
message.attach(part2)
body = {'raw': base64.urlsafe_b64encode(message.as_string().encode('utf-8')).decode('utf-8')}
self.service.users().messages().send(userId=userID, body=body).execute()
Most helpful comment
@jonparrott indeed!
This works: