Python调用Gmail API回复邮件 引用原文未正常显示灰色引用条
问题核心原因
Gmail 显示默认灰色引用标识条、支持引用折叠的前提是邮件纯文本内容符合标准邮件回复格式,且能准确识别历史引用块,当前代码存在3个关键问题导致识别失败:
- 原始内容提取错误:直接对完整原始MIME邮件做base64解码,拿到的内容包含邮件头、MIME分隔符、多段内容边界标记,并非纯净的原始邮件纯文本正文,无法匹配Gmail的引用特征规则
- 引用格式不规范:换行符混用
\n和\r\n,已有引用前缀的行处理逻辑错误,缺少Gmail识别引用必需的格式分隔 - 引用块位置不符合要求:Gmail仅会识别位于邮件正文最末尾的连续引用块,中间不能夹杂其他内容
修复步骤
- 用Python标准库
email模块解析原始MIME邮件,提取纯净的text/plain类型正文,不要直接解码整个原始邮件字符串 - 统一换行符格式,按标准给每一行原始内容添加引用前缀,自动兼容多级历史引用
- 按标准格式拼接回复正文、引用头、引用内容,保证引用块位于正文最末尾
- 显式指定邮件内容为纯文本类型,避免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
相关产品推荐
相关产品推荐

