How To Read Email using GMAIL API for python

In the framework I am working on, I am using Gmail API to do some actions such as Read mail, extract the verification link, extract the temp password or security code …

This post will show you step by step how to integrate Gmail API into a python framework.

First, let’s check the document and library that you need to setup Gmail API:

Authorize Gmail API: https://developers.google.com/gmail/api/auth/about-auth?
Gmail api reference: https://developers.google.com/gmail/api/?authuser=1
Gmail API Client Librarieshttps://developers.google.com/gmail/api/downloads?authuser=1
This tutorial is for Python , the latest version is google-api-python-client 1.7.6, you can install it by access https://pypi.org/project/google-api-python-client/ or using  pip:
$ pip install –upgrade google-api-python-client

Next, I think it would be better if you get familiar with some terms/keywords below before started:
Resource Type:  Gmail API allows you to access several resource types (Messages, Labels, Drafts, History, Threads, Settings). You need to define which resource type you grant for your application to access Gmail service.
In this tutorial , I only mention about Messages. Messages are immutable: they can only be created and deleted. No message properties can be changed other than the labels applied to a given message.
Authentication and Authorization: Gmail API use OAuth 2.0 to handle authentication and authorization.
Scopes: Your app will specify one or more scopes: strings which identify resources that it needs to access. These scopes are used together with a set of tokens to secure a user’s access to resources. A scope represents a particular form of access to a single resource or to a group of resources, for example:
Read a message from Gmail: https://www.googleapis.com/auth/gmail.readonly
Change labels applied to a thread or message: https://www.googleapis.com/auth/gmail.modify
Send a message on behalf of a user: https://www.googleapis.com/auth/gmail.compose
refer https://developers.google.com/gmail/api/auth/scopes?authuser=1 for more options.

AND, you should know how authorization works , how your app can authorize with Gmail API:
At a high level, all apps follow the same basic authorization pattern:

  1. During development, register the application in the Google API Console.
  2. When the app launches, request that the user grant access to data in their Google account.
  3. If the user consents, your application requests and receives credentials to access the Gmail API.
  4. Refresh the credentials (if necessary).

Requests to the Gmail API must be authorized using OAuth 2.0 credentials. You should use server-side flow when your application needs to access Google APIs on behalf of the user, for example when the user is offline.

Now, move on to configure your Gmail account, to enable Gmail API, create a credential.

Implementing Server-Side Authorization
1. Create a client ID and client secret
Access setup tool https://console.developers.google.com/start/api?id=gmail&credential=client_key&authuser=1
which guides you through creating a project in the Google API Console, enable the API and creating credentials.
– Create new project , python-gmail for instance.
– Go to Dashboard tab, click Gmail API, click “Enable GMAIL API”

1
– From the Credentials page, click Create credentials > OAuth client ID to create your OAuth 2.0 credentials or Create credentials > Service account key to create a service account.

2
If you see the warning that you need to configure consent settings, let’s get it configured:
Enter Application name, Adding Scopes for Google APIs (https://mail.google.com/). And you can Save to redirect to Select app type page.
– If you created an OAuth client ID, then select your application type. Here I select Other for my application.

3.JPG
– Fill in the form and click Create.

Then a client ID and client secret key will be generated. You can also download it as json file. download it as credentials.json,you’ll need to add it to your code later.

Handling authorization requests
When a user loads your application for the first time, they are presented with a dialog to grant permission for your application to access their Gmail account with the requested permission scopes. After this initial authorization, the user is only presented with the permission dialog if your app’s client ID changes or the requested scopes have changed.

Authorizing with stored credentials
When users visit your app after a successful first-time authorization flow, your application can use a stored refresh token to authorize requests without prompting the user again.
If you have already authenticated the user, your application can retrieve the refresh token from its database and store the token in a server-side session. If the refresh token is revoked or is otherwise invalid, you’ll need to catch this and take appropriate action.

We have done configuring Gmail account. Next we need to implement the code in our framework to use Gmail APIs.

Let’s start by creating a project folder called fetchEmailPython. Copy the credential’s json file inside the project folder fetchEmailPython. Create a file called fetchEmail.py which will be our program file.

from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

SCOPES = 'https://www.googleapis.com/auth/gmail.readonly'

def main():
   
    store = file.Storage('token.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
        creds = tools.run_flow(flow, store)
    service = build('gmail', 'v1', http=creds.authorize(Http()))
    
    # Call the Gmail API to fetch INBOX
    results = service.users().messages().list(userId='me',labelIds = ['INBOX']).execute()
    messages = results.get('messages', [])
    

    if not messages:
        print "No messages found."
    else:
        print "Message snippets:"
        for message in messages:
            msg = service.users().messages().get(userId='me', id=message['id']).execute()
            print msg['snippet']

if __name__ == '__main__':
    main()

As seen in the above code, the program searches for a token.json file. If the token.json file is not found, then it makes a service call based on the project credentials.json file that you copied into the project folder. A service object is created based on the credentials which can queried to make API calls to GMAIL.

Save the above changes and execute the Python program. The python program launches the Google chrome browser which asks for permission to access the Gmail account. Once the consent is granted a token.json file is created inside the project folder. you will then see the Email snippets printed on the terminal from the GMAIL API.

For Sending an email using Gmail API, refer to below code:

from __future__ import print_function
from googleapiclient.discovery import build
from apiclient import errors
from httplib2 import Http
from email.mime.text import MIMEText
import base64
from google.oauth2 import service_account

# Email variables. Modify this!
EMAIL_FROM = 'noreply@lyfpedia.com'
EMAIL_TO = 'mark.zuckerber@facebook.com'
EMAIL_SUBJECT = 'Hello from Lyfepedia!'
EMAIL_CONTENT = 'Hello, this is a test\nLyfepedia\nhttps://lyfepedia.com'

service = service_account_login()
# Call the Gmail API
message = create_message(EMAIL_FROM, EMAIL_TO, EMAIL_SUBJECT, EMAIL_CONTENT)
sent = send_message(service,'me', message)

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())}

def send_message(service, user_id, message):
    """Send an email message.
    Args:
    service: Authorized Gmail API service instance.
    user_id: User's email address. The special value "me"
    can be used to indicate the authenticated user.
    message: Message to be sent.
    Returns:
    Sent 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)

def service_account_login():
    SCOPES = ['https://www.googleapis.com/auth/gmail.send']
    SERVICE_ACCOUNT_FILE = 'service-key.json'
    credentials = service_account.Credentials.from_service_account_file(
    SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    delegated_credentials = credentials.with_subject(EMAIL_FROM)
    service = build('gmail', 'v1', credentials=delegated_credentials)
    return service

Reference links:
1.https://codehandbook.org/how-to-read-email-from-gmail-api-using-python/
2.https://medium.com/lyfepedia/sending-emails-with-gmail-api-and-python-49474e32c81f
3.https://developers.google.com/gmail/api/auth/about-auth?

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s