Gmail API发送邮件时UTF-8显示名丢失问题求助
Gmail API发送邮件UTF-8显示名丢失问题的成因与解决
问题代码
def send_email(payload, messagesubject, sendtoaddresses, key_file_path: str, subject: str): messagedraft = MIMEText(payload, "plain") mailservice = build_mail_service(key_file_path, subject) messagedraft["From"] = f"Display name <{subject}>" messagedraft["Subject"] = messagesubject for address in sendtoaddresses.split(","): if "To" in messagedraft: del messagedraft["To"] messagedraft["To"] = address message = {"raw": urlsafe_b64encode(messagedraft.as_bytes()).decode()} mailservice.users().messages().send(userId="me", body=message).execute()
问题描述
使用上述函数通过Gmail API发送邮件时,功能基本正常,但当「From」字段中的“Display name”包含UTF-8字符时,显示名会被省略,仅邮箱地址出现在邮件头中。仅将UTF-8字符转为ASCII时才能正常显示,尝试多种编码设置无效,需了解问题成因及解决办法。
成因分析
- 邮件头字段(如From、Subject)必须遵循RFC 2047规范进行编码,才能正确传输非ASCII字符。直接将含UTF-8字符的字符串赋值给
messagedraft["From"],MIMEText不会自动进行符合规范的编码,导致邮件客户端解析失败,直接丢弃显示名部分。 - 默认创建的MIMEText未明确指定编码,可能导致邮件头的编码处理逻辑不兼容非ASCII字符。
解决办法
使用Python标准库email.header中的Header类对显示名(及Subject)进行RFC 2047编码,修改后的代码如下:
from email.header import Header from email.mime.text import MIMEText # 保留原有的其他导入(如build_mail_service、urlsafe_b64encode等) def send_email(payload, messagesubject, sendtoaddresses, key_file_path: str, subject: str): # 明确指定MIMEText的内容编码为utf-8 messagedraft = MIMEText(payload, "plain", "utf-8") mailservice = build_mail_service(key_file_path, subject) # 对显示名进行RFC 2047编码 display_name = "你的UTF-8显示名" # 替换为实际的显示名字符串 encoded_display_name = Header(display_name, "utf-8").encode() messagedraft["From"] = f"{encoded_display_name} <{subject}>" # 同时对Subject字段编码,避免主题含非ASCII字符时出现异常 messagedraft["Subject"] = Header(messagesubject, "utf-8").encode() for address in sendtoaddresses.split(","): if "To" in messagedraft: del messagedraft["To"] messagedraft["To"] = address message = {"raw": urlsafe_b64encode(messagedraft.as_bytes()).decode()} mailservice.users().messages().send(userId="me", body=message).execute()
关键修改说明
- 导入Header类:用于生成符合RFC 2047规范的邮件头字符串,确保非ASCII字符能被正确解析。
- 明确MIMEText编码:创建MIMEText时指定
utf-8编码,统一邮件内容和头的编码逻辑。 - 编码显示名和主题:通过
Header(内容, "utf-8").encode()对含非ASCII字符的字段进行编码,生成类似=?utf-8?B?5L2g5aW95ZCN?= <xxx@example.com>的格式,邮件客户端会自动解码显示原始字符。
内容的提问来源于stack exchange,提问作者AdeQ
相关产品推荐
相关产品推荐

