abittar2022
abittar2022

Reputation: 15

Gmail API Connection

I have been trying to send a test email via the Gmail API configuration with little success. I am not sure what is wrong exactly, but the error I am receiving is as follows:

File "c:\Development\foodSaver\emailAPI.py", line 20, in send_message message = (service.users().messages().send(userId=user_id, body=message).execute()) AttributeError: 'str' object has no attribute 'users'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "c:\Development\foodSaver\emailAPI.py", line 28, in send_message('Gmail', 'Person','yes') File "c:\Development\foodSaver\emailAPI.py", line 23, in send_message except errors.HttpError as error: NameError: name 'errors' is not defined

I have put the Credentials.json file in the same directory as my project, but was never asked to reference it in this script.

The code I have so far (that is producing this error):

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

# Writes gmail message 
def create_message(sender, to, subject, message_text):
  message = MIMEText(message_text)
  message['to'] = to
  message['from'] = sender
  message['subject'] = subject
  message = message.as_string()
  message = message.encode('utf-8')
  return {'raw': base64.urlsafe_b64encode(message)}

# Sends gmail message 
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 as error:
    print('An error occurred: %s' % error)

create_message('[email protected]','[email protected]','This is a test email.','This is the test body message.')
send_message('Gmail', 'Person','yes')

For the last part I tried inputting random things for the def variables in order to test.

Upvotes: 0

Views: 486

Answers (1)

Nikko J.
Nikko J.

Reputation: 5533

The first and second errors occur when you pass the wrong arguments in your send_message function. The content of service should be resource object and the content of user_id should be an email or 'me'.

You need to create credentials and use it to construct a resource to interact with Gmail API. You can start by following this Python Quickstart for Gmail on how to setup your credentials and install necessary libraries. Once you're done with setup, your code should look like this:

Note: You can copy and paste the code and replace the sender and recipient email. Make sure that the content of credentials.json is on the same level as your main script. In my example below, I used this to obtain the content of credentials.json

from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from googleapiclient.errors import HttpError
from email.mime.text import MIMEText
import base64
import os

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.send']


# Writes gmail message
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().encode()).decode()}


# Sends gmail message
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 HttpError as error:
        print('An error occurred: %s' % error)


def main():
    """Shows basic usage of the Gmail API.
    Lists the user's Gmail labels.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    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.json', 'w') as token:
            token.write(creds.to_json())

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

    msg = create_message('sender email', 'recipient email', 'This is a test email.',
                         'This is the test body message.')
    send_message(service, 'me', msg)


if __name__ == '__main__':
    main()

Upvotes: 0

Related Questions