管理專注時間、不在辦公室和工作地點活動

本頁面說明如何使用 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 方法,指定要訂閱的日曆 calendarId,並在 eventTypes 欄位中指定下列一或多個值:

  • 'focusTime'
  • 'outOfOffice'
  • 'workingLocation'

建立及更新日曆狀態活動

如要建立狀態事件,請使用 events.insert 方法建立 Events 資源的執行個體,並設定事件類型的必填欄位。

如果您使用 events.update 方法更新狀態事件,事件必須保留必填欄位。

建立專注時間

如何建立專注時間活動:

  • eventType 設為 'focusTime'
  • 加入 focusTimeProperties 欄位。
  • 將「transparency」欄位設為 'opaque'
  • 將事件的 startend 欄位設為計時事件 (需指定開始和結束時間)。
    專注時間不得為全天活動。

如要進一步瞭解功能,請參閱「在 Google 日曆中使用專注時間」一文

建立不在辦公室

如何建立不在辦公室的活動:

  • eventType 設為 'outOfOffice'
  • 加入 outOfOfficeProperties 欄位。
  • 將「transparency」欄位設為 'opaque'
  • 將事件的 startend 欄位設為計時事件 (需指定開始和結束時間)。
    不在辦公室的活動不得為全天活動。

如要進一步瞭解功能,請參閱「顯示你不在辦公室的時間」。

建立工作地點

如何建立工作地點活動:

  • eventType 設為 'workingLocation'
  • 加入 workingLocationProperties 欄位。
  • visibility 欄位設為 'public'
  • 將「transparency」欄位設為 'transparent'
  • 將事件的 startend 欄位設為以下任一項:

    • 計時事件 (包含指定的開始和結束時間);
    • 為期一天的全天事件 (已指定開始和結束日期)。

    「全天工作地點」事件不能橫跨多天,但具時效性事件可以。

下列為選用欄位,但建議您使用,以便在插入 officeLocation 時提供最佳使用者體驗:

不支援透過批次端點建立及更新工作地點事件。

如需功能詳細資料,請參閱「設定工作時間與地點」和「為使用者開啟或關閉工作地點」。

如何顯示重疊的工作地點事件

使用者可以同時在日曆中設定多個工作地點,這些活動會重疊,也就是說,任何指定時間都可能設定多個工作地點。在只能向使用者顯示單一地點的情況下,使用者應在多個應用程式中一致地顯示這個位置。執行方法時,請按照下列指南選擇要顯示的事件:

  • 定時事件會優先於全天事件。
  • 單一事件的優先順序高於週期性事件及其例外狀況
  • 稍後開始的事件優先於稍早開始的事件。
  • 持續時間較短的事件優先於持續時間較長的事件。
  • 較近期建立的事件優先於先前建立的事件。
  • 部分重疊的事件應顯示為兩個不同的事件,每個事件都有各自的工作地點。

在 Google Apps Script 中建立狀態事件

Google Apps Script 是一種以 JavaScript 為基礎的雲端指令碼語言,可讓您建構與 Google Workspace 整合的業務應用程式。指令碼是使用以瀏覽器為基礎的程式碼編輯器開發,並儲存在 Google 伺服器中。另請參閱 Google Apps Script 快速入門導覽課程,瞭解如何開始使用 Apps Script 將要求傳送至 Google Calendar API。

以下操作說明說明如何使用 Google Calendar API 做為 Google Apps Script 中的進階服務,管理狀態事件。如需 Google Calendar API 資源和方法的完整清單,請參閱參考說明文件

建立及設定指令碼

  1. 前往 script.google.com/create 建立指令碼。
  2. 在左側窗格中,按一下「Services」旁邊的「Add a service」圖示
  3. 選取「Google Calendar API」,然後按一下「新增」
  4. 啟用後,API 會顯示在左側窗格中。在編輯器中,使用「日曆」關鍵字即可列出 API 的可用方法和類別。

(選用) 更新 Google Cloud 專案

每項 Google Apps Script 專案都有相關聯的 Google Cloud 專案。您的指令碼可以使用 Google Apps Script 自動建立的預設專案。如要使用自訂 Google Cloud 專案,請按照下列步驟更新與指令碼相關聯的專案。

  1. 在編輯器左側,按一下「Project Settings」圖示
  2. 按一下「Google Cloud Platform (GCP) 專案」下方的「變更專案」
  3. 輸入開發人員預覽版計畫中的 Google Cloud 專案編號,然後按一下「設定專案」
  4. 選取左側的「Editor」,返回程式碼編輯器。

將程式碼加入指令碼

下列程式碼範例說明如何建立、讀取及列出主要日曆上的狀態事件。

  1. 將下列程式碼貼入程式碼編輯器。

    /** 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}`;
    }
    

執行程式碼範例

  1. 在程式碼編輯器上方,從下拉式選單中選取要執行的函式,然後按一下「Run」
  2. 第一次執行時,系統會提示您授予存取權。檢查並允許 Apps Script 存取您的日曆。
  3. 您可以在視窗底部的「Execution Log」中查看指令碼執行結果。