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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:42:44