0

I'm following the Gmail API guide link. I tried replacing as_string() to as_bytes() but that did not work either. What is the issue?

Traceback (most recent call last):
  File "gmail.py", line 38, in <module>
    message = create_message(sender, to, subject, message_text)
  File "gmail.py", line 20, in create_message
    return {'raw': base64.urlsafe_b64encode(message.as_string())}
  File "/usr/lib/python3.6/base64.py", line 118, in urlsafe_b64encode
    return b64encode(s).translate(_urlsafe_encode_translation)
  File "/usr/lib/python3.6/base64.py", line 58, in b64encode
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'

Here is my code,

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

import time

from datetime import datetime, timedelta
import math

# Ability to create the e-mail
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import base64
import os


def create_message(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 send_message(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:
        print ('An error occurred: %s' % error)

if __name__ == '__main__':
    sender = '<Your email id>'
    to = '<Your email id>'
    subject = 'API test'
    message_text = 'Hello World'

    message = create_message(sender, to, subject, message_text)
    creds = None
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('gmail', 'v1', credentials=creds)

    send_message(service, sender, message)
    print('success')

To recreate this you will need to set up a gmail account with gmail API following this

Thank you!

parth shukla
  • 107
  • 4
  • 11
  • base64.urlsafe_b64encode(message.as_string()) - that is the problem as one does _not_ “base64 encode a string”: base64(bytes) -> string. A minimal reproduction is then: base64.urlsafe_b64encode(“nope!”) - note the same error message, then work to resolve it, and _then_ put it back in context.. – user2864740 Jul 18 '20 at 07:24
  • Found the answer - [Link](https://stackoverflow.com/questions/43352496/gmail-api-error-from-code-sample-a-bytes-like-object-is-required-not-str?noredirect=1&lq=1) – parth shukla Jul 18 '20 at 07:48
  • Makes sense. string.encode() returns the bytes (per encoding) representing the characters.. – user2864740 Jul 18 '20 at 07:55

0 Answers0