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

Python调用Gmail API回复邮件 引用原文未正常显示灰色引用条

问题核心原因

Gmail 显示默认灰色引用标识条、支持引用折叠的前提是邮件纯文本内容符合标准邮件回复格式,且能准确识别历史引用块,当前代码存在3个关键问题导致识别失败:

  • 原始内容提取错误:直接对完整原始MIME邮件做base64解码,拿到的内容包含邮件头、MIME分隔符、多段内容边界标记,并非纯净的原始邮件纯文本正文,无法匹配Gmail的引用特征规则
  • 引用格式不规范:换行符混用\n和\r\n,已有引用前缀的行处理逻辑错误,缺少Gmail识别引用必需的格式分隔
  • 引用块位置不符合要求:Gmail仅会识别位于邮件正文最末尾的连续引用块,中间不能夹杂其他内容
修复步骤
  1. 用Python标准库email模块解析原始MIME邮件,提取纯净的text/plain类型正文,不要直接解码整个原始邮件字符串
  2. 统一换行符格式,按标准给每一行原始内容添加引用前缀,自动兼容多级历史引用
  3. 按标准格式拼接回复正文、引用头、引用内容,保证引用块位于正文最末尾
  4. 显式指定邮件内容为纯文本类型,避免EmailMessage自动做格式转换
修正后代码
import base64
from email.message import EmailMessage
from email import message_from_bytes
from email.policy import default

def send_message(self, event):
    service = self._get_gmail_service()
    message = EmailMessage()

    # 解析原始MIME邮件,提取纯文本正文
    original_mime = message_from_bytes(
        base64.urlsafe_b64decode(event["original_message"]),
        policy=default
    )
    original_text = ""
    for part in original_mime.walk():
        # 跳过附件,只取纯文本正文
        if part.get_content_type() == "text/plain" and not part.get_content_disposition() == "attachment":
            original_text = part.get_content()
            break

    # 统一换行符格式
    original_text = original_text.replace("\r\n", "\n").replace("\r", "\n")

    # 生成标准引用头
    quoted_header = f"On {event['original_message_date']}, {event['original_message_from']} wrote:"
    # 处理引用正文,自动兼容多级引用
    quoted_body = ""
    for line in original_text.splitlines():
        quoted_body += f"> {line}\n"

    # 按标准格式拼接内容:回复内容 + 空行分隔 + 引用头 + 空行 + 引用内容
    replyText = f"{event['message']}\n\n{quoted_header}\n\n{quoted_body}"

    # 显式指定为纯文本内容
    message.set_content(replyText, subtype="plain")
    message["To"] = event["To"]
    message["Cc"] = event["Cc"]
    message["From"] = event["From"]
    message["Subject"] = event["Subject"]
    message["In-Reply-To"] = event["In-Reply-To"]
    message["References"] = event["References"]

    create_message = {
        'raw': base64.urlsafe_b64encode(message.as_bytes()).decode(),
        'threadId': event["threadId"]
    }

    send_message = (service.users().messages().send
                    (userId=self.subject, body=create_message).execute())
    print(f'Message Id: {send_message["id"]}')
    return send_message
补充说明
  • 需保证传入的In-Reply-To、References头值正确,threadId和原始邮件线程ID一致,否则邮件无法正确归并到对应会话线程
  • 如果需要发送HTML格式的回复,需要额外生成text/html类型的内容,用<blockquote>标签包裹原始邮件的HTML正文,才能在HTML视图下正常显示引用样式

内容的提问来源于stack exchange,提问作者Shubham Teotia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:54:29