サイレント モード、不在、勤務場所の予定を管理する

このページでは、Google Calendar API を使用して Google カレンダー ユーザーのステータスを表す予定を作成する方法について説明します。ステータス イベントは、ユーザーの現在地や作業内容(サイレント モード中、不在、特定の場所での勤務など)を表します。

Google カレンダーでは、サイレント モード、不在、勤務場所の予定を作成して、カスタム ステータスと場所を示すことができます。これらの機能は、メイン カレンダーと、一部の Google カレンダー ユーザーにのみご利用いただけます。

詳しくは、Google カレンダーでサイレント モードを使用するユーザーの勤務場所を有効または無効にするをご覧ください。

カレンダーのステータス イベントを読み取り、一覧表示する

Calendar API の Events リソースを使用すると、カレンダーのステータス イベントの読み取りと一覧表示を行うことができます。

ステータス イベントを読み取るには、イベントの eventId を指定して events.get メソッドを使用します。

ステータス イベントを一覧表示するには、events.list メソッドを使用し、eventTypes フィールドに次のいずれかの値を指定します。

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

次に、返された Event オブジェクトで、eventType フィールドにリクエストされた値が含まれていることを確認します。また、Google カレンダーでユーザーが作成したステータスの詳細については、対応するフィールドを参照します。

ステータス イベントの変更を受け取る

Calendar API の Events リソースで、ステータス イベントの変更通知を受け取ることができます。

events.watch メソッドを使用して、定期購入するカレンダーの calendarId と、eventTypes フィールドに次の値の 1 つ以上を指定します。

  • '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' に設定します。
  • イベントの start フィールドと end フィールドを次のいずれかに設定します。

    • 時刻指定のイベント(開始時間と終了時間を指定)
    • 1 日間(開始日と終了日が指定されている)の終日イベント。

    終日の勤務場所の予定は複数日にまたがって設定できませんが、時刻指定の予定は複数日にまたがって設定できます。

次のフィールドは省略可能ですが、officeLocation を挿入する際のユーザー エクスペリエンスを向上させるために指定することをおすすめします。

バッチ エンドポイントを介して勤務地イベントを作成および更新することはできません。

機能の詳細については、業務時間と勤務場所を設定するユーザーの勤務場所を有効または無効にするをご覧ください。

重複する勤務場所の予定を表示する方法

ユーザーのカレンダーで同時に複数の勤務場所の予定が重複して表示されることがあります。つまり、任意の時間に複数の勤務場所が設定されることがあります。ユーザーに表示できる場所が 1 つしかない場合は、複数のアプリでその場所を常に表示する必要があります。この場合、表示するイベントは次のガイドラインに沿って選択してください。

  • 時刻指定の予定は、終日の予定よりも優先されます。
  • 1 回限りの予定は、定期的な予定とその例外よりも優先されます。
  • 後で開始するイベントは、それより前に開始するイベントよりも優先されます。
  • 長さが短いイベントは、長さが長いイベントよりも優先されます。
  • 最近作成されたイベントは、それより前に作成されたイベントよりも優先されます。
  • 部分的に重複するイベントは、それぞれが独自の勤務地を持つ 2 つの異なるイベントとして表示する必要があります。

Google Apps Script でステータス イベントを作成する

Google Apps Script は、Google Workspace と統合されたビジネス アプリケーションを構築できる JavaScript ベースのクラウド スクリプト言語です。スクリプトはブラウザベースのコードエディタで開発され、Google のサーバーに保存され、実行されます。Apps Script を使用して Google Calendar API にリクエストを送信するには、Google Apps Script クイックスタートもご覧ください。

次の手順では、Google Apps Script の拡張サービスとして Google Calendar API を使用し、ステータス イベントを管理する方法について説明します。Google Calendar API のリソースとメソッドの一覧については、リファレンス ドキュメントをご覧ください。

スクリプトを作成して設定する

  1. script.google.com/create に移動してスクリプトを作成します。
  2. 左側のペインで、[サービス] の横にある [サービスを追加] をクリックします。
  3. [Google Calendar API] を選択し、[追加] をクリックします。
  4. 有効にすると、API が左側のペインに表示されます。API で使用可能なメソッドとクラスは、エディタで Calendar キーワードを使用して一覧表示できます。

(省略可)Google Cloud プロジェクトを更新する

各 Google Apps Script プロジェクトには、関連付けられた Google Cloud プロジェクトがあります。スクリプトでは、Google Apps Script が自動的に作成するデフォルト プロジェクトを使用できます。カスタムの Google Cloud プロジェクトを使用する場合は、次の手順でスクリプトに関連付けられたプロジェクトを更新します。

  1. エディタの左側にあるプロジェクト設定アイコン をクリックします。
  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. コードエディタの上にあるプルダウン メニューから実行する関数を選択し、[実行] をクリックします。
  2. 最初の実行で、アクセスの承認を求められます。Apps Script によるカレンダーへのアクセスを確認して、許可してください。
  3. スクリプトの実行結果は、ウィンドウの下部に表示される [実行ログ] で確認できます。