質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2516閲覧

【Python/Gmail/GmailAPI】任意のメール内のスレッドIDに返信メールを送りたい

t-hiroki

総合スコア1

Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/12 07:56

編集2021/12/12 08:55

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で取得しており、こちらは問題なく取得できています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

下記の内容で、threadIdを直打ちしたら、返信できたことが確認されました。
あとは、スレッドIDの有無を条件分岐うまく作って実装してみたいと思います。
解決に向けてご助力いただいた方々ありがとうございました。

if thread_id: raw_msg['threadId'] = thread_id return raw_msg

投稿2021/12/12 09:12

t-hiroki

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問