Python版Gmail API ClientでThreadにメール(返信)を送信する
上記のサイトを参考に、Pythonを使ってGmailの返信機能の実装を目指しています。
今書いているコードがこのような感じです。
Python
1import pickle 2import os.path 3from googleapiclient.discovery import build 4from google_auth_oauthlib.flow import InstalledAppFlow 5from google.auth.transport.requests import Request 6import base64 7from email.mime.text import MIMEText 8from apiclient import errors 9import json 10 11SCOPES = ['https://mail.google.com/', 12 'https://www.googleapis.com/auth/gmail.send', 13 'https://www.googleapis.com/auth/gmail.readonly', 14] 15 16def create_message(sender, to, subject, message_text, 17 thread_id=None, reply_to=None, past_message=None): 18 if past_message: 19 message_text = message_text + '\r\n\r\n' 20 for strline in past_message.splitlines(): # 過去のメッセージを一行ずつ分割 21 message_text = message_text + '\r\n>' + strline # 手で改行 + '>'を追加 22 message = MIMEText(message_text) 23 message['to'] = to 24 message['from'] = sender 25 message['subject'] = subject 26 if reply_to: 27 message['Reference'] = reply_to 28 message['In-Reply-To'] = reply_to 29 raw_msg = base64.urlsafe_b64encode(message.as_bytes()) 30 raw_msg = raw_msg.decode() 31 raw_msg = {'raw': raw_msg} 32 if thread_id: 33 raw_msg['threadId'] = thread_id 34 return raw_msg 35 36 37def send_message(service, user_id, message): 38 try: 39 message = service.users().messages().send(userId=user_id, body=message).execute() 40 print('Message Id: %s' %message['id']) 41 return message 42 except errors.HttpError as error: 43 print('An error ocurred: %s' % error) 44 45### Thread IDを取得する 46def get_thread_list(service, user_id, query): 47 return service.users().threads().list(userId=user_id, q=query).execute() 48 49### メッセージの中身を取得する 50def get_thread(service, user_id, thread_id): 51 return service.users().threads().get(userId=user_id, id=thread_id).execute() 52 53def main(): 54 creds = None 55 if os.path.exists('token.pickle'): 56 with open('token.pickle','rb') as token: 57 creds = pickle.load(token) 58 59 if not creds or not creds.valid: 60 if creds and creds.expired and creds.refresh_token: 61 creds.refresh(Request()) 62 else: 63 flow = InstalledAppFlow.from_client_secrets_file( 64 'credentials.json', SCOPES) 65 creds = flow.run_local_server() 66 67 with open('token.pickle', 'wb') as token: 68 pickle.dump(creds, token) 69 70 service = build('gmail','v1',credentials=creds) 71 72##### 一発目(threadが立っていない)のときにコメントアウト ##### 73 query = 'in:sent' # 自分が送信したThreadを検索 74 thread_list = get_thread_list(service,'me',query) # jsonをdictionaryにdumpしたものが帰ってくる 75 thread_id = thread_list['threads'][0]['id'] 76 print(thread_id) # 検索の最初のThreadのthreadIdが出力される 77 thread = get_thread(service,'me',thread_id) 78 latest_message = thread['messages'][-1]['payload'] # threadの一番最後のメッセージオブジェクトを取得 79 latest_msg_body = base64.urlsafe_b64decode(latest_message['body']['data']).decode() # base64形式なのでstringにdecodeする 80 81 ###ついでに、ここからReplyするメッセージIDをHeaderから取得しておく 82 for att in latest_message['headers']: 83 if att['name'] == 'Message-Id': 84 message_id = att['value'] 85 break 86##### コメントアウトおわり ###### 87 88 sender = '******@******' 89 to = '######@######' 90 subject = 'Gmail API test' 91# message_text = 'This mail is sent via the Gmail API' # 1回目(reply_toとthread_idは定義しない) 92 message_text = 'This mail is test for sending to the same thread' # 2回目 93# message_text = 'This mail is test for sending to the same thread (2nd)' #3回目 94 95# message = create_message(sender, to, subject, message_text) # 一発目のみ 96 message = create_message(sender, to, subject, message_text, thread_id, message_id, latest_msg_body) 97 send_message(service, 'me', message) 98 99if __name__ == '__main__': 100 main()
こちらのリンクを参考にしてみたのですが、メッセージIDを指定して実行しても新着メールとして届いてしまいます。。
メッセージIDで検索し、その中の最新のスレッドIDに返信をするには何か設定が足りないのでしょうか。
もしわかる方いたら教えてください。
よろしくお願いします。
<補足>
GmailのメッセージIDとスレッドIDもPythonで取得しており、こちらは問題なく取得できています。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。