最新のものだけ取得するようにする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 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 # スコープの設定 # トークンとクレデンシャルのパス 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件のメールのみ取得できるようになる
次に未読のものだけ取得するようにする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 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 # スコープの設定 # トークンとクレデンシャルのパス 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を本文から削除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 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 # スコープの設定 # トークンとクレデンシャルのパス 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のみ削除しているため
発信元とかについては削除されていないので
これも対処する必要がある