PythonでGmailAPIを利用して内容を取得した。
チャットボットに組み込んだ機能の一つ。
もくじ
GmailAPIを使う
GmailAPIとは、Googleが提供しているGmailを扱うためのAPI。
できることは、
・メッセージの読み取りと送信
・下書きと添付ファイルの管理
・スレッドとメッセージの検索
・ラベルの操作
・プッシュ通知の設定
・およびGmail設定の管理
と多岐にわたる。
というかGmailで使う機能をほぼほぼ網羅してる。
要するにコードで自由にGmailを扱えるってことね。
素晴らしい。
GmailAPIの使い方については詳細には書かない。
理由は、他に非常にわかりやすくまとまっているサイトがあるため。
参考サイトはこちら。
PythonでGmailのメールを確認しよう
何ならこのサイト通りにするだけで、GoogleAPIを使ってメールの要約を表示するところまでは出来てしまうのでおすすめ。
GmailAPIで未読のメールの本文だけ取得する
とりあえずコード。
基本的にはさっきの参考サイトのコピペ。
認証情報へのPATHを直接コードに書いてたり、余計な動作が混じってるのはご容赦。
import httplib2, os from apiclient import discovery from oauth2client import client, tools from oauth2client.file import Storage def gmail_get_service(): # ユーザー認証の取得 credentials = getauth() http = credentials.authorize(httplib2.Http()) # GmailのAPIを利用する service = discovery.build('gmail', 'v1', http=http) return service # メッセージの一覧を取得 def gmail_get_messages(): service = gmail_get_service() data_list = [] # メッセージの一覧を取得 messages = service.users().messages() msg_list = messages.list(userId='me', maxResults=30).execute() # 取得したメッセージの一覧を表示 for msg in msg_list['messages']: topid = msg['id'] msg = messages.get(userId='me', id=topid).execute() if msg['labelIds'][0] == "UNREAD": data_list.append(msg['snippet']) print(msg['snippet']) return "OK" def getauth(): # ユーザーの認証データの読み取り store = Storage('credentials-gmail.json') credentials = store.get() # ユーザーが認証済みか? if not credentials or credentials.invalid: # 新規で認証する flow = client.flow_from_clientsecrets('gmail.json', 'https://www.googleapis.com/auth/gmail.readonly') flow.user_agent = 'Python Gmail API' credentials = tools.run_flow(flow, store, None) return credentials gmail_get_messages()
ポイントはこの部分。
# メッセージの一覧を取得 messages = service.users().messages() msg_list = messages.list(userId='me', maxResults=30).execute() # 取得したメッセージの中で未読のものを表示 for msg in msg_list['messages']: topid = msg['id'] msg = messages.get(userId='me', id=topid).execute() if msg['labelIds'][0] == "UNREAD": data_list.append(msg['snippet']) print(msg['snippet'])
Gmailから受け取ったメッセージは次のような形式で渡される。
未読のメールに関しては、’labelIds’に’UNREAD’という情報が追加されている。
なので’UNREAD’の有無の条件分岐で未読メールを表示できる。
{ 'id': '16629c6e7163565f', 'threadId': '16629c6e7163565f', 'labelIds': ['UNREAD', 'IMPORTANT', 'SENT', 'INBOX'], 'snippet': 'テストメール', 'historyId': '4807380', 'internalDate': '1538299190000', 'payload': {'partId': '', 'mimeType': 'text/plain', 'filename': '', 'headers': [{'name': 'Return-Path', 'value': '<メールアドレス>' }, { 'name': 'Received', 'value': 'from [IPアドレス] (ai126173163159.46.access-internet.ne.jp. [IPアドレス]) by smtp.gmail.com with ESMTPSA id y85-v6sm17088410pfa.170.2018.09.30.02.19.52 for <メールアドレス> (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 30 Sep 2018 02:19:52 -0700 (PDT)' }, { 'name': 'From', 'value': '"送信者" <メールアドレス>' }, {'name': 'Content-Transfer-Encoding', 'value': 'base64'}, {'name': 'Content-Type', 'value': 'text/plain; charset=utf-8'}, {'name': 'Mime-Version', 'value': '1.0 (1.0)'}, {'name': 'Date', 'value': 'Sun, 30 Sep 2018 18:19:50 +0900'}, {'name': 'Message-Id', 'value': '<メールアドレス>'}, {'name': 'To', 'value': '"送信者" <メールアドレス>'}, { 'name': 'X-Mailer', 'value': 'iPhone Mail (15G77)'}], 'body': {'size': 20, 'data': '44OG44K544OI44Oh44O844OrDQo='} }, 'sizeEstimate': 752}
まとめ
とりあえずこれでGmailAPIから受け取った内容をPythonで扱うことが出来た。
今回作ったこのコードは、自作のLINEBotに組み込んでメール通知機能として使っている。
とはいえその機能自体はメールアプリで事足りる。
送信者でIF文を書けば特定の相手からのメールのみを通知したりできるし、使い方はアイデアしだいで広がりそう。
ちなみに僕は始め、GmailをPythonで扱うためにIMAPプロトコルを利用したのだが、問題があってやめてしまった。
その問題とは、Googleのセキュリティレベルを下げなければならない点である。
IMAPでGmailと連携すると、通常の設定ではブロックされてしまう。
便利なAPIがある中で無理に問題のある方法を選ぶ必要はないので、特に使う必要はないだろう。