きっかけ
「Zoomを利用したリモート講義の動画をLMSにアップロードしているが、手動でダウンロードして登録するのが手間なので自動にできないか?」という話があったので、そもそもそのようなことが可能なのか検討してみる。
APIとApp Marketplace
Zoomの有償サービスだとクラウドレコーディングが利用でき、エンコードが完了してダウンロードできる状態になると、ダウンロード先URLが記載されたメールが送られてくる。
ただ、メールを指定したアドレスに転送するとか、POP3かなにかでメールをチェックしてリンクからダウンロードするのは最終手段として、もっと良さそうな案を考えていると、ZoomのAPIが利用できそうだということが分かった。ただし、その場合はApp Marketplaceでアプリを公開する必要があるらしい。
幸いにApp Marketplaceでのアプリ作成は有償サービスのライセンスを持っていれば簡単にできるようで、さらにアプリは非公開での利用もできる様子。そこで考えた導入シナリオは、プラグインをLMS管理者が導入し、プラグインのドキュメントの手順に従って自組織のZoomライセンスを利用してApp Marketplaceにアプリを作成する。アプリ作成といっても実際はOAuth2.0のエンドポイントの登録やシークレットキーの作成程度。
「講義を行う教員が自分のコースにブロックを設置し、自分のZoomアカウントと紐づけておくと、事前に設定した条件に従ってダウンロードされた動画が、コース中に自動的に貼り付けられる。」という挙動で行けそうだ。
実証コードの作成
ここで「できそうですよ」と回答してもよいのだが、実際に作成を依頼されたときに「…できませんでした」とならないように実証コードを書いてみる。
composerでGuzzleを導入して、get_token.phpにアクセス。「Zoom認証」のリンクをクリックすると、Zoomのログインと認可画面が表示される。このget_token.phpのURLがAPP_REDIRECT_URLに設定してあるため、Zoomで認証して権限を付与した後は$codeの値を利用してaccess_tokenなどを取得する。
<?php
require_once __DIR__.'/vendor/autoload.php';
define('APP_CLIENT_ID', '');
define('APP_CLIENT_SECRET', '');
define('APP_VERIFICATION_TOKEN', '');
define('APP_REDIRECT_URL', '');
echo '<a href="https://zoom.us/oauth/authorize?response_type=code&client_id='.APP_CLIENT_ID.'&redirect_uri='.APP_REDIRECT_URL.'">Zoom認証</a>';
if (empty($_SERVER['QUERY_STRING'])) {
die('no query');
}
list($name, $code) = explode('=', $_SERVER['QUERY_STRING']);
$Client = new \GuzzleHttp\Client;
$params = [
'headers' => [
'Authorization' => 'Basic ' . base64_encode(APP_CLIENT_ID.':'.APP_CLIENT_SECRET),
'Content-Type' => 'application/x-www-form-urlencoded',
],
'form_params' => [
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => APP_REDIRECT_URL,
]
];
$Response = $Client->request('POST', 'https://zoom.us/oauth/token', $params);
$json = $Response->getBody()->getContents();
$json = json_decode($json);
echo '<pre>'; var_dump($json); echo '</pre>';
とりあえず動作テストなので、var_dump()された結果からaccess_tokenをコピペしてget_metadata.phpに渡す。
事前に別途取得しておいた(という設定の)ミーティングIDから録画された動画をダウンロードして保存する。
<?php
require_once __DIR__.'/vendor/autoload.php';
$access_token = '';
$meeting_id = '';
$Client = new \GuzzleHttp\Client;
$params = [
'headers' => [
'Authorization' => 'Bearer ' . $access_token,
]
];
$Response = $Client->request('GET', "https://api.zoom.us/v2/meetings/{$meeting_id}/recordings", $params);
$json = $Response->getBody()->getContents();
$json = json_decode($json);
$url = $json->recording_files[0]->download_url;
$Response = $Client->request('GET', $url.'?access_token='.$access_token);
file_put_contents(__DIR__.'/movie/'.$json->id.'.mp4', $Response->getBody()->getContents());
ひとまずZoom APIを利用して期待した処理が可能そうなので、本当に必要ならプラグインを作成すると回答。
実際に作成する場合はEvent subscriptionでエンコード完了時にWebhookで呼び出してもらえるかとか確認する必要があると思う。