最近流行りのZoomにAPIがあるということで。まずはアプリケーションの作り方から。
アプリケーションの作成
アカウントの作成は終えている前提です。
https://marketplace.zoom.us/ にアクセスして、「Build App」に進みます。
JWT(赤枠)とOauth(緑枠)について説明していきます。
JWTアプリの作成
JWT Tokenの取得
Createボタンを押すと、アプリ名の入力が求められるので適当に入力します。
入力して次に進むと、下記画像のように詳細な情報の入力を求められます。枠が赤くなっている部分は必須項目なので埋めましょう。
左の欄の「App Credentials」に進むと、API KeyとAPI SecretとIM Chat Histrory Tokenが取得できます。左のRegenerateボタンを押すと値を再生成できます。
下の「View JWT Token」をクリックして開くと簡単に期限付きのJWT Tokenを取得することが出来ます。
JWT Tokenが使えるかどうかの確認
本当にJWT Tokenが使えるのかどうかをサクっと確認してしまいましょう。
https://marketplace.zoom.us/docs/guides/auth/jwt の下の方にNode.js。cURL・PHP・Python・Ruby・C#のサンプルコードがあるので、コピペして実行してみましょう。
PHPなら下みたいな感じ。authorization: Bearer <JWT_TOKEN>の部分に上で取得した長いJWT Tokenを貼り付けます。JWT Tokenを送信する際にはAuthorizationヘッダにBeararスキームを設定します。
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.zoom.us/v2/users?status=active&page_size=30&page_number=1",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"authorization: Bearer <JWT_TOKEN>",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
実行すると、以下のようなレスポンスが返ります。
今実行したAPIはGET /usersで、ユーザーの情報が取れます。idはアカウント番号、pmiはパーソナルミーティングIDを表します。
JWT Tokenの生成
先程は既に生成されたJWT Tokenを使用しましたが、実際にはこれを生成しなければなりません。
JWTの生成については https://marketplace.zoom.us/docs/guides/auth/jwt で述べられていますので、この通り進めれば生成できるかと思います。
Header:下記JSONをURL-Safe Base64でエンコードする。→”eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9″
※URL-Safe Base64 Encodeとは、Base64 Encode後に”+”を”-“に、”/”を”_”に、”=”を(削除)とそれぞれ置換したものです。
{
"alg": "HS256",
"typ": "JWT"
}
Payload:下記JSONに適切なAPI Keyと有効期限(Unixtime)を埋めてURL-Safe Base64でエンコードする。
※先に取得した自動生成されるTokenにはPayload内に”iat”・”aud”クレームも含まれている。順にJWT発行時間・受信者を示す。自動生成されるTokenでは”iat”にはUnixtime、”aud”にはnullを与えている。
{
"iss": "API_KEY",
"exp": TIME_STAMP
}
Signature:下記3手順で作る。
(1) Header(エンコード済)とPayload(エンコード済)を”.”で連結する。
(2) (1)で得られた文字列を、Headerのalgで指定したアルゴリズムとAPI Secretを用いてハッシュ値を求め(署名)、求めたハッシュ値をURL-Safe Base64でエンコードする。
(3) (1)で得られた文字列と(2)で得られた文字列を”.”で連結する。
PHPで書くとするとこんな感じ。
<?php
function urlsafe_base64_encode($str){
return str_replace(array('+','/','='), array('-','_',''), base64_encode($str));
}
$API_Key = 'API_KEY';
$API_Secret = 'API_SECRET';
$expiration = time() + 5;//5秒
$header = urlsafe_base64_encode('{"alg":"HS256","typ":"JWT"}');
$payload = urlsafe_base64_encode('{"iss":"'.$API_Key.'","exp":'.$expiration.'}');
$signature = urlsafe_base64_encode(hash_hmac('sha256', "$header.$payload", $API_Secret, TRUE));
$token = "$header.$payload.$signature";
HeaderとPayloadには機密情報を含めてはいけません。Base64でエンコードしただけなので簡単にデコードされてしまいます。
Oauthアプリの作成
Createボタンを押すと、アプリ名の入力が求められるので適当に入力します。JWTと違い、アプリの種類を選択したりマーケットプレイスで公開したりするかどうか聞かれます。
設定画面のApp Credentialsの「Redirect URL for Oauth」と「Whitelist URL」を埋めます。
Informationも適当に埋めます。
Featureでは、特定のイベントがトリガーされた際にZoomが自動的に通知を送信してくれるような仕組みを設定できます。
Featureの設定
Event SubscriptionsをONにして、「+ Add new event subscription」をクリックすると、上のような画面が現れます。
Event Subscriptionは1つのアプリ毎に最大10個設定できます。
Subscription Name:識別名
Event notification endpoint URL:通知を受け取るURL(送信先URL)
を入力したら、Event typesの「Add events」をクリックし、どのイベントをトリガーとするかを選択します(複数選択可)。
チェックボックスの下にRequired…と書かれています。ここに記載されている情報を、Scopesに追加しなければなりません。
例えば、ユーザーのログインを対象のイベントとして設定したとして、実際にログインすると次のようなデータが先程指定したendpoint URLにPOSTリクエストとして送信されます。PHP初心者なので$_POSTで内容が取れなくて悩みましたがfile_get_contents(‘php://input’)で取ればいいそうです。
{
"event": "user.signed_in",
"payload": {
"account_id": "hogehoge",
"object": {
"id": "hogehoge",
"client_type": "Browser",
"date_time": "2020-04-18T04:53:33Z",
"version": "-",
"email": "example@hoge.com"
}
}
}
Scopesの設定
ここでは、アプリケーションが使用できるスコープを選択します。
使用するAPIによって必要なスコープは異なります。
Oauth・Access Tokenの取得
実際に、Oauthを用いて認可・認証を行ってみます。
認証をリクエストするURLは次のようにして生成されます。
https://zoom.us/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URL
CLIENT_IDとREDIRECT_URLにはApp Credentialsにて得られる値・設定した値を入れます。実際にアクセスすると下のようになります。
このURLにアクセスし、ユーザーがアプリケーションを承認すると、Redirect URLで指定したURLにリダイレクトされます。この際、リダイレクトURLにGETパラメータとしてcodeが含まれます。アクセストークンを得るには、リダイレクトURLから得られるcodeとREDIRECT_URLそのものをクエリパラメータとし、AuthorizationヘッダにはClient_IDとClient_Secretを”:”で連結後Base64でエンコードした文字列の先頭に”Basic “を連結したものを指定し、https://zoom.us/oauth/tokenにPOSTリクエストを送信します。このときのBase64 EncodeはURL-Safeではありません。Authorizationヘッダの部分はBasic認証そのものです。
リダイレクト後、アクセストークンを得る例を示します。これ自体がRedirect URLとして指定されているとします。
<?php
session_start();
$Client_ID = 'CLIENT_ID';
$Client_Secret = 'CLIENT_SECRET';
$Redirect_URL = 'REDIRECT_URL';
if(isset($_GET['code'])){
$basic = base64_encode($Client_ID.':'.$Client_Secret);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://zoom.us/oauth/token?grant_type=authorization_code&code={$_GET['code']}&redirect_uri=$Redirect_URL",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => array(
"authorization: Basic $basic"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
}else{
echo 'Authorization Error';
}
実際にアクセストークンを得る部分まで実行すると、下のようなオブジェクトが返ります。
アクセストークンを使ってAPIを使用するには、上記「JWT Tokenが使えるかどうかの確認」で示したプログラム内の<JWT_TOKEN>の代わりに得られたaccess_tokenをセットします(要は、Authorizationヘッダに”Bearar <access_token>”をセットする)。実際にAPIが実行できるか確認してみてください。但し、APIの要求するScopesに対してアプリケーションに設定されているScopesが不足しているとエラーが出ます。
{
"code": 4700,
"message": "Invalid access token, does not contain scopes: [user:write:admin, user:read:admin, zms:user:write, zms:user:read]"
}
Access Tokenの更新
アクセストークンを得たときのJSON内にexpires_inというキーがあります。この値が3599であるならば、有効期限が1時間であることを示しています(厳密には59分59秒)。アクセストークンの有効期限は1時間であるため、1時間を過ぎるとアクセストークンを更新しなければなりません。
アクセストークンを更新するには、再度https://zoom.us/oauth/tokenにPOSTリクエストを送信します。先程のリクエストとの違いは、クエリパラメータが”grant_type=refresh_token“及び”refresh_token=<REFRESH_TOKEN>”の2つとなる点です。code・redirect_uriは不要となります。ここで、<REFRESH_TOKEN>は先程のアクセストークン取得で得られたJSON内のrefresh_tokenです。なお、このrefresh_tokenの有効期限は15年です。
Access Tokenの取消
アクセストークンを取り消すには、クエリパラメータにtoken=<ACCESS_TOKEN>を指定、Authorizationヘッダには先程と同様にBasic認証の値を指定してhttps://zoom.us/oauth/revokeにPOSTリクエストを送信します。
成功した場合、
{
"status": "success"
}
といったオブジェクトが返ります。
アプリケーションの許可取消
アプリケーションは、アンインストールされた場合もしくはユーザーの許可が取消された場合にユーザーデータを削除し、場合によってはAPIを通じて削除したことをZoomに通知しなければなりません。
アンインストールされた場合もしくはユーザーの許可が取り消された場合、Zoom側から認証解除エンドポイントURLに認証解除イベント通知が送信されます。
その通知を見て、ユーザーデータを必要に応じて消去し、その旨をZoomに通知するという流れになります。
これは、アプリケーションがZoom App Marketplaceで公開されたときのみ有効です。とりあえず自分には関係なさそうなのでカット。
https://marketplace.zoom.us/docs/guides/auth/deauthorization
https://marketplace.zoom.us/docs/api-reference/webhook-reference/app-events/app-deauthorized
https://marketplace.zoom.us/docs/api-reference/data-compliance
ドキュメント
https://marketplace.zoom.us/docs/guides/auth/jwt
https://marketplace.zoom.us/docs/guides/auth/oauth
https://marketplace.zoom.us/docs/guides/auth/deauthorization
コメント