Help us understand the problem. What is going on with this article?

zoom-sdk-electron でできることを調べるまでのアレコレ

概要

zoomが提供しているElectronのAPIでできそうなことがリファレンスだとちょっとわかりにくいのでデモアプリを起動しようと思ったが、案外ハマりどころが多かったのでそれについて。

参考資料

Zoom Electron SDK 入門

非常にわかりやすかったのですが、具体的なコードの変更内容が例示されていなくて詰まってしまったのでその補足をしたい。当時と若干バージョンが異なる関係で行数のところがずれてしまうので...

記事を読む限り、この方のときはむしろ私が書いているように SDK Key/Secretによる認証が基本だったように見えるのですが...(https://github.com/zoom/zoom-sdk-electron/commit/dbdff5a65dff40c1bccb7a1b269391ea72d8f6b5#diff-3b4cc93c41d4067694a6d9ff6ae923efL643 このコミットで大規模に改修が入ってますね)

CHANGELOG 見る限りでは開発用途ではJWT Tokenのほうが、more secure, more convenient, and more versatile. ということのようです。SDK Key/Secret認証のメソッド消さなくてもいいのに...

まずは必要なものの準備

※ 前提としてMac版で実施しています

こちらのページから必要な事項を確認します。

  • ソースコード(Gitでcloneする)
    • A device with Mac OS or Windows OS
    • Mac OS: MacOS 10.10 or later. とのこと
  • node.js 12.0.0 version と書いてある
    • nvmで用意しておこう
  • zoomのアカウント(またMarketplaceでのAPIキー、トークン等の生成)
    • あとでやります

基本の準備〜ビルド

node 12.0.0.0 (マイナーバージョンまであわせる必要はないかも)

$ nvm install 12.0.0
$ node -v
v12.0.0

ソースコード

$ git clone https://github.com/zoom/zoom-sdk-electron

手順通りに必要なものを入れて、ビルドします

$ npm install --save-dev electron@5.0.2 -g
$ npm install node-gyp -g
$ npm install bindings -g

$ cd zoom-sdk-electron
$ sh build_nodeaddon_mac.sh

手元の環境ではめっちゃwarningが出ました。

gyp info ok
cp: ../../../../../../Bin/Mac/Release: No such file or directory
cp: ./build/Release/zoomsdk.node.dSYM: unable to copy extended attributes to ../../../../../../Bin/Mac/Release: No such file or directory
cp: ../../../../../../Bin/Mac/Release/Contents: No such file or directory
cp: ./build/Release/zoomsdk.node.dSYM/Contents: unable to copy extended attributes to ../../../../../../Bin/Mac/Release/Contents: No such file or directory
cp: ../../../../../../Bin/Mac/Release/Contents/Resources: No such file or directory
cp: ./build/Release/zoomsdk.node.dSYM/Contents/Resources: unable to copy extended attributes to ../../../../../../Bin/Mac/Release/Contents/Resources: No such file or directory
cp: ../../../../../../Bin/Mac/Release/Contents/Resources/DWARF: No such file or directory
cp: ./build/Release/zoomsdk.node.dSYM/Contents/Resources/DWARF: unable to copy extended attributes to ../../../../../../Bin/Mac/Release/Contents/Resources/DWARF: No such file or directory
cp: ../../../../../../Bin/Mac/Release/Contents/Resources/DWARF/zoomsdk.node: No such file or directory
cp: ../../../../../../Bin/Mac/Release/Contents/Info.plist: No such file or directory

結果的に失敗しているようにも見えますが、大丈夫っぽいので突き進みます。

デモの起動

$ sh run_demo_mac.sh
run_demo_mac.sh: line 12: cd: ./demo: No such file or directory

こちらもエラーか?!と思いますがそういうもんです。このあといろいろ生成してくれます。

image.png

無事起動しました...が...

objc[43150]: Class ZoomLauncher3rdSdkIPCReciever is implemented in both /Users/tetsunosuke/work/zoom/electron/zoom-sdk-electron/demo/node_modules/electron/dist/Electron.app/Contents/Frameworks/ZoomSDKChatUI.framework/Versions/A/ZoomSDKChatUI (0x10d2e6b30) and /Users/tetsunosuke/work/zoom/electron/zoom-sdk-electron/demo/node_modules/electron/dist/Electron.app/Contents/Frameworks/zChatApp.bundle/Contents/MacOS/zChatApp (0x115173560). One of the two will be used. Which one is undefined.
InitSDK 0
Error: Send error, 60 Operation timed out
Error: Send error, 60 Operation timed out
Error: Send error, 60 Operation timed out

エラーっぽいなにかが出ています・・・。気にしなくても動作はしているので一旦無視します。

で?

このままStart Demo を押すと

image.png

というように jwt token を求められますが、jwt token の有効期限のことを考えると、 とりあえずのお試しには、 SDK Key/SDK Secret のほうがいいんじゃないかなと思います。

以後、その前提で手を入れていきます。参考記事の Zoom Electron SDK 入門 とはここからがやや異なります。

手を加えていきます

その前にSDKで Key/Secret を発行しておく

https://marketplace.zoom.us/ よりサインアップして、

Develop → Build App と選択します。 Choose your app type から SDK を選択しましょう。

各種情報を入力してアプリを作成すると

image.png

SDK Key、 SDK Secret が払い出されるので控えておきます。

アプリの起動を簡略化します。

こちらも参考記事と同様に内部フローを把握しておくと

  • main.js: createWindow() -> showDomainWindow() -> pages/domain.html が開かれる
  • dmain.html: doinit() -> senddomainmsg() -> asynchronous-message で "setDomain", 画面で選ばれたdomain, enable_logがメインプロセスに送られる
  • main:js は asynchronous-messageを受け取ってfunctionObj[arg1](arg2, arg3, arg4, arg5); を呼び出す

という流れになっており、「ボタンを押す」操作は

 function createWindow() {
   // Create the browser window.
-  showDomainwindow();
+  // showDomainwindow();
+  functionObj["setDomain"](
+      "https://www.zoom.us", /* domain */
+      true                    /* enable_log */
+  );
 }

こうしたのと同じと言えます。

※ ところでこのdomainって一体何・・・?

また、 jwt tokenを要求する画面は pages/index.html が呼び出されます。
これは、 ProcSDKReady() が呼ばれたときに、 showAuthWindow() が呼ばれているからですね。

ここから先の処理は

  • index.html: ボタンクリックで dosdkauth() が呼ばれる -> authWithJwtToken が asynchronous-messageで呼び出される

となっているので、ここを一気にスキップします。

今回は認証をSDKのKey/Secretで行うので、 zoomauth.AuthWithJwtToken(sdk_context); の代わりに、zoomauth.SDKAuth(key, secret); を使うようにします。

つまり

+  sdkLogin: function(key, secret) {
+    let ret = zoomauth.SDKAuth(key, secret);
+    if (ret == 0) {
+      showWaitingWindow();
+    }
   } 

このように新しい関数を main.js に実装して、

 function ProcSDKReady() {
-  showAuthwindow()
   var options = {
     authcb: sdkauthCB,
     logincb: loginretCB,
     logoutcb: null
   }
   zoomauth = zoomsdk.GetAuth(options);
+  functionObj["sdkLogin"](
+      "ここに取得していた SDK Keyを",  /* key */
+      "ここに取得していた SDK Secretを"   /* secret */
+  );
 }

と書くことで、sdkLoginが呼ばれ、コールバック(sdkauthCB)以降が動き出します。

これと、言語を日本語化する処理(ZoomSDK_LANGUAGE_ID.LANGUAGE_English→ZoomSDK_LANGUAGE_ID.LANGUAGE_Japanese)を加えて、差分は以下のようになりました。

main.js
@@ -489,13 +489,16 @@ function showStartJoinWindow() {
 }

 function ProcSDKReady() {
-  showAuthwindow()
   var options = {
     authcb: sdkauthCB,
     logincb: loginretCB,
     logoutcb: null
   }
   zoomauth = zoomsdk.GetAuth(options);
+  functionObj["sdkLogin"](
+      "<省略>",  /* key */
+      "<省略>"   /* secret */
+  );
 }

 function apicallresultcb(apiname, ret) {
@@ -625,7 +628,7 @@ let functionObj = {
       path: '', // win require absolute path, mac require ''
       domain: domain,
       enable_log: enable_log,
-      langid: ZoomSDK_LANGUAGE_ID.LANGUAGE_English,
+      langid: ZoomSDK_LANGUAGE_ID.LANGUAGE_Japanese,
       locale: ZoomAPPLocale.ZNSDK_APP_Locale_Default,
       logfilesize: 5
     }
@@ -2613,6 +2616,12 @@ let functionObj = {
     }
     let ret = zoomsms.SetDefaultCellPhoneInfo(opts);
     console.log('SetDefaultCellPhoneInfo', ret);
+  },
+  sdkLogin: function(key, secret) {
+    let ret = zoomauth.SDKAuth(key, secret);
+    if (ret == 0) {
+      showWaitingWindow();
+    }
   }
 }

@@ -2629,7 +2638,10 @@ app.on('window-all-closed', function () {

 function createWindow() {
   // Create the browser window.
-  showDomainwindow();
+  functionObj["setDomain"](
+      "https://www.zoom.us", /* domain */
+      true                   /* enable_log */
+  );
 }

image.png

これでzoomクライアントとしてのメインの実装は完了です!

あとはデモ用の用途をお楽しみください

image.png

image.png

tetsunosukeito
人事部門に所属し、エンジニア採用とまなびプランナーとして全社育成制度の設計をしています。ゲームを用いた研修や体を使ったアクティビティ、レゴや写真を活用した対話のワークショップを得意としています。 株式会社フォトクリエイト / 株式会社CCCフォトライフラボ / 株式会社しまうまプリント / 株式会社キタムラ・ホールディングス
https://note.com/tetsunosuke
photocreate
ITの力で、写真を通じて感動があふれかえる社会を実現する「フォトライフ構想」を目指すWebサービスを展開しています
https://www.photocreate.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした