通过Gmail API发送回复邮件的技术问题问询
搞定Gmail API发送指定已发送邮件的回复问题
我完全懂你的需求——不管收件人有没有回过原始已发送邮件(emailA),都得用Gmail API发emailB作为它的回复,而且你已经成功创建并发送了草稿,拿到了这样的返回结果:
{u'labelIds': [u'SENT'], u'id': u'16303ecfd567afa3', u'threadId': u'16303ecad298cdd1'}
接下来我就详细说怎么把返回的id转换成Message-ID,以及确保emailB能稳稳关联到emailA的线程里:
第一步:获取emailA的原始邮件内容
要拿到Message-ID,得先调用users.messages.get接口,用刚才得到的邮件id,并且指定format='raw'参数。给你个Python示例代码:
from googleapiclient.discovery import build def get_raw_email(service, user_id, msg_id): try: # 调用API获取原始邮件 message = service.users().messages().get( userId=user_id, id=msg_id, format='raw' ).execute() return message['raw'] except Exception as e: print(f"获取原始邮件翻车了: {e}") return None
第二步:解码并提取Message-ID
返回的raw字段是Base64编码的,得先解码成可读的邮件内容,再从邮件头里抠出Message-ID。代码如下:
import base64 from email import policy from email.parser import BytesParser def extract_message_id(raw_email): # URL安全的Base64解码 decoded_bytes = base64.urlsafe_b64decode(raw_email) # 解析邮件内容 parsed_msg = BytesParser(policy=policy.default).parsebytes(decoded_bytes) # 提取Message-ID return parsed_msg['Message-ID']
第三步:发送emailB时关联emailA
要让emailB成为emailA的回复,邮件头里必须加两个关键字段:
In-Reply-To: 填emailA的Message-IDReferences: 同样填emailA的Message-ID(如果是多层回复可以追加,但这里只关联emailA就行)
另外,显式设置返回的threadId会更保险,虽然Gmail会根据邮件头自动关联线程,但双保险总没错。
发送回复的示例代码:
def send_reply_email(service, user_id, recipient, original_subject, reply_body, original_msg_id, thread_id): # 构建回复的邮件内容,注意主题要加Re: reply_content = f"""From: {user_id} To: {recipient} Subject: Re: {original_subject} In-Reply-To: {original_msg_id} References: {original_msg_id} {reply_body} """ # 编码成Gmail API要求的格式 encoded_content = base64.urlsafe_b64encode(reply_content.encode('utf-8')).decode('utf-8') # 构建发送请求体 send_request = { 'raw': encoded_content, 'threadId': thread_id } try: sent_message = service.users().messages().send( userId=user_id, body=send_request ).execute() print(f"回复发出去啦!邮件ID: {sent_message['id']}") return sent_message except Exception as e: print(f"发送回复失败了: {e}") return None
几个要注意的坑
- 你的API授权范围必须包含
https://www.googleapis.com/auth/gmail.send和https://www.googleapis.com/auth/gmail.readonly,不然拿不到原始邮件也发不了信。 - 因为emailA是你自己发的,它的
threadId和你发送草稿返回的threadId是同一个,所以直接用这个threadId也能关联线程,但加In-Reply-To和References是标准邮件协议的做法,其他邮件客户端也能识别。 - Base64编码一定要用url-safe的方式,Gmail API不认普通的Base64编码哦。
内容的提问来源于stack exchange,提问作者Neil Aggarwal
相关产品推荐
相关产品推荐

