gpt4 book ai didi

python - GmailAPI : "Error sending test message to Cloud PubSub projects/[project-id]/topics/[topic-id] : User not authorized to perform this action."?

转载 作者:行者123 更新时间:2023-12-03 08:20:06 32 4
gpt4 key购买 nike

我正在使用 Gmail API,并尝试使用 Python 3.9 设置推送通知。当我尝试在 Gmail 收件箱上调用 watch() 时,出现错误,即使我已遵循针对类似问题给出的所有建议。错误如下:

“向 Cloud PubSub 项目/[project-id]/topics/[topic-id] 发送测试消息时出错:用户无权执行此操作。”


到目前为止,我已经完成了以下工作:

  • 创建主题
  • 创建订阅
  • 手动发送和接收消息
  • 创建一个服务帐号,并授予“所有者”和“Cloud Pub/Sub 服务代理”权限
  • 对于该主题,将服务帐户设置为所有者
  • 对于订阅,请将服务帐户设置为所有者

就代码而言,我只是添加到 Google 提供的 Python Quickstart 文件 ( https://developers.google.com/gmail/api/quickstart/python ) 中。这是我添加的内容:

from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']

def main():
"""Shows basic usage of the Gmail API.
Lists the user's Gmail labels.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())


#NEW CODE I ADDED FOR watch()
service = build('gmail', 'v1', credentials=creds)

request = {
'labelIds': ['INBOX'],
'topicName': 'projects/[project-id]/topics/[topic-id]'
}

service.users().watch(userId='me', body=request).execute()

if __name__ == '__main__':
main()



编辑:

  1. 我在 Windows 笔记本电脑上的 Visual Studio Code 中运行它。我只是打开了一个新的 Python 文件。
  2. 这是 @gmail.com 帐户,而不是 GSuite 帐户
  3. 我正在使用服务帐户进行身份验证(creds 对象)

编辑2:我使用上面的凭据添加了完整文件。

最佳答案

更新答案

我已经测试了您的代码,并且遇到了同样的问题,但这是因为我故意跳过了一些步骤来弄清楚某些阶段会发生什么。

当我没有添加服务帐户时,我遇到了您的具体问题 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="77101a161e1b5a16071e5a0702041f37040e0403121a5910041205011e1412161414180219035914181a" rel="noreferrer noopener nofollow">[email protected]</a>作为相关主题的发布者。

请原谅我糟糕的绘画技巧: enter image description here


原始答案

所以问题是,您正在尝试使用服务帐户来验证 @gmail.com 帐户的 Gmail API 的 API 调用,我猜测遵循 this example .

唯一可行的方法是,如果您使用的帐户是 GSuite 帐户并且您正在使用域范围委派。 This doc (对于 Admin SDK,但其工作方式是相同的)解释了其工作原理。它不适用于您,但为了完整起见,我添加了此内容。

服务帐户不能用于验证 @gmail.com 帐户的请求。

它们可以用于验证自己的 GSuite 相关 API,例如 GDrive、GDocs 等,但它们基本上用于验证自己的帐户,而不是 @gmail.com 帐户。我不会详细介绍这一点,因为这并不完全相关,而且这是一个有点奇怪的兔子洞,即使爱丽丝也无法摆脱。

要将 Gmail API 与您的 @gmail.com 帐户结合使用,您需要按照快速入门 you linked 中的说明创建 creds 对象。所以请求得到 authenticated using the credentials for your @gmail.com account 。您只需执行一次此操作,并将生成的 JSON 凭证文件保存在某处,以便您可以重复使用它。它将一直有效,直到您撤销它为止。

请注意the docs还声明您需要使用标准 Gmail API 身份验证。


下面的部分创建 JSON 文件,您可以使用该文件通过登录时使用的 @gmail.com 帐户对 Gmail API 的请求进行身份验证。

        # Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())

您可以使用这部分将凭据加载到 creds 对象中,然后只需使用您已有的代码就可以了...

    if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)

我不能 100% 确定您是否需要授予 GCloud 项目本身的权限,但您可以通过完成快速入门的其余部分来测试 Gmail 信用对象是否有效,并查看是否可以获得该项目的标签。 @gmail.com 帐户。如果此方法有效,但您仍然收到 403 错误,请尝试向 @gmail.com 帐户授予您向服务帐户授予的 Pub/Sub IAM 权限。

关于python - GmailAPI : "Error sending test message to Cloud PubSub projects/[project-id]/topics/[topic-id] : User not authorized to perform this action."?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68091042/

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