Microsoftの開発者プログラムを使用してAPIでOutlookカレンダーに予定を登録してみた！

# 概要

Microsoftには開発者プログラムと言って無料でMicrosoftの機能を90日間使えるサービスがあります。
今回はMicrosoftの開発者プログラムで作成したアカウントで、AzureADにアプリを登録し、
APIを使ってOutlookカレンダーに予定を登録してみました！

大きく3点に分けてご説明します！
* 開発者プログラムの登録手順
* AzureADのアプリの登録
* APIを使用してカレンダーに予定を追加

### 環境
* macOS M1 Monterey Version 12.5.1

# 開発者プログラム登録手順

### 開発者プログラムの概要

開発者プログラムはMicrosoft365の検証やテストを行える環境を提供するプログラムです。

参考にしたサイト
https://kuroivlog.com/microsoft365_e5_enviroment

## 手順 1~15 工程

### 1. 下記 URL から開発者プログラムに参加

https://developer.microsoft.com/ja-JP/microsoft-365/dev-program

使用するアカウントでMicrosoftにサインインを行います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/1b08e6cb-d681-1e20-6197-0d4f1e99279f.png" width=700px>

### 2. 会社名等入力

国/地域、会社名、言語を入力し、次へ選択します。
個人開発ならば、会社名は適当でも使用できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/423328d6-2f93-e487-e133-bf9db9464b15.png" width=500px>

### 3. アンケートに回答

アンケートに当てはまる項目にチェックをつけます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/7556a996-df9b-5f70-da91-bf8245323d89.png" width=400px>

### 4. アンケートに回答

アンケートに当てはまる項目にチェックをつけます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/af15cc03-3b77-8732-2517-34bd9f3a4e81.png" width=400px>


### 5. サンドボックス(仮想環境)をセットアップ

サンドボックスをセットアップします。
インスタントサンドボックスを選択すると、自動的に16人の架空のユーザーアカウントが作成されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/1f69a277-860b-5779-ce84-572f66bad4f9.png" width=400px>

### 6. 管理者名/パスワード設定

管理者名/パスワード設定を設定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/083aff19-de13-81f9-4843-b29fdadb2388.png" width=300px>

### 7. 自身の電話番号で確認

本人確認のため、SMSメッセージを設定した電話番号に送り、コードを入力し設定します。
設定すると、開発者サブスクリプションのセットアップが行われます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/d69a58cb-c90b-b5bf-c0f8-424b071aae52.png" width=300px>

### 8. サブスクリプションに移動

サブスクリプションに移動するを押下します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/b700c4a9-272f-6b76-1f7e-eb65a8efdf8e.png" width=500px>

### 9. Microsoft Authenticator にてセキュリティ保護

使用しているスマートフォンのMicrosoft Authenticatorを使用します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/d2496dd3-7636-c3d5-26ca-60abc7d4fc27.png" width=400px>

### 10. Office 画面に自動で移動

Office画面に移動後、管理センターに移動します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/022b4477-91a4-f33d-94af-4a0f15cf3905.png" width=500px>

### 11. 管理センターからセットアップへ移動

移動後は、ガイド付きセットアップに移動を押下します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/7e2d4aab-510c-e9d6-2b46-2725b44bccea.png" width=500px>

### 12. Office のインストール

既にOfficeが入っている場合はインストール不要です。
まだ持っていない方はダウンロードしましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/a85b2119-5872-dd62-cb9c-2a3eec1b51b6.png" width=500px>

### 13. ドメインの作成

ドメインがない方は自動作成されるドメインを使用しましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/8e1d97ef-d800-8f9c-9c69-fb5fa594a3c4.png" width=500px>

### 14. ライセンスを割り当てるユーザー追加

自分を含め、既存で17名分のユーザーが作成されているため、
最大で8名まで新規にユーザーを追加することができます。
ユーザーはテスト用として架空のユーザー、もしくは実在するユーザーを追加可能です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/39d3df51-79ff-1ec5-7da1-b36257fc814c.png" width=500px>

