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

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

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

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

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

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

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

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

  • '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 つの場所のみを表示できる状況では、複数のアプリでその場所を一貫して表示する必要があります。その場合は、次のガイドラインに沿って、表示するイベントを選択してください。

  • 終日イベントよりも時間指定イベントが優先されます。
  • 単一の予定は、定期的な予定とその例外よりも優先されます。
  • 後から開始されたイベントは、それより前に開始されたイベントよりも優先されます。
  • 期間が短いイベントは、期間が長いイベントよりも優先されます。
  • 最近作成されたイベントは、以前に作成されたイベントよりも優先されます。
  • 部分的に重複する予定は、それぞれ別の勤務場所を持つ 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 が左側のペインに表示されます。エディタで Calendar キーワードを使用すると、API で使用可能なメソッドとクラスを一覧表示できます。

(省略可)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. ウィンドウの下部に表示される実行ログで、スクリプト実行の結果を調べることができます。