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

本頁面說明如何使用 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. 在左側窗格中,點選「服務」旁的「新增服務」圖示
  3. 選取「Google Calendar API」,然後按一下「新增」
  4. 啟用後,API 會顯示在左側窗格中。您可以在編輯器中使用 Calendar 關鍵字,列出 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. 選取左側的「編輯器」圖示 ,即可返回程式碼編輯器。

在指令碼中新增程式碼

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

  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」中,檢查指令碼執行結果。