Microsoft Graph API を Ruby で操作してみる

タイトル通り、Microsoft Graph API を Ruby で操作してました。
パッと検索してもあまりわかりやすい情報が出てこなかったため、手順をメモ書きしておきます。

## 準備編

### 1. Microsoft Azure にサインイン

[Microsoft Azure](https://portal.azure.com/) にアクセスし、Microsoftアカウントでサインインします。

![スクリーンショット 2024-05-19 19.06.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/45201e0a-e8ef-d2ff-de8d-b791a6774bf6.png)


### 2. アプリを作成

サインインに成功したら、[アプリの登録](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade) からアプリを新規作成します。

![スクリーンショット 2024-05-19 20.06.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/f9d9ca52-0e44-36cf-ca55-fdfb447f0e79.png)

- 名前
    - test
- サポートされているアカウントの種類
    - 任意の組織ディレクトリ内のアカウント（任意の Microsoft Entra ID テナント - マルチテナント）と個人用の Microsoft アカウント（Skype、Xbox など）
- リダイレクト URI
    - http://localhost:3000/auth/microsoft_graph/callback

### 3. API のアクセス許可を設定

「管理」 -> 「APIのアクセス許可」と進み、「Microsoft Graph」を追加し、必要な許可を追加します。

![スクリーンショット 2024-05-19 19.21.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/9d0b7700-2f5b-7e71-2f70-6f3376a81768.png)

今回は試しにカレンダーへの読み書き権限（`Calendars.ReadWrite`）を追加してみました。

### 4. クライアントシークレットを追加

「管理」 -> 「証明書とシークレット」と進み、「新しいクライアントシークレット」からクライアントシークレットを追加します。

![スクリーンショット 2024-05-19 19.23.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/9389c636-28c2-aa3d-9c9c-c1c7b0840a1f.png)
![スクリーンショット 2024-05-19 19.24.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/106f6178-e509-eb59-9e4b-338056f8f722.png)

「値」列に表示されている文字列がクライアントシークレットです。初回以降は見えなくなってしまうため、忘れずにメモしておきましょう。

## 実践編

諸々の下準備が完了したので、いよいよ実践に入っていきましょう。

### 1. 環境構築

下記コマンドを実行し、実行環境の構築を行います。

```shell
$ mkdir outlool-api-for-calendar && cd outlool-api-for-calendar
$ touch Gemfile  Gemfile.lock
```

```rb:./Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "oauth2"
gem "httparty"
```

```shell
$ bundle install --path vendor/bundle
```

### 2. アクセストークンを取得

API リクエスト時に使用するアクセストークンを取得するためのコードを書きます。

```shell
$ touch get_token.rb
```

```ruby:./get_token.rb
require "bundler/setup"
require "oauth2"
require "httparty"

client_id = "*************"     # 「概要」ページ内の「アプリケーション (クライアント) ID」
client_secret = "*************" # 「管理 -> 証明書とシークレット」ページ内の「値」
redirect_uri = "http://localhost:3000/auth/microsoft_graph/callback"
tenant = "common"
authorize_url = "https://login.microsoftonline.com/#{tenant}/oauth2/v2.0/authorize"
token_url = "https://login.microsoftonline.com/#{tenant}/oauth2/v2.0/token"

client = OAuth2::Client.new(client_id, client_secret, {
  site: "https://login.microsoftonline.com",
  authorize_url: authorize_url,
  token_url: token_url
})

# 認証 URL を生成
auth_url = client.auth_code.authorize_url(redirect_uri: redirect_uri, scope: "openid email profile https://graph.microsoft.com/Calendars.ReadWrite")
puts "Open the following URL in your browser and authorize the application: #{auth_url}"

# 認証後に取得したコードを入力してアクセストークンを取得
puts "Enter the authorization code: "

code = gets.chomp
token = client.auth_code.get_token(code, redirect_uri: redirect_uri, scope: "openid email profile https://graph.microsoft.com/Calendars.ReadWrite")

puts "Access token: #{token.token}"
```

![スクリーンショット 2024-05-20 4.14.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/0b5818ce-db1f-1cc1-6ebc-8b0cce33fa5d.png)


`client_id` は「概要」ページ内の「アプリケーション (クライアント) ID」に表示されているものをセットしてください。

```shell
$ ruby get_token.rb

=> Open the following URL in your browser and authorize the application: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=*************&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fmicrosoft_graph%2Fcallback&response_type=code&scope=openid+email+profile+https%3A%2F%2Fgraph.microsoft.com%2FCalendars.ReadWrite
```


コードを実行すると、認証用の URL（`Open the following URL in your browser and authorize the application:` 以下）が生成されるので、そちらにアクセスします。

![スクリーンショット 2024-05-20 4.22.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/945d795a-d636-4b92-bb96-6c6dafca4d4d.png)

アプリを許可し、認証に成功すると次のような画面にリダイレクトされるはずです。

![スクリーンショット 2024-05-19 20.16.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/5d57c652-3bc1-b5f3-5df8-8647d4f425f9.png)

URL 内に含まれる `code=` の部分を `Enter the authorization code: ` 以下に入力してください。

![スクリーンショット 2024-05-20 4.17.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/510f9ef8-b844-fa91-a02e-414012557dff.png)

特に問題が無ければ `Access token:` 以下にアクセストークンが表示されるので、こちらをメモっておきましょう。

### 3. カレンダーを操作してみる

アクセストークンが取得できたら、早速カレンダーを操作してみましょう。


```shell
$ touch create_event.rb
```

```rb:./create_event.rb
require "bundler/setup"
require "httparty"
require "json"

access_token = "*************************"

new_event = {
  "subject": "test",
  "body": {
    "contentType": "HTML",
    "content": "test test test"
  },
  "start": {
    "dateTime": "2024-05-20T19:00:00",
    "timeZone": "Asia/Tokyo"
  },
  "end": {
    "dateTime": "2024-05-20T20:00:00",
    "timeZone": "Asia/Tokyo"
  },
}

response = HTTParty.post(
  'https://graph.microsoft.com/v1.0/me/events',
  headers: {
    'Authorization' => "Bearer #{access_token}",
    'Content-Type': 'application/json'
  },
  body: new_event.to_json
)

if response.code == 201
  puts "Event created successfully."
else
  puts "Failed to create event: #{response.body}"
end
```

```
$ ruby create_event.rb
```

上手くいけばカレンダーにイベントが追加されているはずです。

![スクリーンショット 2024-05-20 4.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/cda228ac-810d-30a7-2de5-bae19b247267.png)

その他にも

- 一覧取得
- 更新
- 削除

といった操作が可能なので、ドキュメントを参考に色々遊んでみるといいでしょう。

https://learn.microsoft.com/ja-jp/graph/api/resources/calendar?view=graph-rest-1.0

## まとめ

以上、Microsoft Graph API を Ruby で操作してみました。

ちなみに、Ruby 向けの SDK としてこんなものも出ているみたいです。

https://github.com/microsoftgraph/msgraph-sdk-ruby

今回は使用しませんでしたが、時間のある時にチェックしてみたいと思います。