最新のものだけ取得するようにする
from __future__ import print_function import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials import base64 import email import dateutil.parser # スコープの設定 SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] # トークンとクレデンシャルのパス tokenPath = "token.json" credentialsPath = "credentials.json" # メール本文のデコード関数 def decode(encoded): decoded = base64.urlsafe_b64decode(encoded).decode() return decoded # 最新のメール本文を取得する関数 def gmail_get_latest_message_body(service, labelIdsValue): messages = service.users().messages() msg_list = messages.list(userId='me', labelIds=labelIdsValue, maxResults=1).execute() if not msg_list['messages']: return "No messages found." msg = msg_list['messages'][0] date = gmail_get_messages_body_date(messages, msg) topid = msg['id'] msg = messages.get(userId='me', id=topid).execute() # メールの本文を取得 if msg["payload"]["body"]["size"] != 0: return date + "<br>" + decode(msg["payload"]["body"]["data"]) elif 'parts' in msg["payload"]: # メール本文が parts 属性にある場合 for part in msg["payload"]["parts"]: if part["body"]["size"] != 0: return date + "<br>" + decode(part["body"]["data"]) return date + "<br> No body content" # メールの受信日時を取得する関数(変更なし) def gmail_get_messages_body_date(messages, msg): msg_id = msg['id'] m = messages.get(userId='me', id=msg_id, format='raw').execute() raw = base64.urlsafe_b64decode(m['raw']) eml = email.message_from_bytes(raw) date = dateutil.parser.parse(eml.get('Date')).strftime("%Y-%m-%d_%H-%M-%S") return date # ラベルの表示関数(変更なし) def gmail_display_label(service): results = service.users().labels().list(userId='me').execute() labels = results.get('labels', []) # Gmail API 初期化関数(変更なし) def gmail_init(): creds = None if os.path.exists(tokenPath): creds = Credentials.from_authorized_user_file(tokenPath, SCOPES) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( credentialsPath, SCOPES) creds = flow.run_local_server(port=0) with open(tokenPath, 'w') as token: token.write(creds.to_json()) service = build('gmail', 'v1', credentials=creds) return service # メイン処理 service = gmail_init() gmail_display_label(service) # ラベル ID を指定して最新のメール本文を取得 latest_message_body = gmail_get_latest_message_body(service, "Label_4") print(latest_message_body)
これで最新の1件のメールのみ取得できるようになる
次に未読のものだけ取得するようにする
from __future__ import print_function import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials import base64 import email import dateutil.parser # スコープの設定 SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] # トークンとクレデンシャルのパス tokenPath = "token.json" credentialsPath = "credentials.json" # メール本文のデコード関数 def decode(encoded): decoded = base64.urlsafe_b64decode(encoded).decode() return decoded # 未読メールの本文を取得する関数 def gmail_get_unread_messages_body(service, labelIdsValue): mailBody = [] messages = service.users().messages() msg_list = messages.list(userId='me', labelIds=labelIdsValue, q="is:unread").execute() if 'messages' not in msg_list: return ["No unread messages found."] for msg in msg_list['messages']: date = gmail_get_messages_body_date(messages, msg) topid = msg['id'] msg = messages.get(userId='me', id=topid).execute() # メールの本文を取得 if msg["payload"]["body"]["size"] != 0: mailBody.append(date + "<br>" + decode(msg["payload"]["body"]["data"])) elif 'parts' in msg["payload"]: # メール本文が parts 属性にある場合 for part in msg["payload"]["parts"]: if part["body"]["size"] != 0: mailBody.append(date + "<br>" + decode(part["body"]["data"])) break else: mailBody.append(date + "<br> No body content") return mailBody # メールの受信日時を取得する関数(変更なし) def gmail_get_messages_body_date(messages, msg): msg_id = msg['id'] m = messages.get(userId='me', id=msg_id, format='raw').execute() raw = base64.urlsafe_b64decode(m['raw']) eml = email.message_from_bytes(raw) date = dateutil.parser.parse(eml.get('Date')).strftime("%Y-%m-%d_%H-%M-%S") return date # ラベルの表示関数(変更なし) def gmail_display_label(service): results = service.users().labels().list(userId='me').execute() labels = results.get('labels', []) # Gmail API 初期化関数(変更なし) def gmail_init(): creds = None if os.path.exists(tokenPath): creds = Credentials.from_authorized_user_file(tokenPath, SCOPES) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( credentialsPath, SCOPES) creds = flow.run_local_server(port=0) with open(tokenPath, 'w') as token: token.write(creds.to_json()) service = build('gmail', 'v1', credentials=creds) return service # メイン処理 service = gmail_init() gmail_display_label(service) # ラベル ID を指定して未読メールの本文を取得 unread_messages_body = gmail_get_unread_messages_body(service, "Label_4") for body in unread_messages_body: print(body)
未読のメールのみを表示するようにコードを修正するには
Gmail APIのクエリパラメータに q=”is:unread” を追加する
q=”is:unread” パラメータを messages.list
API呼び出しに追加することで、未読のメールのみがフィルタリングされる
取得したメールの中で
decode 関数を使用してメールの本文をデコードし
必要に応じて parts 属性を確認
未読メールがない場合
“No unread messages found.”
というメッセージが返され
未読メールがある場合は
それぞれのメールについて受信日時と本文が表示される
Label_4
に属する未読メールのみを処理しているので
他のラベルや追加のフィルタリング条件を使用したい場合は
labelIdsValue 引数や q パラメータを適宜変更する
この場合
過去全てからになってしまうので期間を設定する
未読で最新のものを取得するようにする
そしてURLを本文から削除
from __future__ import print_function import os.path import re from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials import base64 import email import dateutil.parser # スコープの設定 SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] # トークンとクレデンシャルのパス tokenPath = "token.json" credentialsPath = "credentials.json" # メール本文のデコード関数 def decode(encoded): decoded = base64.urlsafe_b64decode(encoded).decode() return decoded # URLを削除する関数 def remove_urls(text): # URLにマッチする正規表現パターン url_pattern = r'https?://\S+|www\.\S+' return re.sub(url_pattern, '', text) # 未読で最新のメール本文を取得する関数 def gmail_get_latest_unread_message_body(service, labelIdsValue): messages = service.users().messages() msg_list = messages.list(userId='me', labelIds=labelIdsValue, q="is:unread").execute() if 'messages' not in msg_list: return "No unread messages found." # 未読メッセージのリストを取得し、最初のメッセージ(最新)を選択 msg = msg_list['messages'][0] date = gmail_get_messages_body_date(messages, msg) topid = msg['id'] msg = messages.get(userId='me', id=topid).execute() # メールの本文を取得 body = "" if msg["payload"]["body"]["size"] != 0: body = decode(msg["payload"]["body"]["data"]) elif 'parts' in msg["payload"]: # メール本文が parts 属性にある場合 for part in msg["payload"]["parts"]: if part["body"]["size"] != 0: body = decode(part["body"]["data"]) break if not body: return date + "<br> No body content" # URLを削除 body_no_urls = remove_urls(body) return date + "<br" + body_no_urls # メールの受信日時を取得する関数(変更なし) def gmail_get_messages_body_date(messages, msg): msg_id = msg['id'] m = messages.get(userId='me', id=msg_id, format='raw').execute() raw = base64.urlsafe_b64decode(m['raw']) eml = email.message_from_bytes(raw) date = dateutil.parser.parse(eml.get('Date')).strftime("%Y-%m-%d_%H-%M-%S") return date # ラベルの表示関数(変更なし) def gmail_display_label(service): results = service.users().labels().list(userId='me').execute() labels = results.get('labels', []) # Gmail API 初期化関数(変更なし) def gmail_init(): creds = None if os.path.exists(tokenPath): creds = Credentials.from_authorized_user_file(tokenPath, SCOPES) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( credentialsPath, SCOPES) creds = flow.run_local_server(port=0) with open(tokenPath, 'w') as token: token.write(creds.to_json()) service = build('gmail', 'v1', credentials=creds) return service # メイン処理 service = gmail_init() gmail_display_label(service) # ラベル ID を指定して未読メールの本文を取得 latest_unread_message_body = gmail_get_latest_unread_message_body(service, "Label_4") print(latest_unread_message_body)
しかしこれだと本文の中のURLのみ削除しているため
発信元とかについては削除されていないので
これも対処する必要がある