Python调用Gmail API从Google Workspace发邮件至个人Gmail失败求助
问题:使用服务账户通过Gmail API发送邮件失败(Precondition check failed)
报错信息
return (<HttpError 400 when requesting https://gmail.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Precondition check failed.". Details: "[{'message': 'Precondition check failed.', 'domain': 'global', 'reason': 'failedPrecondition'}]"> )
使用的代码
import base64 from google.oauth2 import service_account from googleapiclient.errors import HttpError from googleapiclient.discovery import build from googleapiclient import errors from email.mime.text import MIMEText # Authenticate with credentials from JSON file creds = credentials SCOPES = ['https://www.googleapis.com/auth/gmail.send'] SERVICE_ACCOUNT_FILE = 'C:/Users/Desktop/service-account-gmail-app.json' credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES) # connect gmail api service = build('gmail', 'v1', credentials=creds) def send_email(service, to, subject, body, sender): try: message = create_message(to, subject, body, sender) send_message(service, message) print('E-mail was send successfully') except HttpError as error: print(f'E-mail was not sent: {error}') def create_message(to, subject, body, sender): message = MIMEText(body) message['to'] = to message['subject'] = subject message['body'] = body message['from'] = sender return {'raw': base64.urlsafe_b64encode(message.as_bytes()).decode()} def send_message(service, message): message = (service.users().messages().send(userId="me", body=message).execute()) to = 'individual gmail adress here' subject = 'Test e-mail' body = 'Hello this is a test message.' sender='google workspace e-mail address here (including domain information) ' message = create_message(to, subject, body,sender) print(message) send_email(service, to, subject, body, sender)
已完成的配置操作
- 将收件人邮箱地址添加至Google Workspace的「Manage address lists」;
- 在Google Cloud新建项目中启用Gmail API;
- 将Google Workspace邮箱地址添加至OAuth consent screen测试用户;
- 在OAuth consent screen的Authorized domains中添加Google Workspace域名;
- 在OAuth consent screen的Gmail scopes中授予以下权限:
- Gmail API .../auth/gmail.modify 读取、撰写并发送Gmail账户邮件
- Gmail API .../auth/gmail.compose 管理草稿并发送邮件
- Gmail API .../auth/gmail.readonly 查看邮件消息及设置
- 为服务账户分配「actions admin」角色;
- 创建服务账户并将生成的JSON密钥保存至代码运行目录。
疑问
为何完成上述操作后仍无法从Google Workspace邮箱向个人Gmail地址发送邮件?该如何解决此问题?
解决方案
1. 配置服务账户的域范围委派(核心问题)
服务账户无法直接发送邮件,必须获得Google Workspace域的授权来代表指定用户操作:
- 登录Google Workspace管理控制台,进入「安全」>「API控制」>「域范围委派」;
- 点击「添加新客户端」,输入服务账户的客户端ID(可从Google Cloud控制台的服务账户详情页获取);
- 在「OAuth范围」中添加
https://www.googleapis.com/auth/gmail.send,保存配置。
2. 修改代码,模拟目标Workspace用户
服务账户本身没有Gmail邮箱,必须指定要模拟的Workspace用户:
修改认证代码,添加with_subject()方法:
credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES).with_subject(sender)
其中sender就是你要用来发送邮件的Google Workspace邮箱地址。
3. 调整服务账户权限
「actions admin」角色与Gmail API无关,需给服务账户分配正确权限:
- 登录Google Cloud控制台,进入项目的IAM页面;
- 找到目标服务账户,添加角色
Gmail > Gmail Sender,确保拥有发送邮件的权限。
4. 修复代码中的冗余问题
- 删除
create_message函数中的message['body'] = body,MIMEText已处理邮件内容; - 给
send_message函数添加异常捕获,方便排查问题:
def send_message(service, message): try: message = (service.users().messages().send(userId="me", body=message).execute()) print(f"Message Id: {message['id']}") except errors.HttpError as error: print(f'An error occurred: {error}')
5. 补全OAuth同意屏幕的权限范围
当前OAuth同意屏幕中未添加代码使用的https://www.googleapis.com/auth/gmail.send权限,需补充该范围到同意屏幕的授权列表中。
内容的提问来源于stack exchange,提问作者user14178341
相关产品推荐
相关产品推荐

