Microsoft Graph を使用して他人の予定を取得する方法について

こんにちは。Exchange サポートの益森です。
今回は、主に開発者向けの内容となります。
 
開発者の方から、他人の予定をプログラムで一括で取得したいというお問い合わせをいただくことがあります。
オンプレミス環境の場合は、EWS Managed API で実装する方法をご紹介させていただいたのですが、最近は REST API を使用して実装したいというお問い合わせも良くいただきます。

そのため、REST API の 1 つである Microsoft Graph を使用して他人の予定を取得する際にご注意いただきたい点について紹介いたします。

まず、Microsoft Graph を使用して予定を取得する場合によく利用される API は、calendarView です。
 
1) 自分の予定を取得するリクエストの例

https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=2018-07-01T19:00:00.0000000\&endDateTime=2018-07-10T19:00:00.0000000
 
2) 他人の予定を取得するリクエストの例

https://graph.microsoft.com/v1.0/users//calendar/calendarView?startDateTime=2017-07-01T19:00:00.0000000\&endDateTime=2018-07-10T19:00:00.0000000
 
- 参考情報
Title : calendarView を一覧表示する
URL : https://developer.microsoft.com/ja-jp/graph/docs/api-reference/v1.0/api/user_list_calendarview
 
また、こちらの API を使用するためには、事前にアプリケーションの登録を行い、アクセス トークンを取得する必要があります。
ご存知の方も多いと思いますが、 Web アプリで calendarView を実行する場合のアプリケーションの登録例を紹介します。
 
 <アプリケーションの登録例>

 1. 以下の URL にアクセスして、Azure Active Directory 管理センターにサインインします。

   https://aad.portal.azure.com/
 
 2. 左ペインより [Azure Active Directory] をクリックします。
 
 3. [アプリの登録] - [新しいアプリケーションの登録] をクリックします。
 
 4. 以下のように設定し、[作成] をクリックします。

   名前 : 任意のアプリケーションの名前を指定します (例 : MyMicrosoftGraphDemoApp01)
   アプリケーションの種類 : Web アプリ/API
   リダイレクト URI : アプリケーションで使用する URL (例 : https://test.contoso.com/MyMicrosoftGraphDemoApp01)
 
 5. [アプリケーション ID] の値を控えておきます。
 
 6. [設定] - [キー] をクリックします。
 
 7. キーの説明、有効期限を設定して [保存] をクリックします。
  ※保存時にキーが表示されるため控えておきます。
   絶対に漏洩しないよう管理してください。
 
 8. [設定] - [必要なアクセス許可] - [追加] - [API を選択します] をクリックします。
 
 9. [Microsoft Graph] を選択し、[選択] をクリックします。
 
 10. [委任されたアクセス許可] の中の [Read user and shared calendars] のチェックをオンにし、[選択] をクリックします。
   その他に必要なアクセス許可がある場合は適宜追加してください。
 
 11. [完了] をクリックします。
 
しかし、上記登録を行い、アクセス トークンを取得して他人の予定を取得しようとした際、以下のようなエラーが返される場合があります。

こちらは上記で委任したアクセス許可が不足しているのではなく、アクセスするユーザーが参照先のユーザーの予定表フォルダーに対してアクセス権がないことが原因です。
 
具体的には、ClendarView で他人の予定を取得する場合は、参照先のユーザーの予定表フォルダーに対して参照者以上の権限を持っている必要があります。
参照者の権限を持っている場合、例えばデスクトップ版の Outlook では、以下のように他人の予定をダブルクリックして本文まで見ることが可能になります。
※予定の件名や場所については一覧で見れるものの、本文は見れない場合は、"空き時間、件名、場所" までの権限しか持っていないと考えられます

以下は、参照先のユーザーの予定表フォルダーにて、参照元ユーザーに参照者の権限を付与する Exchange 管理コマンドの例です。

 
1) 既定のアクセス権を参照者に変更する場合

Set-MailboxFolderPermission -Identity <ユーザー名>:\<予定表フォルダーの名前> -User "Default" -AccessRights Reviewer

