はじめに
今来ているこのビックウェーブに乗って、MS Teamsのボットで「名前を奪ってみようと」思います。
MS Teamsの送信Webhook
公式のマニュアルを見ながらいろいろやっていきます。
ボットの作成
まずは湯婆婆ボットを作ります。
チームを管理
> アプリ
を選択して、右下にある 送信 Webhook を作成
をクリックします。
送信 Webhook を作成していきます。
名前とコールバックURLを指定して「作成」します。
作成したときにシークレットキーが表示されるので忘れずにメモっておきます!
これで、Teamsからボットを呼べるようになります。
コールバック側の処理
なんでもいいんですが、今回は手元に環境があったNode.js + Express4で実装します。
まずはnpmでインストール
$ npm install express --save
$ npm install body-parser --save
で実装はこんな感じ
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const port = 3001;
const crypto = require('crypto');
const sharedSecret = ''; // ここにシークレットキーを入れてください
const bufSecret = Buffer(sharedSecret, "base64");
let rawBodySaver = (req, res, buf, encoding) => {
if (buf && buf.length) {
req.rawBody = buf.toString(encoding || 'utf8');
}
};
let jsonParser = bodyParser.json();
app.use(bodyParser.urlencoded({
verify: rawBodySaver,
extended: true
}));
app.use(bodyParser.json({verify: rawBodySaver}));
app.use(bodyParser.raw({verify: rawBodySaver, type: '*/*'}));
app.post('/ubaba/', (req, res, next) => {
let auth = req.get('authorization');
let msgBuf = Buffer.from(req.rawBody, 'utf8');
var msgHash = "HMAC " + crypto.createHmac('sha256', bufSecret).update(msgBuf).digest("base64");
//console.log("Computed HMAC: " + msgHash);
//console.log("Received HMAC: " + auth);
if (msgHash == auth) {
next();
} else {
res.json({ "type": "message", "text": "Error: message sender cannot be authenticated." });
}
});
app.post('/ubaba/', jsonParser, (req, res) => {
let name = req.body.from.name;
let newName = name.substr(Math.round(Math.random() * name.length) -1, 1);
res.json({ "type": "message", "text": "フン。"+name+"というのかい。贅沢な名だねぇ。<br>今からお前の名前は"+newName+"だ。いいかい、"+newName+"だよ。分かったら返事をするんだ、"+newName+"!!"});
});
app.listen(port, () => console.log(`Eample app listening on port ${port}!`));
起動
$ node index.js
(node:10057) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
Eample app listening on port 3001!
Bufferの使い方があまりよくないみたいですが、公式がこう書いているのでいったんそのままにしておきます。
使い方としてはこんな感じ
名前はreq.body.from.name
に入ってくるのでこれを加工してます。
苦労した点
公式のNode.js実装では生のNode.jsを使っているので、リクエストボディのデータを素直にとって来れるんですが、expressの場合はBodyParserがパース処理をしてしまうのでハッシュ値の計算がうまくいきません。
そのため、認証部分では生データを使って、「名前を奪う」処理では改めてBodyParserを指定して処理しています。
参考記事
送信 Webhook を使用して Microsoft Teams にカスタム ボットを追加する
Node.js Express でPOST本文のRawBodyを取得する