如何代表其他用户创建 Google 日历事件?
How to create Google Calendar events on behalf of another user?
我想实现一个日程安排应用程序,其中 X 可以在特定时间创建事件并将其添加到他们的 Google 日历中。然后 Y 应该能够注册同一事件并将其添加到他们的 Google 日历中。 X 人也应该能够重新安排活动。我在理解如何设计时遇到了一些困难,希望得到一些指点。
所以 X 可以在客户端进行身份验证并创建事件,但随后服务器需要存储该事件 ID,以便 Y 可以注册。但是服务器如何代表 X 邀请 Y 呢?我正在尝试使用服务帐户进行身份验证,但当我尝试创建邀请服务器端并添加与会者时,我得到了 There was an error contacting the Calendar service: Error: Service accounts cannot invite attendees without Domain-Wide Delegation of Authority.
。这似乎是一个基本问题,服务帐户无法邀请随机参与者,除非他们在 GSuite 域中。
像 Calendly 这样的应用程序基本上可以做到这一点(你可以在别人的日历上注册,然后受邀参加他们组织的 Google 日历活动),所以我相信这是可行的。
这是我的基本测试代码:它在没有 attendees
字段的情况下工作,但如果设置它则会失败并出现上述错误。
import { google } from 'googleapis'
import * as SERVICE_ACCOUNT from './service-account.json'
const SCOPES = 'https://www.googleapis.com/auth/calendar';
const auth = new google.auth.JWT(
SERVICE_ACCOUNT.client_email,
null,
SERVICE_ACCOUNT.private_key,
SCOPES
)
console.log("Testing Google Calendar API")
const api = google.calendar({version : "v3", auth : auth})
api.events.insert({
calendarId: '{CALENDAR}@group.calendar.google.com',
requestBody: {
summary: 'Dope Test Event',
description: 'Wow this works!',
start: { dateTime: '2020-12-28T09:00:00-07:00', timeZone: 'America/Los_Angeles' },
end: { dateTime: '2020-12-28T10:00:00-07:00', timeZone: 'America/Los_Angeles' },
attendees: [
{ email: '{EMAIL}@gmail.com' } // works without this
]
}},
function (err, res) {
if(err) {
console.log(err)
} else {
console.log(res)
}
}
)
如错误信息所述:
Service accounts cannot invite attendees without Domain-Wide Delegation of Authority.
因此,您需要设置域范围的委派,这将允许服务帐户模拟用户 - 即代表用户行事。
要设置全域委派:
- 在 GCP 控制台中,通过继续
Actions-> Edit
,勾选您正在使用的服务帐户的复选框 Enable G Suite Domain-wide Delegation
- Enable the necessary scopes 通过继续
Security > API controls.
在您的管理控制台中委派服务帐户
修改您的代码如下:
const auth = new google.auth.JWT(
SERVICE_ACCOUNT.client_email,
null,
SERVICE_ACCOUNT.private_key,
SCOPES,
USER_EMAIL
)
其中 USER_EMAIL
是服务帐户应模拟的域用户的电子邮件。
推荐阅读:
https://developers.google.com/identity/protocols/oauth2/service-account#authorizingrequests
我想实现一个日程安排应用程序,其中 X 可以在特定时间创建事件并将其添加到他们的 Google 日历中。然后 Y 应该能够注册同一事件并将其添加到他们的 Google 日历中。 X 人也应该能够重新安排活动。我在理解如何设计时遇到了一些困难,希望得到一些指点。
所以 X 可以在客户端进行身份验证并创建事件,但随后服务器需要存储该事件 ID,以便 Y 可以注册。但是服务器如何代表 X 邀请 Y 呢?我正在尝试使用服务帐户进行身份验证,但当我尝试创建邀请服务器端并添加与会者时,我得到了 There was an error contacting the Calendar service: Error: Service accounts cannot invite attendees without Domain-Wide Delegation of Authority.
。这似乎是一个基本问题,服务帐户无法邀请随机参与者,除非他们在 GSuite 域中。
像 Calendly 这样的应用程序基本上可以做到这一点(你可以在别人的日历上注册,然后受邀参加他们组织的 Google 日历活动),所以我相信这是可行的。
这是我的基本测试代码:它在没有 attendees
字段的情况下工作,但如果设置它则会失败并出现上述错误。
import { google } from 'googleapis'
import * as SERVICE_ACCOUNT from './service-account.json'
const SCOPES = 'https://www.googleapis.com/auth/calendar';
const auth = new google.auth.JWT(
SERVICE_ACCOUNT.client_email,
null,
SERVICE_ACCOUNT.private_key,
SCOPES
)
console.log("Testing Google Calendar API")
const api = google.calendar({version : "v3", auth : auth})
api.events.insert({
calendarId: '{CALENDAR}@group.calendar.google.com',
requestBody: {
summary: 'Dope Test Event',
description: 'Wow this works!',
start: { dateTime: '2020-12-28T09:00:00-07:00', timeZone: 'America/Los_Angeles' },
end: { dateTime: '2020-12-28T10:00:00-07:00', timeZone: 'America/Los_Angeles' },
attendees: [
{ email: '{EMAIL}@gmail.com' } // works without this
]
}},
function (err, res) {
if(err) {
console.log(err)
} else {
console.log(res)
}
}
)
如错误信息所述:
Service accounts cannot invite attendees without Domain-Wide Delegation of Authority.
因此,您需要设置域范围的委派,这将允许服务帐户模拟用户 - 即代表用户行事。
要设置全域委派:
- 在 GCP 控制台中,通过继续
Actions-> Edit
,勾选您正在使用的服务帐户的复选框 - Enable the necessary scopes 通过继续
Security > API controls.
在您的管理控制台中委派服务帐户 修改您的代码如下:
Enable G Suite Domain-wide Delegation
const auth = new google.auth.JWT(
SERVICE_ACCOUNT.client_email,
null,
SERVICE_ACCOUNT.private_key,
SCOPES,
USER_EMAIL
)
其中 USER_EMAIL
是服务帐户应模拟的域用户的电子邮件。
推荐阅读:
https://developers.google.com/identity/protocols/oauth2/service-account#authorizingrequests