gpt4 book ai didi

python - 使用 python 在 Gmail 中发送邮件

转载 作者:行者123 更新时间:2023-12-02 02:56:41 24 4
gpt4 key购买 nike

我尝试使用 Gmail API 发送一封简单的测试电子邮件,但对于我找到的每个代码示例,我不断收到相同的错误。

我现在的代码是这样的:

def validationService():
SCOPES = ['https://mail.google.com/']
SERVICE_ACCOUNT_FILE = 'creds.json'
creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)

service = build('gmail', 'v1', credentials=creds)
return service


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


def CreateMessage(sender, to, subject, message_text):
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_string().encode()).decode()}

service = validationService()

email = CreateMessage("<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6310060d0706110e020a0f23040e020a0f4d000c0e" rel="noreferrer noopener nofollow">[email protected]</a>", "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef9d8a8c8a86998a9d9d828e8683af88828e8683c18c8082" rel="noreferrer noopener nofollow">[email protected]</a>", "Test", "This is a test")

sent = SendMessage(service, "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7a091f141e1f08171b13163a1d171b131654191517" rel="noreferrer noopener nofollow">[email protected]</a>", email)

返回

>>> An error occurred: <HttpError 400 when requesting https://www.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Bad Request">

我也不明白 CreateMessage 中的“sender”参数和 SendMessage 中的 userId 之间的区别。

如果有目的,我正在使用服务帐户凭据

-谢谢!

最佳答案

当使用 service account 时与 Gmail API 。您需要设置domain-wide delegation ,这允许服务帐户模拟 G Suite domain 中的任何用户。因此,您必须拥有 G Suite 帐户才能使用域范围委托(delegate),如文档所述:

If you have a G Suite domain—if you use G Suite, for example—an administrator of the G Suite domain can authorize an application to access user data on behalf of users in the G Suite domain.

那么现在,为什么需要冒充用户(真人)?这是因为服务帐户是一个机器人(不是真人),用于服务器到服务器的交互,使您的应用程序可以调用 Google API,尽管服务帐户有一个名为 client_email 的参数。 ,其结构类似于 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="deb0bfb3bb9eaeacb1b4bbbdaaf3acbfb0bab1b3b0abb3bcbbacf0b7bfb3f0b9adbbaca8b7bdbbbfbdbdb1abb0aaf0bdb1b3" rel="noreferrer noopener nofollow">[email protected]</a>这不是一封属于真人的真实电子邮件(我知道这有点令人困惑)。

话虽如此,我对您的代码做了一些更改。首先,我修改了你的validationService函数以便使用域范围委托(delegate)构建服务。

def validationService():
# Set the crendentials
credentials = service_account.Credentials.\
from_service_account_file(SERVICE_ACCOUNT_FILE, scopes= SCOPES)
# Delegate the credentials to the user you want to impersonate
delegated_credentials = credentials.with_subject(USER_EMAIL)
service = discovery.build('gmail', 'v1', credentials=delegated_credentials)
return service

在您的 SendMessage 中功能不一定是传递要发送电子邮件的用户。使用 me 就足够了,因为 Users.messages: send Parameters状态:

userId string The user's email address. The special value me can be used to indicate the authenticated user.

def SendMessage(service, message):
message = service.users().messages().send(userId="me", body=message).execute()
return message

最后的整个代码可能如下所示:

from googleapiclient import discovery, errors
from oauth2client import file, client, tools
from google.oauth2 import service_account
from email.mime.text import MIMEText
import base64

SERVICE_ACCOUNT_FILE = 'service_account.json'
SCOPES = [' https://mail.google.com/']
# The user we want to "impersonate"
USER_EMAIL = "user@domain"


def validationService():
# Set the crendentials
credentials = service_account.Credentials.\
from_service_account_file(SERVICE_ACCOUNT_FILE, scopes= SCOPES)
# Delegate the credentials to the user you want to impersonate
delegated_credentials = credentials.with_subject(USER_EMAIL)
service = discovery.build('gmail', 'v1', credentials=delegated_credentials)
return service


def SendMessage(service, message):
message = service.users().messages().send(userId="me", body=message).execute()
return message


def CreateMessage(sender, to, subject, message_text):
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_string().encode()).decode()}


def main():
try:
service = validationService()
email = CreateMessage(USER_EMAIL, "receiverrmail@domain", "Test", "This is a test")
email_sent = SendMessage(service, email)
print('Message Id:', email_sent['id'])
except errors.HttpError as err:
print('\n---------------You have the following error-------------')
print(err)
print('---------------You have the following error-------------\n')


if __name__ == '__main__':
main()

通知

您还需要通过设置 Managing API client access 来允许您的服务帐号在使用域范围委派时访问 Google 的 API在您的 G Suite 帐户中。

关于python - 使用 python 在 Gmail 中发送邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60961428/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com