Create a desktop application using Gmail API

814 views Asked by At

I have been trying to configure my conky to show the details of unread mails in my Gmail account. I have finally come up with a python script which does this task. It uses a client_secret.json file I downloaded from the google developer console. Here's the code

from datetime import datetime
import os
from apiclient import errors
from apiclient.discovery import build
from httplib2 import Http
import oauth2client
from oauth2client import client
from oauth2client import tools

"""Get a list of Messages from the user's mailbox.
"""

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None
SCOPES = 'https://www.googleapis.com/auth/gmail.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Gmail Notifier'

def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
    Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir, 'gmail-notifier.json')
    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatability with Python 2.6
            credentials = tools.run(flow, store)
        print 'Storing credentials to ' + credential_path
    return credentials


def ListMessagesMatchingQuery(service, user_id, query=''):
    """List all Messages of the user's mailbox matching the query.

    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.
    query: String used to filter messages returned.
    Eg.- 'from:user@some_domain.com' for Messages from a particular sender.

  Returns:
    List of Messages that match the criteria of the query. Note that the
    returned list contains Message IDs, you must use get with the
    appropriate ID to get the details of a Message.
  """
    try:
        response = service.users().messages().list(userId=user_id, q=query).execute()
        messages = []
        if 'messages' in response:
            messages.extend(response['messages'])

        while 'nextPageToken' in response:
            page_token = response['nextPageToken']
            response = service.users().messages().list(userId=user_id, q=query, pageToken=page_token).execute()
            messages.extend(response['messages'])

        return messages
    except errors.HttpError, error:
        print 'An error occurred: %s' % error


def ListMessagesWithLabels(service, user_id, label_ids=[]):
    """List all Messages of the user's mailbox with label_ids applied.

    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.
    label_ids: Only return Messages with these labelIds applied.

  Returns:
    List of Messages that have all required Labels applied. Note that the
    returned list contains Message IDs, you must use get with the
    appropriate id to get the details of a Message.
  """
    try:
        response = service.users().messages().list(userId=user_id, labelIds=label_ids).execute()
        messages = []
        if 'messages' in response:
            messages.extend(response['messages'])

        while 'nextPageToken' in response:
            page_token = response['nextPageToken']
            response = service.users().messages().list(userId=user_id, labelIds=label_ids, pageToken=page_token).execute()
            messages.extend(response['messages'])

        return messages
    except errors.HttpError, error:
        print 'An error occurred: %s' % error

def main():
    credentials = get_credentials()
    service = build('gmail', 'v1', http=credentials.authorize(Http()))
    msgids = ListMessagesMatchingQuery(service, 'me', query='is:unread')

    if (len(msgids)>0):
        # Play notification sound
        os.system('paplay /usr/share/sounds/freedesktop/stereo/complete.oga')
        print "%s new message(s) in Inbox\n" % len(msgids)
        for id in msgids:
            message = service.users().messages().get(userId='me', id=id['id']).execute()

            # Print Sender
            headers = message['payload']['headers']
            for i in range(len(headers)):
                if headers[i]['name'] == "From":
                    sender = headers[i]['value'].replace('"', '')
                    sender = sender.split("<")

                    # get sender name, if no name then print email
                    if (sender[0].replace(" ", "") != ""):
                        print ">", sender[0]
                    else:
                        print ">", sender[1][:-1]

            # Print Subject
            for i in range(len(headers)):
                if headers[i]['name'] == "Subject":
                    print "Sub: ", headers[i]['value']

            print message['snippet']
            print " "
    else:
        print "Yipeeee! No unread messages\n"

if __name__ == "__main__":
    try:
        main()
    except:
        print "Network unavailable :("

Now I want to make this into a proper application so that it can be shared and the user does not need to go to the google developer console to get the .json file.

  • Is it fine if I distribute my .json with the app?

If this is the case then I'm done but if not then

  • What is the correct method to make this script into a desktop application?

I looked at various options in the developer console but could not figure out how to make a desktop application. I am completely new to the google developer and API thing so any help would be appreciated.

1

There are 1 answers

0
artemdevel On BEST ANSWER

I'm also new to this API and trying to figure out the same thing.. I think distribution of the .json file with secrets is a bad idea.

At least I found this warning in the docs "Keep your client secret private. If someone obtains your client secret, they could use it to consume your quota, incur charges against your Console project, and request access to user data."