Cloud FunctionsつかってSlack Bot作ってみた話
ざっくりまとめ。
- Firebase の Cloud Functions をつかって Slack Bot つくった!
- リクエストの検証でハマった
- エンコードの仕様が違うので通らない
URLSearchParams
を使うといい
です。
追記(2019.02.04)
こっちの記事で実は取れたっていうのを書いた
環境
- firebase-tools v6.3.0
- node v6.16.0
やりたいこと
Cloud Functions をつかって何か遊びたいな〜と思ったので、
Slack Bot をつくってみることにしました。
とりあえず、色を指定したらその情報とかを返すやつ。
成果物
さきに完成したものを。
ハマったこと
Verifying requests from Slack というので詳しく書かれているので、ありがたく参考にしつつ実装しようとしたのですが、
どうも一致しないっていうことでハマりました。
(公開はしてないんで、別にやらなくてもいいのですけど。。)
request の body をとりたい
Cloud Functions でリクエストをうけると、
Request
っていうものを通してもろもろの情報をアクセスすることになるのですけれど、
これで body をそのまま受け取るためにはどうしたら。。?🤔
というのも、検証の手順のなかで、
'v0:' + timestamp + ':' + request_body
と文字列を作る必要があって、
このrequest_body
が必要なのです。
request.body
というので body にはアクセスできるけど、これはすでに Object
に変換されているものなので使えない。
request.rawBody
みたいなものがあればいいのですけれど、どうもなさげ。。
(request_raHeaders
はあるけれど。。。)
どうしたのか
結局 request.body
から文字列を再構築することにしました😇
const params = new URLSearchParam()
Object.keys(request.body).forEach(key => {
params.append(key, request.body[key])
})
const baseString = params.toString()
これで、欲しかった文字列を再構築することができました。
ダメだった方法
const baseString = Object.keys(request.body).map(key => {
return key + '=' + encodeURIComponent(request.body[key])
}).join('&')
これでもできるのだけれど、一部文字列だとだめなのです。
/cc aaaaaa
はできても /cc rgb(12,12,12)
は通らないみたいな。
どうやら ( と ) のエンコードが違うみたいです。
encodedURIComponent
では - _ . ! ~ * ' ( ) の記号が対象外みたいだけど、
多分 Slack 側でつかっているエンコードは対象外ではないんだろうな。。と
(どの規格でやってるんだろ。。。)
encodedURIComponent
のドキュメントをみると、
RFC 3986 に対応するためには〜〜というサンプルがあって、
そちらと同じようにやってもダメだったんですよね。。
ほとほと困っているところで、
encodedURIComponent
は最新のエンコード規格状況においきれてないので URLSearchParams
を使うと良いっていうのを見て
最初に紹介した成功例の通りやったら検証が通るようになりました💪
これで Slack Bot 生活が捗りそうです!
次は annict のなにか作ってみようかな〜