実行例)
Set-MailboxFolderPermission -Identity User01:\予定表 -User "Default" -AccessRights Reviewer

 
2) 特定のユーザーに参照権限を追加する場合

Add-MailboxFolderPermission -Identity User01:\<予定表フォルダーの名前> -User <権限を付与したいユーザー名> -AccessRights Reviewer

実行例)
Add-MailboxFolderPermission -Identity User01:\予定表 -User User02 -AccessRights Reviewer
 
- 参考情報
Title : Set-MailboxFolderPermission
URL : https://docs.microsoft.com/en-us/powershell/module/exchange/mailboxes/set-mailboxfolderpermission?view=exchange-ps

Title : Add-MailboxFolderPermission
URL : https://docs.microsoft.com/en-us/powershell/module/exchange/mailboxes/Add-MailboxFolderPermission?view=exchange-ps

また、上記のように予定表フォルダーの権限を変更することが難しい場合のアプローチについてご紹介させていただきます。

 
A) App-Only Token を取得して clendarView を実行する

こちらは、ユーザーの代理でアプリケーションの権限を使用して API を実行することで、参照元のユーザー自身が参照先のユーザーの予定表フォルダーに対して参照者の権限を持っていない場合でも情報の取得が可能になります。

EWS Managed API を使用した際の偽装アカウントを使用したアクセスのようなイメージとなります。

- 参考情報
Title : 方法:偽装を構成する
URL : https://msdn.microsoft.com/ja-jp/library/office/dn722376(v=exchg.150).aspx

Title : 方法:偽装するアカウントを指定する
URL : https://msdn.microsoft.com/ja-jp/library/office/dn722378(v=exchg.150).aspx

App-Only Token を取得するためには、Azure Active Directory 管理センターのアプリケーションの設定にて、以下のようにアプリケーションにアクセス許可を与えます。
 
1. [設定] - [必要なアクセス許可] - [追加] - [API を選択します] をクリックします。

2. [Microsoft Graph] を選択し、[選択] をクリックします。

3. [アプリケーションのアクセス許可] の中の [Read calendars in all mailboxes] のチェックをオンにし、[選択] をクリックします。

4. [保存] をクリックします。

5. [アクセス許可の付与] をクリックします。確認が表示されますので [はい] をクリックします。
 
そして、App-Only Token を取得するために、以下の HTTP リクエストを送信します。
 
<リクエスト内容>
POST https://login.microsoftonline.com/\<テナント名>.onmicrosoft.com/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&resource=https://graph.microsoft.com/&client_id=<アプリケーション ID>&client_secret=<キー>

 
以下は、リクエスト、レスポンスを Fiddler で採取した際のキャプチャです。

こちらで取得したトークンをデコードすると、以下のようにユーザーに関する情報がないことが確認出来ます。

上記で取得したアクセス トークンを使用して、calendarView のリクエストを行います。
アクセス トークンにユーザー情報が含まれていないため、リクエスト時に /me は使用できませんので必ず取得対象ユーザーを指定する必要があります。

 
B) findMeetingTimes を使用する
 
こちらは、clendarView を使用した予定の取得ではなく、会議の候補時間を取得する API となります。
こちらの API では出席者や会議の時間を指定することになりますが、ユーザーの予定表フォルダーに対して参照者の権限がない場合でも会議の候補時間を取得することが可能です。
 
詳細な使い方については以下の公開情報をご確認いただければと思います。
 
Title : user: findMeetingTimes
URL : https://developer.microsoft.com/ja-jp/graph/docs/api-reference/v1.0/api/user_findmeetingtimes
他人の予定を取得する目的が、適切な時間に会議を設定するための場合は、こちらの API を使用することで代替できる可能性があるため参考までにご紹介させていただきました。
 
今後とも、弊社サポート ブログをよろしくお願いいたします。

 
※本情報の内容(添付文書、リンク先などを含む)は、作成日時点でのものであり、予告なく変更される場合があります。