TypeError with base64 encoding in Gmail API - expecting bytes but getting string

I’m working on a Python script that uses the Gmail API to send emails automatically. However, I keep running into a TypeError that’s causing my program to crash. The error message says it needs a bytes object but I’m passing a string instead.

Here’s my code:

import googleapiclient.discovery
from httplib2 import Http
from oauth2client import file, client, tools
import base64
from email.mime.text import MIMEText
import os

def build_email_message(sender_email, recipient_email, email_subject, email_content):
    msg = MIMEText(email_content)
    msg['To'] = recipient_email
    msg['From'] = sender_email
    msg['Subject'] = email_subject
    
    return {'raw': base64.urlsafe_b64encode(msg.as_string().encode('utf-8'))}

def dispatch_email(gmail_service, user_account, email_message):
    result = gmail_service.users().messages().send(
        userId=user_account, 
        body=email_message
    ).execute()
    print(f'Email sent with ID: {result["id"]}')
    return result

def main_email_function(content_list):
    API_SCOPE = 'https://mail.google.com/'
    credential_store = file.Storage('token.json')
    credentials = credential_store.get()
    
    if not credentials or credentials.invalid:
        auth_flow = client.flow_from_clientsecrets('credentials.json', API_SCOPE)
        credentials = tools.run_flow(auth_flow, credential_store)
    
    gmail_service = googleapiclient.discovery.build(
        'gmail', 'v1', 
        http=credentials.authorize(Http())
    )
    
    email_body = content_list[0]
    prepared_message = build_email_message(
        '[email protected]',
        '[email protected]', 
        'Test Email Subject',
        email_body
    )
    dispatch_email(gmail_service, '[email protected]', prepared_message)

main_email_function(['Hello World'])

The error happens in the build_email_message function when I try to encode the message. It seems like the base64 function expects bytes but I’m giving it a string. How can I fix this issue?

Same thing happened to me last week! The base64 encoding spits out bytes, but Gmail’s API wants a string. Just tack .decode() onto your base64 line - base64.urlsafe_b64encode(msg.as_string().encode('utf-8')).decode() works perfectly. You’re encoding to bytes then decoding back to string for the API.

Had this exact problem when I started using Gmail API. The issue is base64.urlsafe_b64encode() returns bytes, but Gmail API wants the ‘raw’ field as a string. You need to decode those bytes back to a string after encoding. Fix your return statement in build_email_message like this: python return {'raw': base64.urlsafe_b64encode(msg.as_string().encode('utf-8')).decode('utf-8')} That .decode('utf-8') at the end converts the bytes back to a string Gmail API can handle. Tripped me up too since the docs don’t really explain this step clearly, but adding the decode fixes everything.

Yeah, this is a classic Gmail API encoding issue. The problem is base64.urlsafe_b64encode() returns bytes, but Gmail’s raw field wants a string. I hit the exact same thing when switching from an older email library. Your encoding works fine until the base64 step - you just need to convert it back to a string. Change your return to: return {'raw': base64.urlsafe_b64encode(msg.as_string().encode('utf-8')).decode('ascii')}. That .decode('ascii') at the end does the trick. I use ascii instead of utf-8 for the final decode since base64 is always ASCII-compatible anyway. Works every time across different Python versions.