[英]send mail using service account and google api python
编辑:接受答案后:我的问题是关于一个免费的 Gmail 帐户(我不知道有什么区别),答案是关于一个付费帐户(这是一个正确的帐户),答案告诉我有一个区别,它让我对我的情况做出了正确的回答——使用密码
我正在尝试使用 google API 和服务帐户发送邮件,但出现以下错误:
An error occurred: <HttpError 400 when requesting https://gmail.googleapis.com/gmail/v1/users/me/drafts?alt=json returned "Precondition check failed.". Details: "[{'message': 'Precondition check failed.', 'domain': 'global', 'reason': 'failedPrecondition'}]">
这是我的代码:
from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from oauth2client.service_account import ServiceAccountCredentials
import base64
from email.message import EmailMessage
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://mail.google.com/']
def main():
"""Shows basic usage of the Gmail API.
Lists the user's Gmail labels.
"""
creds = None
creds = ServiceAccountCredentials.from_json_keyfile_name(
"""path_to_cred_file.json""", SCOPES)
try:
# Call the Gmail API
service = build('gmail', 'v1', credentials=creds)
message = EmailMessage()
message.set_content('This is automated draft mail')
message['To'] = 'somemail@gmail.com'
message['From'] = 'somemail@gmail.com'
message['Subject'] = 'Automated draft'
# encoded message
encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
create_message = {
'message': {
'raw': encoded_message
}
}
# pylint: disable=E1101
draft = service.users().drafts().create(userId="me",
body=create_message).execute()
except HttpError as error:
# TODO(developer) - Handle errors from gmail API.
print(f'An error occurred: {error}')
if __name__ == '__main__':
main()
“Precondition check failed”通常意味着您正在尝试做一些无法完成的事情。 在这种情况下,您尝试从服务帐户发送 email,这是不可能的。 此答案包含指向 Google 文档中相关主题的链接。 他们说:
服务帐户不能与 gmail 一起使用,除非您将全域委托设置为 Gsuite 帐户。 原因是服务帐户是它自己的用户,您需要委托其访问您的 gmail 帐户的权限。 这仅适用于 gsuite 域 email 地址。
这意味着服务帐户本身不能发送消息,而是需要将访问权限委托给普通用户帐户才能发送电子邮件。 为此,您可以在creds
之后添加以下行:
delegated_creds=credentials.with_subject("someuser@yourdomain.com")
#where someuser@ is the email of the user that you're sending email as
之后,您可以使用delegated_creds
而不是creds
来调用服务。
此外,您似乎已经从 Google 的 指南中获得了示例,但请注意,您的示例创建了草稿而不是发送 email。发送电子邮件的 API 调用略有不同。 考虑到这一点,这是一个基于您的代码的完整示例,它对我有用:
#all the imports
SCOPES = ['https://mail.google.com/']
def main():
creds = None
creds = ServiceAccountCredentials.from_json_keyfile_name(
"""path_to_cred_file.json""", SCOPES)
delegated_creds=credentials.with_subject("someuser@yourdomain.com")
try:
# Call the Gmail API
service = build('gmail', 'v1', credentials=delegated_creds)
message = EmailMessage()
message.set_content('This is automated draft mail')
message['To'] = 'somemail@gmail.com'
message['From'] = 'somemail@gmail.com'
message['Subject'] = 'Automated draft'
encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
create_message = {
'raw': encoded_message
}
email = service.users().messages().send(userId="me",
body=create_message).execute()
except HttpError as error:
# TODO(developer) - Handle errors from gmail API.
print(f'An error occurred: {error}')
if __name__ == '__main__':
main()
最后,正如我链接的主题中所解释的那样,这仅适用于 Google Workspace 帐户,您不能将访问权限委托给免费的 Gmail 帐户,因此请记住这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.