Thomas Varano
Thomas Varano

Reputation: 33

base64 encoding not taking mime message

I am trying to send an oauth gmail using python and am not able to create MimeMessages that agree with Google's API. After creating a sample message, I use base64 to encode it as a string. However, I come up with the error: TypeError: a bytes-like object is required, not 'str'

The line at the top of the stack:

return {'raw': base64.urlsafe_b64encode(message_str)}

I've tried using different versions of encoding (encoders.encode_base64(message), message.as_string().encode("utf-8"), etc.) and have tried converting the message.as_string() to bytes (as the error message suggests) but am met with different error messages from Google, saying the encoding doesn't meet their requirements, which are "MIME email messages compliant with RFC 2822 and encoded as base64url strings."

My entire function is as follows.

def create_message(sender, to, subject, message_text):

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

I have no idea why this shouldn't work. It is copy-pasted from the tutorial. I am running python 3.7.2

Upvotes: 0

Views: 982

Answers (2)

tylerlindell
tylerlindell

Reputation: 1563

based on the answer here, you could use:

'string'.as_bytes()

Not sure why gmail api docs have this error in their code but this is how I got it to work. (possibly, they are referring to python 2)


To put this answer in context of your specific question, I did this:

def create_message(sender, to, subject, message_text):

    message = MIMEText(message_text)
    message['To'] = to
    message['From'] = sender
    message['Subject'] = subject
    message_bytes = message.as_bytes()
    return {'raw': base64.urlsafe_b64encode(message_bytes).decode('ascii')}

I used decode('ascii') here because the result from this will need to be a json string and bytes cannot be serialized. You are likely to get an error such as TypeError: Object of type bytes is not JSON serializable otherwise.

Upvotes: 1

Thomas Varano
Thomas Varano

Reputation: 33

For anyone who has this problem later, this seemed to work

raw = base64.urlsafe_b64encode(message.as_bytes())
raw = raw.decode()
return {'raw': raw}

Upvotes: 1

Related Questions