【Zoom ISVパートナー】ZoomのAPIを使ってミーティングを作成して第三者に提供する

本記事では、Zoomのミーティングを作成して**第三者に提供したい場合**のAPIの使用例についてご紹介したいと思います。

## はじめに
まず、前提となるライセンスの話について簡単に触れておきます。
ミーティングの主催者がホストとして**参加する**場合は、REST APIが利用可能な[プロ以上のライセンス](https://zoom.us/pricing)を利用します。
一方で、主催者がホストとして**参加しない**ミーティングを第三者に提供する場合は、[ISVパートナー](https://explore.zoom.us/docs/jp-jp/platform/isv.html)（以下、ISVと呼びます）の契約を結ぶ必要があります。
どちらの場合も使用するAPI自体は共通ですが、ISV契約を分数課金で締結した場合はライセンス済みユーザーをほぼ無制限に作ることができるため、設計が変わってきます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248138/521a3dda-fa57-cd30-e800-8392ae605c32.png)

:::note info
ISV契約を分数課金で締結した場合はライセンス済みユーザーをほぼ無制限に作成可能
:::


## API
要件として、「既存のZoomミーティングと時間帯の重複が無いようにミーティングを作成して、そのミーティングへの参加情報を取得したい」というケースを考えます。
どのAPIを使用すれば実現できるでしょうか？

ISVでは、例えば以下の4つのAPIを組み合わせて実現できます。
- ①ライセンス済みのユーザーを作成する
- ②ユーザーをグループに追加する
- ③ミーティングを作成する
- ④招待状（ミーティングへの参加情報）を取得する


### ①ライセンス済みのユーザーを作成する
ISV契約を分数課金で締結した場合はライセンス済みのユーザーをほぼ無制限に作成できることを利用し、ミーティング毎に新たなユーザーを作成します。
もし、新たなユーザーを作成せずに既存のユーザーに対して重複が無いミーティングを作成する場合は、重複を判定する仕組みを別途用意する必要があります（Zoomとしては同時間帯にミーティングを作成することを許容しており、作成してもエラーにはならないものの、同一ユーザーで同時に開催できるミーティング数には制限があるため、重複を避けるなら独自の実装が必要）。
この重複判定をしなくて済むのは、ISV契約のメリットです。

:::note info
使用するAPI：[[POST] /users](https://marketplace.zoom.us/docs/api-reference/zoom-api/methods/#operation/userCreate)
:::

```json
# Request Bodyの例
{
  "action": "custCreate",  # ISVではこれを指定
  "user_info": {
    "email": "abcdefg@hijk.com",
    "type": 2,  # ライセンス済みユーザーのtype
    "first_name": "Terry",
    "last_name": "Jones"
  }
}
```

以下は、同様の操作をZoomウェブポータルから行う時のイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248138/9db00626-db4a-5caa-7cc2-f9dc02ed8d03.png)

### ②ユーザーをグループに追加する
このAPIを利用する前の準備として、[Zoomウェブポータル](https://zoom.us/)にオーナーアカウントでサインインし、「ユーザー管理」→「グループ」のメニューから、ユーザーグループを作成しておきます。このユーザーグループには、 作成するミーティングに共通で適用すべき設定を施します。

そして、APIによって①で作成したユーザーをこのグループに追加することで、ミーティングに共通な設定を適用できます。

なお、「ユーザー管理」→「ユーザー」→「詳細」からデフォルトのユーザーグループを設定することで本APIの実行を省略できますが、後々の仕様変更に強くするためにも、このAPIを利用して任意のユーザーグループを指定できるようにしておくのがお勧めです。
このAPIを利用しておけば、本番環境と試験環境で異なるユーザーグループを用意し、試験環境で十分に検証してから設定を本番環境に反映することも可能になります。

:::note info
使用するAPI：[[POST] /groups/{作成済のgroupId}/members](https://marketplace.zoom.us/docs/api-reference/zoom-api/methods/#operation/groupMembersCreate)
:::

```json
# Request Bodyの例
{
  "members": [
    {
      "email": "abcdefg@hijk.com"
    }
  ]
}
```

以下は、同様の操作をZoomウェブポータルから行う時のイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248138/38d130c1-7f4a-d3ca-61f6-51c99505e6c1.png)

### ③ミーティングを作成する
このAPIでは多くのオプションを指定することが可能ですが、共通で指定すべき設定は②で適用しておくことによって、動的に変更が必要なパラメータだけを指定すればよくなり、シンプルな実装になります。

:::note info
使用するAPI：[[POST] /users/{①で作成したuserId}/meetings](https://marketplace.zoom.us/docs/api-reference/zoom-api/methods/#operation/meetingCreate)
:::

```json
# Request Bodyの例
{
  "topic": "Meeting title",
  "type": "2",  # 日時を指定した1度きりのミーティング
  "start_time" : "2021-08-03T18:00:00",
  "duration": 60,
  "timezone": "Asia/Tokyo",
  "settings": {
    "participant_video": false,
    "auto_recording": "none",
    "global_dial_in_countries": ["JP", "US"]
  }
}
```

以下は、同様の操作をZoomウェブポータルから行う時のイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248138/4d2abc27-27c2-26f3-6d49-459f9ae2db29.png)

### ④招待状（ミーティングへの参加情報）を取得する

Zoomミーティングへの参加情報を取得するだけであれば、③のレスポンス中にも含まれるので本APIの実行は不要です。
ただし、特にZoomミーティングに電話で参加するケースでは、電話番号が適切に桁区切りされていたり言語が反映されている④の使用を検討しても良いと思います。

:::note info
使用するAPI：[[GET] /meetings/{③で作成したmeetingId}/invitation](https://marketplace.zoom.us/docs/api-reference/zoom-api/methods/#operation/meetingInvitation)
:::

```json
# ③のレスポンスの一部（一部伏字）
"global_dial_in_numbers": [
    {
        "country_name": "Japan",
        "number": "+81 524XXXYYY",
        "type": "toll",
        "country": "JP"
    },
    {
        "country_name": "US",
        "city": "New York",
        "number": "+1 6465WWWZZZ",
        "type": "toll",
        "country": "US"
    },
],
```

```
# ④のレスポンス中の文字列の一部（英語で取得した場合）
Dial by your location
        +81 524 XXX YYY Japan
        +1 646 5WW WZZZ US (New York)

# ④のレスポンス中の文字列の一部（日本語で取得した場合）
所在地でダイアル
        +81 524 XXX YYY 日本
        +1 646 5WW WZZZ 米国 (New York)
```

以下は、同様の操作をZoomウェブポータルから行う時のイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248138/bd771385-6581-2a75-610d-4b97d957624a.png)

なお、本APIで取得する招待状の言語は、API実行時に指定するのではなく、**オーナーアカウントの言語設定により指定されます**。
また、Zoomウェブポータルのフッターでサイトの言語設定を変えると、連動してアカウントの言語設定が変わるため、意図せず変えないよう、基本的にオーナーアカウントではサインインしない運用にするのが良いと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248138/1d1fc7d3-7af5-aa5d-f593-9e7b2487f007.png)

:::note warn
フッターの言語設定を変えるとアカウントの言語設定も変わる（画面リロード後確認できる）
:::

## まとめ
このように、Zoomは1つ1つのAPIが役割毎にシンプルに分かれており、要件に応じて組み合わせて利用できます。
シンプルに分かれている分、個々のAPIの細かな検証もしやすくなっていると感じました。
皆さんもAPIでZoomを便利に利用してみてはいかがでしょうか。

---
※この記事は[VisasQ Dev Blog](https://tech.visasq.com/zoom-isv/)の内容をQiitaにも掲載したものです。