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.
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."