[英]Google Calendar API with domain wide delegation: events.watch method fails with "The request is missing a valid API key"
I have followed all of the steps for domain wide delegation.我已遵循域范围授权的所有步骤。 An example of this is the ability to sign in with the service account json, impersonate users in my Google Workspace account and list their events (see example below).
这方面的一个示例是能够使用服务帐户 json 登录,在我的 Google Workspace 帐户中模拟用户并列出他们的事件(参见下面的示例)。
# list-events.py
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
from pprint import pprint
def create_calendar_api_service(service_acc_filepath):
"""Build and return a Google Calendar service object authorized with the service
account that acts on behalf of a given user.
Args:
service_acc_filepath: path to service account json with domain wide delegation enabled.
"""
credentials = ServiceAccountCredentials.from_json_keyfile_name(
service_acc_filepath, scopes=str(SCOPES)
)
# impersonate user with emailaddress=calendarId
delegate = credentials.create_delegated(USER_EMAIL)
return build("calendar", "v3", credentials=delegate)
if __name__ == "__main__":
UUID = get_uuid()
SCOPES = "https://www.googleapis.com/auth/calendar"
SERVICE_ACCOUNT_FILE_PATH = "./workspace-sa/my-project-d2355248f03f.json"
USER_EMAIL = "workspace-user-1@company.com"
BASE_URL = "https://acf1-92-233-162-75.eu.ngrok.io"
# get authenticated object to interact with Google API.
my_service = create_query_api_service(SERVICE_ACCOUNT_FILE_PATH)
req = my_service.events().list(calendarId=f"{USER_EMAIL}").execute()
The problem I am having is that the same setup doesn't let me receive notifications from the watch() method...我遇到的问题是相同的设置不允许我从 watch() 方法接收通知...
# watch-for-events.py
...
body = {
"id": f"{UUID}",
"type": "webhook",
"address": f"{BASE_URL}/calendar-push", # The URL to which notifications are delivered for this channel.
}
my_service = create_calendar_api_service(SERVICE_ACCOUNT_FILE_PATH)
req = my_service.events().watch(calendarId=f"{USER_EMAIL}", body=body).execute()
Running the watch() method returns the following to the terminal.运行 watch() 方法将以下内容返回到终端。
{'expiration': '1669901130000',
'id': '0184a9d0-8b55-c62d-ee15-84891fcf1014',
'kind': 'api#channel',
'resourceId': '7kxHSfF9AbNVLSXk5cxPcmgfhAg',
'resourceUri': 'https://www.googleapis.com/calendar/v3/calendars/workspace-user-1%40company.com/events?alt=json'}
Upon following the resourceUri I see the aforementioned error message.在遵循 resourceUri 后,我看到了上述错误消息。
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"errors": [
{
"message": "The request is missing a valid API key.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
very single change in the target calendar hits my https webhook/endpoint with a 400 BAD REQUEST
.目标日历中的非常单一的更改会以
400 BAD REQUEST
命中我的 https webhook/端点。
I cannot even read the request in my Flask backend.我什至无法在我的 Flask 后端读取请求。
Can someone please help me understand why I am not able to receive push notifications (why they all return 400 BAD REQUEST)?有人可以帮我理解为什么我无法收到推送通知(为什么他们都返回 400 BAD REQUEST)?
PS: I have read that I can provide some further access credentials via a bearer token in the header. But there is no header attribute in these methods. PS:我读到我可以通过 header 中的不记名令牌提供一些进一步的访问凭证。但是这些方法中没有 header 属性。
Here are the images below for the workspace admin settings in question:以下是相关工作区管理员设置的图片:
@app.route("/calendar-push", methods=["GET", "POST"])
def add_message():
app.logger.info("HIT THE /calendar_push ROUTE")
content = request.json
app.logger.info(content)
return request.json
127.0.0.1 - - [24/Nov/2022 17:39:50] "POST /calendar-push HTTP/1.1" 400 -
'resourceUri': 'https://www.googleapis.com/calendar/v3/calendars/workspace-user-1%40company.com/events?alt=json'
'resourceUri':'https://www.googleapis.com/calendar/v3/calendars/workspace-user-1%40company.com/events?alt=json'
All that is is telling you what notification endpoint the message response is for.所有这些都是告诉您消息响应是针对哪个通知端点的。
In which case you will need to do a在这种情况下,您需要做一个
events = service.events().list(calendarId='workspace-user-1%40company.com').execute()
Your getting missing api key because your calling the endpoint without first being authorized.您缺少 api 密钥,因为您在未经授权的情况下调用端点。
Authorize the call then check it and you will get a response.授权调用然后检查它,您将得到响应。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.