### 15. セットアップ完了

これでセットアップ完了です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/a7d341e7-bb40-59d0-23d8-06398bc667a4.png" width=500px>


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/f9bd60c6-ca66-396e-a54a-35cfd75865be.png" width=600px>

---

# Microsoft Azure ADでアプリ登録

### Microsoft Azure Active Directory(Azure AD)とは
Azure Active Directory (Azure AD) は、クラウドベースのIDおよびアクセス管理サービスです。
このサービスは、従業員が Microsoft 365、Azure portalや、
その他のさまざまなSaaSアプリケーションなどの外部リソースにアクセスするのに役立ちます。 
さらに Azure Active Directory は、
会社のイントラネットネットワーク上のアプリなどの内部リソースと、
自分の組織向けに開発されたクラウドアプリにアクセスするのにも役立ちます。
さまざまな機能を保有していますが、
今回はAPIを通してOutlookカレンダーに予定を登録するので、アプリ登録を使用します。

### アプリ登録とは
Azure ADにはアプリ登録という項目があります。
Webアプリケーションで認証を行いたい場合や、
Webアプリケーション経由でマイクロソフトのクラウドサービスへ
APIアクセスしたい、などというときに利用するのが「アプリの登録」というメニューです。
MicorosoftのAPIを使用しても良い認証を受けるのに必要な機能で、
一般的な用語でサービスプリンシパルに該当します。

## 手順 1~8 工程

### 1. Azure ADを選択

