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

使用Gmail API(Python)设置邮件发件人显示姓名时遇到Invalid Impersonation Sub字段错误的技术问询

解决Gmail API发件人显示格式错误及RefreshError问题

我一眼就看出问题出在哪了——你把服务账号模拟身份的参数和邮件头的发件人显示格式搞混了!

错误原因

credentials.with_subject()这个方法里的参数只能是纯邮箱地址(比如my_name@company.com),不能带显示名和引号这类格式。你把"First Last '<my_name@company.com>'"传进去,Google的服务就会认为这是个无效的模拟主体,直接抛出Invalid impersonation "sub" field错误。

而你想要的First Name <my_name@company.com>这种显示格式,应该放在邮件的MIME头里,也就是create_message函数的sender参数里,和服务账号的模拟身份是完全独立的两件事。

修正后的代码

from __future__ import print_function
from googleapiclient.discovery import build
from apiclient import errors
from httplib2 import Http
from email.mime.text import MIMEText
import base64
from google.oauth2 import service_account

# 拆分变量:一个用于服务账号模拟的纯邮箱,一个用于显示的发件人格式
IMPERSONATE_EMAIL = "my_name@company.com"
DISPLAY_SENDER = "First Last <my_name@company.com>"
EMAIL_TO = 'some_mail@hotmail.com'
EMAIL_SUBJECT = 'Hello from Me!'
EMAIL_CONTENT = 'Some body'

# 调用Gmail API
def service_account_login():
    SCOPES = ['https://www.googleapis.com/auth/gmail.send']
    SERVICE_ACCOUNT_FILE = 'my-credentials.json'
    credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    # 模拟身份仅传纯邮箱地址
    delegated_credentials = credentials.with_subject(IMPERSONATE_EMAIL)
    service = build('gmail', 'v1', credentials=delegated_credentials)
    return service

def create_message(sender, to, subject, message_text):
    message = MIMEText(message_text)
    message['to'] = to
    # 这里用带显示名的格式设置发件人头
    message['from'] = sender
    message['subject'] = subject
    raw = base64.urlsafe_b64encode(message.as_bytes())
    raw = raw.decode()
    return {"raw": raw}

def send_message(service, user_id, message):
    try:
        message = (service.users().messages().send(userId=user_id, body=message)
                   .execute())
        print('Message Id: %s' % message['id'])
        return message
    except errors.HttpError as error:
        print('An error occurred: %s' % error)

service = service_account_login()
# 传入带显示名的发件人参数
message = create_message(DISPLAY_SENDER, EMAIL_TO, EMAIL_SUBJECT, EMAIL_CONTENT)
sent = send_message(service,'me', message)

关键注意点

  • with_subject()的参数必须是经过Google Workspace管理员授权的纯邮箱地址,不能有任何额外格式,这是服务账号用来模拟该用户发邮件的核心身份标识。
  • 邮件收件箱里显示的发件人名称,完全由MIME头的from字段控制,标准格式就是显示名称 <邮箱地址>,不需要加多余的引号。
  • 提前确认你的服务账号已经在Workspace管理控制台中被授予了模拟目标邮箱的权限,否则即使参数正确也可能触发权限错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:37:28