本页介绍了如何使用 Google Calendar API 创建用于显示 Google 日历用户状态的活动。状态事件用于描述用户所在的位置或正在执行的操作,包括用户是否处于专注时间、外出或在特定位置工作。
在 Google 日历中,用户可以创建专注时间、不在办公室和工作地点活动,以指明其自定义状态和地点。这些功能仅适用于主日历,并且仅面向部分 Google 日历用户提供。
如需了解详情,请参阅在 Google 日历中使用专注时间和为用户启用或停用工作地点。
读取和列出日历状态事件
您可以在 Calendar API 的 Events
资源中读取和列出日历状态事件。
如需读取状态事件,请使用 events.get
方法,指定事件的 eventId
。
如需列出状态事件,请使用 events.list
方法,在 eventTypes
字段中指定以下一个或多个值:
'focusTime'
'outOfOffice'
'workingLocation'
然后,在返回的 Event
对象中,检查 eventType
字段是否具有请求的值,并参阅相应字段,了解用户在 Google 日历中创建的状态的详细信息:
订阅状态事件的更改
您可以在 Calendar API 的 Events
资源中订阅状态事件的更改。
使用 events.watch
方法,在 eventTypes
字段中指定要订阅的日历的 calendarId
,以及以下一个或多个值:
'focusTime'
'outOfOffice'
'workingLocation'
创建和更新日历状态事件
如需创建状态事件,您可以使用 events.insert
方法创建 Events
资源的实例,并为事件类型设置所需字段。
如果您使用 events.update
方法更新状态事件,则该事件必须保留必需字段。
创建专注时间
如需创建专注时间活动,请执行以下操作:
- 将
eventType
设置为'focusTime'
。 - 添加
focusTimeProperties
字段。 - 将
transparency
字段设置为'opaque'
。 - 将活动的
start
和end
字段设置为限时活动(指定了开始时间和结束时间)。
“专注时间”不能是全天活动。
如需了解功能详情,请参阅在 Google 日历中使用专注时间
创建“不在办公室”回复
如需创建外出事件,请执行以下操作:
- 将
eventType
设置为'outOfOffice'
。 - 添加
outOfOfficeProperties
字段。 - 将
transparency
字段设置为'opaque'
。 - 将活动的
start
和end
字段设置为限时活动(指定了开始时间和结束时间)。
“不在办公室”活动不能是全天活动。
如需了解该功能的详细信息,请参阅显示您不在办公室
创建工作地点
如需创建工作地点事件,请执行以下操作:
- 将
eventType
设置为'workingLocation'
。 - 添加
workingLocationProperties
字段。 - 将
visibility
字段设置为'public'
。 - 将
transparency
字段设置为'transparent'
。 -
- 定时事件(指定了开始时间和结束时间);
- 全天活动(指定了开始日期和结束日期),时长正好是一天。
全天工作地点活动不能跨多天,但定时活动可以。
以下字段为选填字段,但建议您在插入 officeLocation
时提供这些字段,以便获得最佳用户体验:
workingLocationProperties.officeLocation.buildingId
:此值应与组织的资源数据库中的buildingId
相匹配。这有助于用户获享 Google 日历的所有功能,例如会议室建议。workingLocationProperties.officeLocation.label
:这是 Google 日历网页版和移动客户端上显示的标签。您可以使用resources.buildings.list
方法提取建筑物 ID 和建筑物标签。
不支持通过批量端点创建和更新工作位置事件。
如需了解该功能的详细信息,请参阅设置工作时间和地点以及为用户启用或停用工作地点
如何显示重叠的工作地点活动
用户的日历中可以同时有多个重叠的工作地点事件,这意味着任何给定时间都可以设置多个工作地点。如果只能向用户显示一个位置,则应在多个应用中一致地向用户显示该位置。在执行此操作时,请遵循以下准则来选择要显示的事件:
- 设有时间的活动优先于全天活动。
- 单次事件优先于周期性事件及其例外情况。
- 开始时间较晚的事件优先于开始时间较早的事件。
- 时长较短的事件优先于时长较长的事件。
- 创建时间较晚的事件优先于创建时间较早的事件。
- 部分重叠的活动应显示为两个不同的活动,每个活动都有自己的工作地点。
在 Google Apps 脚本中创建状态事件
Google Apps 脚本是一种基于 JavaScript 的云脚本语言,可让您构建可与 Google Workspace 集成的商务应用。脚本是在基于浏览器的代码编辑器中开发的,并存储在 Google 的服务器上并在其上运行。另请参阅 Google Apps 脚本快速入门,开始使用 Apps 脚本向 Google 日历 API 发送请求。
以下说明介绍了如何在 Google Apps 脚本中将 Google Calendar API 用作高级服务来管理状态事件。如需查看 Google 日历 API 资源和方法的完整列表,请参阅参考文档。
创建并设置脚本
- 前往 script.google.com/create 创建脚本。
- 在左侧窗格中,点击“服务”旁边的“添加服务”图标 。
- 选择 Google Calendar API,然后点击添加。
- 启用后,该 API 会显示在左侧窗格中。您可以在编辑器中使用 Calendar 关键字列出 API 中的可用方法和类。
(可选)更新 Google Cloud 项目
每个 Google Apps 脚本项目都有一个关联的 Google Cloud 项目。您的脚本可以使用 Google Apps 脚本自动创建的默认项目。如果您想使用自定义 Google Cloud 项目,请按照以下步骤更新与脚本关联的项目。
- 在编辑器的左侧,点击“Project Settings”(项目设置)图标 。
- 在 Google Cloud Platform (GCP) Project(Google Cloud Platform [GCP] 项目)下,点击 Change project(更改项目)。
- 输入参与开发者预览版计划的 Google Cloud 项目的项目编号,然后点击设置项目。
- 在左侧,选择“编辑器”图标 返回代码编辑器。
向脚本添加代码
以下代码示例展示了如何在主要日历中创建、读取和列出状态事件。
将以下代码粘贴到代码编辑器中。
/** Creates a focus time event. */ function createFocusTime() { const event = { start: { dateTime: '2023-11-14T10:00:00+01:00' }, end: { dateTime: '2023-11-14T12:00:00+01:00' }, eventType: 'focusTime', focusTimeProperties: { chatStatus: 'doNotDisturb', autoDeclineMode: 'declineOnlyNewConflictingInvitations', declineMessage: 'Declined because I am in focus time.', } } createEvent(event); } /** Creates an out of office event. */ function createOutOfOffice() { const event = { start: { dateTime: '2023-11-15T10:00:00+01:00' }, end: { dateTime: '2023-11-15T18:00:00+01:00' }, eventType: 'outOfOffice', outOfOfficeProperties: { autoDeclineMode: 'declineOnlyNewConflictingInvitations', declineMessage: 'Declined because I am on vacation.', } } createEvent(event); } /** Creates a working location event. */ function createWorkingLocation() { const event = { start: { date: "2023-06-01" }, end: { date: "2023-06-02" }, eventType: "workingLocation", visibility: "public", transparency: "transparent", workingLocationProperties: { type: 'customLocation', customLocation: { label: "a custom location" }, } } createEvent(event); } /** * Creates a Calendar event. * See https://developers.google.com/calendar/api/v3/reference/events/insert */ function createEvent(event) { const calendarId = 'primary'; try { var response = Calendar.Events.insert(event, calendarId); var event = (response.eventType === 'workingLocation') ? parseWorkingLocation(response) : response; console.log(event); } catch (exception) { console.log(exception.message); } } /** * Reads the event with the given eventId. * See https://developers.google.com/calendar/api/v3/reference/events/get */ function readEvent() { const calendarId = 'primary'; // Replace with a valid eventId. const eventId = "sample-event-id"; try { var response = Calendar.Events.get(calendarId, eventId); var event = (response.eventType === 'workingLocation') ? parseWorkingLocation(response) : response; console.log(event); } catch (exception) { console.log(exception.message); } } /** Lists focus time events. */ function listFocusTimes() { listEvents('focusTime'); } /** Lists out of office events. */ function listOutOfOffices() { listEvents('outOfOffice'); } /** Lists working location events. */ function listWorkingLocations() { listEvents('workingLocation'); } /** * Lists events with the given event type. * See https://developers.google.com/calendar/api/v3/reference/events/list */ function listEvents(eventType = 'default') { const calendarId = 'primary' // Query parameters for the list request. const optionalArgs = { eventTypes: [eventType], showDeleted: false, singleEvents: true, timeMax: '2023-04-01T00:00:00+01:00', timeMin: '2023-03-27T00:00:00+01:00', } try { var response = Calendar.Events.list(calendarId, optionalArgs); response.items.forEach(event => console.log(eventType === 'workingLocation' ? parseWorkingLocation(event) : event)); } catch (exception) { console.log(exception.message); } } /** * Parses working location properties of an event into a string. * See https://developers.google.com/calendar/api/v3/reference/events#resource */ function parseWorkingLocation(event) { if (event.eventType != "workingLocation") { throw new Error("'" + event.summary + "' is not a working location event."); } var location = 'No Location'; const workingLocation = event.workingLocationProperties; if (workingLocation) { if (workingLocation.type === 'homeOffice') { location = 'Home'; } if (workingLocation.type === 'officeLocation') { location = workingLocation.officeLocation.label; } if (workingLocation.type === 'customLocation') { location = workingLocation.customLocation.label; } } return `${event.start.date}: ${location}`; }
运行代码示例
- 在代码编辑器上方,从下拉菜单中选择要运行的函数,然后点击运行。
- 首次执行时,系统会提示您授予访问权限。查看并允许 Apps Script 访问您的日历。
- 您可以在窗口底部显示的执行日志中检查脚本执行结果。