先ほど登録した開発者プログラムのアカウントで[Azure Portal](https://portal.azure.com/#home)にログインします。
ログイン後、Azure Active Directoryを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/f97ca1e3-c703-2334-e809-6ab07252f5e6.png" width=600px>

### 2. アプリの新規登録

左側にあるタブからアプリの登録を選択し、アプリの新規登録をします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/afe92764-70b1-2197-4af2-8911bd50c48c.png" width=600px>

### 3. アプリの登録

任意の名前を記載します。
サポートされているアカウントの種類は、個人開発であるならば、`シングルテナント`を選択します。
他の組織に属するアカウントでも使用するならば、マルチテナントを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/2f87a156-12a6-b723-cbab-71feb6a1cb4d.png" width=500px>

### 4. クライアントシークレットIDを作成

`クライアントシークレットID`を作成します。
作成直後のみに値は表示されるため、保存しましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/15889571-9ea1-2edc-0a4b-635f97edc1e8.png" width=600px>

### 5. APIのアクセス許可を追加

APIのアクセス許可を追加を押下後、APIアクセス許可の要求に含まれる`Microsoft Graph`を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/866fa721-2e20-7f34-6622-e08890cfc913.png" width=600px>

### 6. アクセス許可の選択

アプリケーションに必要なアクセス許可の種類を選択します。
* 「委任されたアクセス許可」 ・・・ 指定したユーザーの権限で API を使用する
* 「アプリケーションの許可」 ・・・ AzureAD アプリに設定した権限で API を使用する

アプリケーションの許可は組織全体が使用できてしまう設定のため、注意が必要となります。
今回は委任されたアクセス許可を使用します。
カレンダーに予定を追加できる`Calendars.ReadWrite`を選択します。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/296838a0-e75d-01ae-b4d1-1123988c5cea.png" width=500px>

### 7. 管理者の同意を付与

管理者の同意を付与し、追加したアクセス許可を使用できる状態にします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/a31e2377-b0cf-d694-cdf1-dc4b0ba88b63.png" width=400px>

### 8. クライアントIDとテナントIDの取得

最後に概要から`クライアントID`と`テナントID`を取得します。
アプリの登録は以上となります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/3025aa8c-a963-5eb3-1405-3703a373770a.png" width=600px>

---

# APIを使用してカレンダーに予定を追加

## 手順 1~9 工程

### 1. Microsoftが提供しているクイックスタートをお借りする

アプリ登録を済ませたので、APIを叩く際に使用するアクセストークンを取得していきます。
下記を使用する場合、前提条件として`Node.js`を使用できる環境が必要です。
私の環境はv18.9.0で行いました。

https://github.com/microsoftgraph/msgraph-training-javascript

### 2. 必要な情報を追加

`demo/graphtutorial/node_modules/appSettings.example.js`
上記のJavaScriptファイルに必要な情報を追加します。
アクセス許可にカレンダーの読み書きを追加したため、
`graphUserScopes`には`calendars.readwrite`を定義します。

```js:JavaScript
const settings = {
  clientId: "アプリの登録で保存したクライアントID",
  clientSecret: "アプリの保存で登録したクライアントシークレットの値",
  tenantId: "アプリの登録で保存したテナントID",
  authTenant: "common",
  graphUserScopes: ["calendars.readwrite"],
};

module.exports = settings;
```

### 3. ファイル名を修正

先ほど情報を追加したファイル名を修正します。
```
appSettings.example.js → appSettings.js
```

### 4. ビルドして実行する

ターミナルで`demo/graphtutorial`ディレクトリまで移動し、下記のコマンドを実行します。

```
npm install
node index.js
```

### 5. Microsoftに認証を行う

実行が成功したときにターミナルに表示されるURLから認証を行います。
開発者プログラムで作成したアカウントを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/130b1198-b31f-76cf-8e5c-d0a3f1532cdc.png" width=400px>

ターミナルに表示されているコードを入力します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/068b5f1a-8976-755d-d747-90912d09b773.png" width=400px>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/82956dcc-e2df-49f2-f335-23fb9bacd654.png" width=400px>

### 6. アクセストークンを取得する

認証が完了すると下記の選択肢が表示されます。
[1]を選択し、アクセストークンを取得します。

```
[1] Display access token
[2] List my inbox
[3] Send mail
[4] List users (requires app-only)
[5] Make a Graph call
[0] Exit
```

### 7. RESTClientでAPIを叩く

VSコードの拡張機能の[RESTClient](https://marketplace.visualstudio.com/items?itemName=MadsKristensen.RestClient)を使用します。
最後にhttpファイルを作成し、RESTClientでAPIを叩きます。
API仕様は下記の公式ドキュメントを参考にします。
https://learn.microsoft.com/en-us/graph/api/calendar-post-events?view=graph-rest-1.0&tabs=http

使用したパラメータは下記の通りになります。
| パラメータ | 内容 |
|-|-|
| subject | タイトル/コメント |
| start | 終了時間 |
| end | 開始時間 |
| isAllDay | 終日 |
| location | 場所 |
| reminderMinutesBeforeStart | リマインダー機能 |
| attendees | 出席者追加 |
| transactionId | 予定の固有ID |

```:test.http
@host = https://graph.microsoft.com/v1.0

@accessToken = Bearer 取得したアクセストークン

#### "カレンダーにイベント(予定)を登録する"
POST {{host}}/me/calendar/events
Content-type: application/json
Authorization: {{accessToken}}

{
	"subject": "友達とキャンプ！",
	"body": {
		"contentType": "text",
		"content": "必要なものは肉とライター！"
	},
	"start": {
		"dateTime": "2022-10-07T00:00:00",
		"timeZone": "Tokyo Standard Time"
	},
	"end": {
		"dateTime": "2022-10-08T00:00:00",
		"timeZone": "Tokyo Standard Time"
	},
	"isAllDay": "true",
	"location": {
		"displayName": "ふもとっぱらキャンプ場"
	},
	"reminderMinutesBeforeStart": "30",
	"attendees": [
		{
			"emailAddress": {
				"address": "example@gmail.com",
				"name": "佐藤太郎"
			},
			"type": "required"
		}
	],
	"transactionId": "7E163156-7762-4BEB-A1C6-729EA8175511"
}
```

### 8. レスポンスの結果

ID等に関する情報は`xxx`で伏せております。

```
HTTP/1.1 201 Created
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; IEEE754Compatible=false; charset=utf-8
Content-Encoding: gzip
Location: https://graph.microsoft.com/v1.0/users('xxxxx')/events('xxxxxx')
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000
request-id: xxxxxx
client-request-id: xxxxxx
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"Japan East","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"xxxxxx"}}
Date: Tue, 29 Nov 2022 17:54:04 GMT
Connection: close

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('xxxx')/calendar/events/$entity",
  "@odata.etag": "xxxxxxxxx",
  "id": "xxxxx",
  "createdDateTime": "2022-11-29T17:54:03.025367Z",
  "lastModifiedDateTime": "2022-11-29T17:54:05.0106611Z",
  "changeKey": "xxxxxx",
  "categories": [],
  "transactionId": "xxxxx",
  "originalStartTimeZone": "Tokyo Standard Time",
  "originalEndTimeZone": "Tokyo Standard Time",
  "iCalUId": "xxxxxx",
  "reminderMinutesBeforeStart": 30,
  "isReminderOn": true,
  "hasAttachments": false,
  "subject": "xxxx",
  "bodyPreview": "xxxxx",
  "importance": "normal",
  "sensitivity": "normal",
  "isAllDay": true,
  "isCancelled": false,
  "isOrganizer": true,
  "responseRequested": true,
  "seriesMasterId": null,
  "showAs": "busy",
  "type": "singleInstance",
  "webLink": "xxxxx",
  "onlineMeetingUrl": null,
  "isOnlineMeeting": false,
  "onlineMeetingProvider": "unknown",
  "allowNewTimeProposals": true,
  "occurrenceId": null,
  "isDraft": false,
  "hideAttendees": false,
  "responseStatus": {
    "response": "organizer",
    "time": "0001-01-01T00:00:00Z"
  },
  "body": {
    "contentType": "html",
    "content": "xxxxxx"
  },
  "start": {
    "dateTime": "2022-10-07T00:00:00.0000000",
    "timeZone": "Tokyo Standard Time"
  },
  "end": {
    "dateTime": "2022-10-08T00:00:00.0000000",
    "timeZone": "Tokyo Standard Time"
  },
  "location": {
    "displayName": "xxxx",
    "locationType": "default",
    "uniqueId": "xxxx",
    "uniqueIdType": "private"
  },
  "locations": [
    {
      "displayName": "xxxx",
      "locationType": "default",
      "uniqueId": "xxxx",
      "uniqueIdType": "private"
    }
  ],
  "recurrence": null,
  "attendees": [
    {
      "type": "required",
      "status": {
        "response": "none",
        "time": "0001-01-01T00:00:00Z"
      },
      "emailAddress": {
        "name": "xxxx",
        "address": "xxx"
      }
    }
  ],
  "organizer": {
    "emailAddress": {
      "name": "xxx",
      "address": "xxxx"
    }
  },
  "onlineMeeting": null
}
```

### 9. Outlookカレンダーを確認してみる
無事にAPIを使用して登録されていることを確認できました！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634988/0c53388d-cc26-aeb1-56a5-7a10af6b587e.png" width=700px>

## 最後に
今回はMicrosoftの開発者プログラム作成からAPIを使用してOutlookカレンダー追加まで記載しました。
開発者プログラム作成・アプリの登録・APIを叩いてOutlookカレンダーに予定を登録等、
Microsoftの機能を無料でここまで触れることに驚きました。

シングルテナントで個人のみ使用できる設定にしていますが、
マルチテナントで複数人で使用できる設定にすれば、
相手側のOutlookに予定を入れたりと、より面白くなると思います。
また、アクセス許可をカレンダー関連のみにしていますが、他にもスコープがたくさん存在しているため、
開発者プログラムの期限が切れる90日間は楽しめそうです。
補足ですが、開発者プログラムは永久的に延長できるみたいです。
詳しく知りたい方は[こちら](https://learn.microsoft.com/en-us/office/developer-program/microsoft-365-developer-program-faq#how-long-is-my-subscription-good-for--and-when-does-it-expire-)をご確認ください。



MicrosoftのAPI調査でお困りの方の手助けになれば幸いです。