使用 Gmail 创建桌面应用程序 API
Create a desktop application using Gmail API
我一直在尝试配置我的 conky 以显示我的 Gmail 帐户中未读邮件的详细信息。我终于想出了一个 python 脚本来完成这个任务。它使用我从 google 开发者控制台下载的 client_secret.json
文件。这是代码
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 :("
现在我想把它做成一个合适的应用程序,这样它就可以共享,用户不需要去 google 开发者控制台来获取 .json
文件。
- 如果我通过应用程序分发
.json
可以吗?
如果是这样,我就完成了,如果不是,那么
- 将此脚本制作成桌面应用程序的正确方法是什么?
我查看了开发人员控制台中的各种选项,但无法弄清楚如何制作桌面应用程序。我对 google 开发人员和 API 完全陌生,所以任何帮助将不胜感激。
我也是这个 API 的新手,正在尝试弄清楚同样的事情。我认为分发带有机密的 .json 文件不是一个好主意。
至少我在 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."
中发现了这个警告
我一直在尝试配置我的 conky 以显示我的 Gmail 帐户中未读邮件的详细信息。我终于想出了一个 python 脚本来完成这个任务。它使用我从 google 开发者控制台下载的 client_secret.json
文件。这是代码
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 :("
现在我想把它做成一个合适的应用程序,这样它就可以共享,用户不需要去 google 开发者控制台来获取 .json
文件。
- 如果我通过应用程序分发
.json
可以吗?
如果是这样,我就完成了,如果不是,那么
- 将此脚本制作成桌面应用程序的正确方法是什么?
我查看了开发人员控制台中的各种选项,但无法弄清楚如何制作桌面应用程序。我对 google 开发人员和 API 完全陌生,所以任何帮助将不胜感激。
我也是这个 API 的新手,正在尝试弄清楚同样的事情。我认为分发带有机密的 .json 文件不是一个好主意。
至少我在 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."
中发现了这个警告