From the Gmail API's developer guide:
The following code sample demonstrates creating a MIME message, encoding to a base64url string, and assigning it to the raw field of the Message resource:
def create_message(sender, to, subject, message_text):
"""Create a message for an email.
Args:
sender: Email address of the sender.
to: Email address of the receiver.
subject: The subject of the email message.
message_text: The text of the email message.
Returns:
An object containing a base64url encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_string())}
But if I do something like
from email.MIMEText import MIMEText
import base64
message = MIMEText('This is a test')
message['to'] = '[email protected]'
message['from'] = '[email protected]'
message['subject'] = 'Test'
body = {'raw': base64.urlsafe_b64encode(message.as_string())}
I get TypeError: a bytes-like object is required, not 'str'
If instead I do:
body = {'raw': base64.urlsafe_b64encode(message.as_bytes())}
message = (service.users().messages().send(userId='me', body=body)
.execute())
I get the following traceback about some binary not being json serializable:
~/env/lib/python3.5/site-packages/googleapiclient/discovery.py in method(self, **kwargs)
792 headers = {}
793 headers, params, query, body = model.request(headers,
--> 794 actual_path_params, actual_query_params, body_value)
795
796 expanded_url = uritemplate.expand(pathUrl, params)
~/env/lib/python3.5/site-packages/googleapiclient/model.py in request(self, headers, path_params, query_params, body_value)
149 if body_value is not None:
150 headers['content-type'] = self.content_type
--> 151 body_value = self.serialize(body_value)
152 self._log_request(headers, path_params, query, body_value)
153 return (headers, path_params, query, body_value)
~/env/lib/python3.5/site-packages/googleapiclient/model.py in serialize(self, body_value)
258 self._data_wrapper):
259 body_value = {'data': body_value}
--> 260 return json.dumps(body_value)
261
262 def deserialize(self, content):
/usr/lib/python3.5/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
228 cls is None and indent is None and separators is None and
229 default is None and not sort_keys and not kw):
--> 230 return _default_encoder.encode(obj)
231 if cls is None:
232 cls = JSONEncoder
/usr/lib/python3.5/json/encoder.py in encode(self, o)
196 # exceptions aren't as detailed. The list call should be roughly
197 # equivalent to the PySequence_Fast that ''.join() would do.
--> 198 chunks = self.iterencode(o, _one_shot=True)
199 if not isinstance(chunks, (list, tuple)):
200 chunks = list(chunks)
/usr/lib/python3.5/json/encoder.py in iterencode(self, o, _one_shot)
254 self.key_separator, self.item_separator, self.sort_keys,
255 self.skipkeys, _one_shot)
--> 256 return _iterencode(o, 0)
257
258 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
/usr/lib/python3.5/json/encoder.py in default(self, o)
177
178 """
--> 179 raise TypeError(repr(o) + " is not JSON serializable")
180
181 def encode(self, o):
TypeError: b'Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJ1cy1hc2NpaSIKTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogN2JpdApGcm9tOiBUZXN0IFB5dGhvbgpUbzogcmFwaGFlbC5hLmR1bWFzQGdtYWlsLmNvbQpTdWJqZWN0OiBQbGVhc2Ugc3RheSBjYWxtLCB0aGlzIGlzIGEgdGVzdAoKVGhpcyBpcyBhIHRlc3Q=' is not JSON serializable
Hi @Anonymous , As I can find, base64 encoded images are not supported in Gmail (from years ago on). Hope this helps. If this post helps, then please consider Accept it as the solution to help the other members find it.
Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. The term Base64 originates from a specific MIME content transfer encoding.
Anything that you paste or enter in the text area on the left automatically gets encoded to base64 on the right. It supports the most popular Unicode encodings (such as UTF-8, UTF-16, UCS-2, UTF-32, and UCS-4) and it works with emoji characters.
Try:
b64_bytes = base64.urlsafe_b64encode(message.as_bytes())
b64_string = b64_bytes.decode()
body = {'raw': b64_string}
base64.urlsafe_b64encode
returns a bytes object (see docs) so you need to convert the output to a string before serialising it as JSON.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With