You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过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-ID
  • References: 同样填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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:57:27