使用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
相关产品推荐
相关产品推荐

