この記事ではGoogle Calendar APIにサービスアカウントを使ってアクセスする方法を紹介します。
今回は以下のシナリオを前提に説明します。 Google Calendarのユーザ(User1)のアカウントでサービスアカウントを作成し、当該ユーザのカレンダーにアクセスできるようにします。
User1のカレンダーには1件のスケジュールが登録されています。
1. APIの有効化
Google CalendarのユーザアカウントでGoogle Cloud Platformにログインし、ナビゲーションメニューの[APIとサービス]から[ライブラリ]を開きます。 サービス一覧からGoogle Calendar APIを選択し、[有効にする]をクリックします。
2. サービスアカウントの作成
Google CalendarのユーザアカウントでGoogle Cloud Platformにログインします。
2.1 OAuth同意画面の作成
はじめにGoogle Calendar APIにアクセスするアプリを作成します。 ナビゲーションメニューの[APIとサービス]から[OAuth同意画面]を開きます。 [User Type]を選択し、[作成]をクリックします。 [User Type]はアプリの公開範囲に従って選択してください。 因みに「内部」はGoogle Workspace (旧G Suite)の組織内のアカウントの場合のみ選択可能です。
[アプリ名]に適当な名前を入力し、[ユーザサポートメール]、[デベロッパーの連絡先情報]にメールアドレスを入力します。
これ以降の画面では特に何も設定せず、すべて[保存して次へ]をクリックします。
2.2 サービスアカウントの作成
ナビゲーションメニューの[APIとサービス]から[認証情報]を開きます。 [認証情報の作成]を開き、[サービスアカウント]を選択します。
適当なサービスアカウント名を入力し、[完了]をクリックします。
2.3 サービスアカウントのキーの生成
サービスアカウント一覧から作成したサービスアカウントを選択し詳細画面を開きます。 [キー]タブを選択し、[鍵を追加]を開いて[新しい鍵を作成]をクリックします。
希望する鍵タイプをチェックし[作成]をクリックします。ここでは「JSON」を選択します。
鍵が生成されダウンロードされます。 このファイルは認証時に必要となりますので保管しておいてください。
3. サービスアカウントへのカレンダーの共有
サービスアカウントからアクセスするユーザ(user1@test.page)のカレンダーをサービスアカウントに共有します。 Google Calendarを開き、カレンダーのオーバーフローメニューを開いて(マウスオーバーすると表示されるアイコンをクリック)、[設定と共有]をクリックします。
[カレンダーの設定]を開き、[特定のユーザとの共有]セクションで[ユーザの追加]をクリックします。
サービスアカウントのメールアドレスを入力し、[権限]を選択して[送信]をクリックします。 今回は権限としてフルアクセスを行う「変更及び共有の管理権限」を選択しました。
以下のように共有にサービスアカウントが追加されたことを確認してください。
動作確認
それではJavaでサービスアカウントを使ったカレンダーの取得を試してみます。 以下のコードはUser1(カレンダーID : user1@test.page)のスケジュール一覧を取得します。 path/to/credentialにはステップ2.3で生成した鍵ファイルのパスを指定してください。
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("path/to/credential")) .createScoped(Collections.singleton(CalendarScopes.CALENDAR_EVENTS)); final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build(); Events events = service.events().list("user1@test.page").execute(); List<Event> items = events.getItems(); for (Event event : items) { DateTime start = event.getStart().getDateTime(); DateTime end = event.getEnd().getDateTime(); System.out.printf(event.getSummary() + " (" + start + " - " + end + ")"); }
上のコードを実行した結果を示します。 User1のスケジュールが取得できることを確認しました。
全体ミーティング(2021-02-16T15:00:00.000+09:00 - 2021-02-16T16:00:00.000+09:00)
これまでの手順で、サービスアカウントから個別のカレンダーのスケジュールを取得する方法を紹介しました。 他のカレンダーも取得できるようにする際はカレンダーごとにステップ3の共有設定を行ってください。
4. カレンダーリストへのカレンダーの追加
個別のユーザのスケジュールを取得するには各カレンダーのIDが分からないと取得できません。 ここではサービスアカウントが各ユーザのカレンダーIDを取得できるように、カレンダーリストにユーザのカレンダーを追加します。
通常、カレンダーリストへの追加はGoogle Calendarの[設定]の[カレンダーを追加]から行いますが、サービスアカウントはUI画面を持たないため画面から追加することができません。 そこでAPIを使ってカレンダーリストへ追加します。
以下のエンドポイントにPOSTメソッドを発行し、追加するカレンダーのIdを送信します。
https://www.googleapis.com/calendar/v3/users/me/calendarList
リクエストボディ:
{ "id": "<追加するカレンダーID>" }
curlでアクセスする場合以下のコマンドを実行します。 AuthorizationヘッダにはサービスアカウントのOAuthアクセストークンを指定してください。
curl --location --request POST "https://www.googleapis.com/calendar/v3/users/me/calendarList" --header "Authorization: Bearer <OAuthアクセストークン>" --header "Content-Type: text/plain" --data-raw "{ \"id\": \" <カレンダーID> \" }"
例:カレンダーリストにカレンダー(user1@test.page)を追加する
curl --location --request POST "https://www.googleapis.com/calendar/v3/users/me/calendarList" --header "Authorization: Bearer ya29.c.Kp4B-QdjWtz3XZoRt1Bt7EvMb29GxuH9frk66ZlsKeCxrTiExQkYUGZn4iiCrL9Utmr9ncHYxTDk1tNbrhnVoIEl8qkA69hsKN7UdVD96Lxo6GOGYICMrGIsjhx-joRrywJjT_APiBxEeLxJA2oVlAbtom_cBDbWW9Di3_wyU_sj45twaYmYqZcM4i1KiBrOtCfqOQAx49WjLcE7H3Ho6Bo" --header "Content-Type: text/plain" --data-raw "{ \"id\": \"user1@cdatatest.page\" }"
カレンダーリストからカレンダーを削除するには以下のエンドポイントにDELETEメソッドを発行します。
https://www.googleapis.com/calendar/v3/users/me/calendarList/<削除するカレンダーID>
例:カレンダーリストからuser1@test.pageのカレンダーを削除する
curl --location --request POST 'https://www.googleapis.com/calendar/v3/users/me/calendarList' \ --header 'Authorization: Bearer ya29.c.Kp4B-QdjWtz3XZoRt1Bt7EvMb29GxuH9frk66ZlsKeCxrTiExQkYUGZn4iiCrL9Utmr9ncHYxTDk1tNbrhnVoIEl8qkA69hsKN7UdVD96Lxo6GOGYICMrGIsjhx-joRrywJjT_APiBxEeLxJA2oVlAbtom_cBDbWW9Di3_wyU_sj45twaYmYqZcM4i1KiBrOtCfqOQAx49WjLcE7H3Ho6Bo' \ --header 'Content-Type: text/plain' \ --data-raw '{ "id": "user1@cdatatest.page" }'
動作確認
それではJavaでサービスアカウントを使ったカレンダーリストの取得を試してみます。
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(path/to/credential)) .createScoped(Collections.singleton(CalendarScopes.CALENDAR)); final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName(APPLICATION_NAME) .build(); String pageToken = null; do { CalendarList calendarList = service.calendarList().list().setPageToken(pageToken).execute(); List<CalendarListEntry> items = calendarList.getItems(); for (CalendarListEntry calendarListEntry : items) { System.out.println(calendarListEntry.getSummary()); } pageToken = calendarList.getNextPageToken(); } while (pageToken != null);
実行結果は以下の通りです。 カレンダーリストに登録されているUser1のカレンダーIDが取得できることを確認しました。
user1@test.page