LINEWORKS Advent Calendar 2020 / 21日目の記事です。
zoomのミーティングルームを作るLINE WORKS Botを作ってみました。
名前はZoomerです。
0. はじめに
記事の流れは下記の通りです。
- こんなの作りました
- 環境準備
- 作ってみる
- 動かしてみる
- まとめ
1. こんなの作りました
シンプルではありますが下記の手順で zoomのミーティングURLを取得します。
- Zoomer Bot とのトークルームを作成する
- Zoomer Bot に zoomアカウントIDを登録する
- Zoomer Bot に いつミーティングをするか伝える
- Zoomer Bot からミーティングURLが返ってくる
2. 環境準備
Zoom API の利用準備
Zoom APIへお試しリクエストを送る方法 (JWT・OAuth) を参考に JWT app を作成しました。
https://marketplace.zoom.us/develop/create
この状態になります。
API Key と API Secret は、Zoomer Bot で使用します。
LINE WORKS Bot APIの利用準備
LINE WORKS の Developer Console で Zoomer Bot サーバーが LINE WORKS と通信するために必要な接続情報の発行と Zoomer Bot の登録を行います。
↓こちらの記事を参考にしていただければ幸いです。
LINE WORKSで初めてのBot開発!(前編) の「Developer ConsoleでAPIを使うための設定とBotを登録する」
※Bot登録の際に指定する Callback URL は、ngrokを利用して取得するとローカルデバッグができるのでとっても便利です。
(記事:ローカル環境で LINEWORKS Bot を動かす話が大変参考になりました)
開発環境
node.jsでいろいろpackageを利用してますが省略します。
3. 作ってみる
GitHub の line-works-zoomer で開発しました。詳細は GitHub を参照して下さい。
Zoomと連携する部分を抜粋して紹介します。
ZoomMeetingCreateAction.js は、Zoomer Bot が Zoom のミーティングルームの作成依頼を受け付けるアクションクラスです。作成結果を基にLINE WORKS の Zoomer Bot 利用者に結果メッセージを送信しています。
ZoomMeetingCreator(MeetingCreator)クラスで実際に Zoom API を使用してミーティングルームを作成しています。
const moment = require("moment");
const BaseAction = require('./BaseAction');
const BotMessageSender = require('../lineworks/bot/MessageSender');
const ZoomMeetingCreator = require('../zoom/MeetingCreator');
const SessionRepository = require('../repositories/SessionRepository');
/**
* ZoomMeetingCreateActionクラス
*/
module.exports = class ZoomMeetingCreateAction extends BaseAction {
/**
* 初期化します。
* @param {object} callbackEvent コールバックイベント
*/
constructor(callbackEvent) {
super(callbackEvent);
}
/**
* アクションを実行します。
*/
async execute() {
var postbackTime = this.callbackEvent.content.postback;
const sessionRepos = new SessionRepository();
let session = sessionRepos.get(this.getRoomId());
const meetingCreator = new ZoomMeetingCreator();
let startDateTime = null;
if (postbackTime) {
if (session.startDate) {
startDateTime = moment(`${session.startDate}T${postbackTime}`);
} else {
startDateTime = moment(`${moment().format('YYYYY-MM-DD')}T${postbackTime}`);
}
}
if (!startDateTime.isValid()) {
startDateTime = null;
}
const res = await meetingCreator.create(session.zoomAccountId, startDateTime);
console.log(res);
let message1 = {
content: {
type: BotMessageSender.MESSAGE_CONTENT_TYPE.text,
text: `Zoomミーティングを${session.zoomAccountId}で登録しました。\nHostのURLはこちら。`,
}
};
this.setMessageTo(message1);
let message2 = {
content: {
type: BotMessageSender.MESSAGE_CONTENT_TYPE.text,
text: `${res.start_url}`,
}
};
this.setMessageTo(message2);
let message3 = {
content: {
type: BotMessageSender.MESSAGE_CONTENT_TYPE.text,
text: `招待のURLはこちら。`,
}
};
this.setMessageTo(message3);
let message4 = {
content: {
type: BotMessageSender.MESSAGE_CONTENT_TYPE.text,
text: `${res.join_url}`,
}
};
this.setMessageTo(message4);
const sender = new BotMessageSender();
await sender.send([ message1, message2, message3, message4 ]);
session.startDate = null;
session.waitingForZoomAcountIdInput = false;
sessionRepos.save(session);
}
}
const moment = require("moment");
const Promise = require("promise");
const request = require("request-promise");
const jwt = require('jsonwebtoken');
/**
* MeetingCreatorクラス
*/
module.exports = class MeetingCreator {
/**
* Zoomのミーティングを作成し結果を返します。
* @param {string} zoomAccountId ZoomアカウントID
* @param {string} startDateTime ミーティング開始日時
* @return {object} ミーティング作成結果オブジェクト
*/
async create(zoomAccountId, startDateTime) {
let json = {
topic: 'LINE WORKS ZOOM連携',
type: 1,
time_zone: 'Asia/Tokyo',
agenda: 'LINE WORKS ZOOM連携してみる',
settings: {
host_video: true,
participant_video: true,
approval_type: 0,
audio: 'both',
enforce_login: false,
waiting_room: false,
registrants_email_notification: false
}
};
if (startDateTime) {
json.type = 2;
json.start_time = startDateTime;
}
const payload = {
iss: process.env.ZOOM_API_KEY,
exp: ((new Date()).getTime() + 5000)
};
const token = jwt.sign(payload, process.env.ZOOM_API_SECRET);
const options = {
method: "POST",
url: `https://api.zoom.us/v2/users/${zoomAccountId}/meetings`,
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${token}`,
},
json : json
};
return new Promise((resolve, reject) => {
request(options)
.then((res) => {
console.log(res);
resolve(res);
})
.catch((error) => {
console.log(`ERROR: ${error}`);
reject(error);
});
});
}
};
4. 動かしてみる
###1) GitHub から line-works-zoomer をクローンする
https://github.com/shotamaco/line-works-zoomer
###2) VS Code のターミナルでプログラムが使用している node.js の package をインストール
npm install
##3) 環境変数 (.env)
.env.sample ファイルを .env に変更して、
「Zoom API の利用準備」と「LINE WORKS Bot APIの利用準備」で発行した接続情報を設定する。
API_ID="API ID"
CONSUMER_KEY="Consumer key"
SERVER_ID="Server ID"
PRIVATE_KEY="Server 認証キー"
BOT_NO="Bot 番号"
ZOOM_API_KEY="Zoom API Key"
ZOOM_API_SECRET="API Secret"
###5) http 3000 で ngrok 起動!
ngrok http 3000
###6) スマフォを手に持って LINE WORKS を動かす
5. まとめ
DBを使用していないのでstatic変数で Server Token や Session データを管理しています。。。また例外処理はほとんどしてません。。。あくまでもLINE WORKSとzoomを連携させることを目的にしています。
今回作成たコードは GitHub の line-works-zoomer で公開してま〜す。
#Link