Zoomのアプリケーションの作成

最近流行りの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

コメント

タイトルとURLをコピーしました