首页 > 解决方案 > 如何代表其他用户创建 Google 日历活动?

问题描述

我想实现一个日程安排应用程序,其中人 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)
        }
    }
)

标签: securityauthenticationgoogle-apigoogle-oauthgoogle-calendar-api

解决方案


正如错误消息所说:

没有全域授权的服务帐户无法邀请与会者。

因此,您需要设置域范围的委派,这将允许服务帐户模拟用户 - 即代表用户行事。

要设置域范围的委派:

  • 在 GCP 控制台中,勾选Enable G Suite Domain-wide Delegation您正在使用的服务帐户的复选框,继续Actions-> Edit
  • 通过继续修改您的代码,在管理控制台中为委派服务帐户启用必要的范围 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


推荐阅读