はじめに
今来ているこのビックウェーブに乗って、MS Teamsのボットで「名前を奪ってみようと」思います。
MS Teamsの送信Webhook
公式のマニュアルを見ながらいろいろやっていきます。
ボットの作成
まずは湯婆婆ボットを作ります。チームを管理
> アプリ
を選択して、右下にある 送信 Webhook を作成
をクリックします。
送信 Webhook を作成していきます。
名前とコールバックURLを指定して「作成」します。
作成したときにシークレットキーが表示されるので忘れずにメモっておきます!
これで、Teamsからボットを呼べるようになります。
コールバック側の処理
なんでもいいんですが、今回は手元に環境があったNode.js + Express4で実装します。
まずはnpmでインストール
$ npm install express --save$ npm install body-parser --save
で実装はこんな感じ
index.js
constexpress=require('express');constapp=express();constbodyParser=require('body-parser');constport=3001;constcrypto=require('crypto');constsharedSecret='';// ここにシークレットキーを入れてくださいconstbufSecret=Buffer(sharedSecret,"base64");letrawBodySaver=(req,res,buf,encoding)=>{if(buf&&buf.length){req.rawBody=buf.toString(encoding||'utf8');}};letjsonParser=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)=>{letauth=req.get('authorization');letmsgBuf=Buffer.from(req.rawBody,'utf8');varmsgHash="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)=>{letname=req.body.from.name;letnewName=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を取得する