はじめに
開発でBotを活用する場面は少なくないと思いますが、皆さんはどうやって実装していますか?
簡単なものであれば、webhookにpostするだけで終わるのでガリガリ書くのもありですが、
インタラクティブな処理を書こうと思った場合には、やっぱりフレームワークを使ったほうが楽ですよね。
ただ、botのためだけにサーバー管理はしたくないのですが、
公開されているbotフレームワークは、
サーバーレス環境へのデプロイは考慮されていないようでした(自分のググりが足りないかもしれませんが)
そこで、AWSのサーバーレスでMS BotFrameworkを動かせるようにするのが今回の話です。
今回のコードはこちらのgithubリポジトリで公開しています。
https://github.com/takaaki-s/serverless-botframework
どうやって動かそうか考えた
今回、数あるBotFrameworkの中でも本命の、Microsoft BotFrameworkと
Slackを使いたかったので、botbuilder-adapter-slackを使いました。
このadapterは内部でExpressを使用しているので、
aws-serverless-expressを使うとサーバーレス動かせそうというのも選択のポイントです。
それから、このBotFrameworkは会話の状態をメモリ上に保存しますが、
Lambdaはステートレスなので、ステートをS3に保存するためのライブラリを自作しました。
https://github.com/takaaki-s/botframework-s3storage
動作チェック用に、公式のexampleから2つピックアップして移植しています。
- simple-slack-bot
- botbuilder-adapter-slack公式example
- チャットの内容に反応してメッセージを表示、削除したりダイアログを表示する。
- botbuilder-adapter-slack公式example
- store-bot
- BotFramework公式のnodejs用example、45.state-management
- 話しかけたユーザーの名前をステートに保存して、呼び出す。
- BotFramework公式のnodejs用example、45.state-management
公式のサンプルコードと見比べてもらうとわかるのですが、
変更しているのはExpressまわりだけで、Botのロジック部分はほとんどいじらずに動かせました。
注)
botbuilder-adapter-slackの公式サンプルはイベント判定でバグっているような箇所があるのと、
setTimeout関数がうまく動かないので、そこは手直ししています。
では、サンプルを動くところまでやっていきますので、
適当なディレクトリにgitからクローンしておきます。
git clone https://github.com/takaaki-s/serverless-botframework
Slackの準備
まずは、Slack側でApp(Bot)を作成しての各種トークンを取得します。
https://api.slack.com/apps
必要になるのは、
Basic Information画面のSigning Secret
とVerification Token
、
OAuth & Permissions画面のBot User OAuth Access Token
です。
デプロイの準備
simple-slack-bot
を動かしてみますので、
ここからはexample/simple-slack-bot
ディレクトリ内で作業します。
setting.yml.example
をsetting.yml
としてコピーしてSlackで取得したトークンを書き込みます。
これがServerlessFrameworkがデプロイ時に吐き出すCloudFormationテンプレートファイルに埋め込まれてデプロイされます。
ただ、こういった情報がファイルに埋め込まれるのはあまりよろしくないので、
実際に運用する際はSSMのParameterStoreやSecretsManagerを使うようにしましょう。
# Basic InformationのSigning Secret
CLIENT_SIGNING_SECRET: ''
# OAuth & PermissionsのBot User OAuth Access Token
BOT_TOKEN: ''
# Basic InformationのVerification Token
VERIFICATION_TOKEN: ''
デプロイ
npm、node.js、serverlessframeworkはインストールされていて、
ローカルにawsのクレデンシャルが置かれているのが前提です。
ローカルにクレデンシャルがおいてある状態とはaws configureの解説を参照するのがわかりやすいです。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html
$ node -v
v11.6.0
$ npm -v
6.9.0
$ sls -v
1.45.1
まずは、node moduleをインストールします。
npm install
そして、おもむろにServerlessFrameworkのデプロイコマンドを叩きます。
お好みでオプションを使用してください。
ちなみに、自分の好みはデプロイ状況が見られる-v
オプションです。
sls deploy -v
デプロイが終わるとターミナルにデプロイ情報が表示されます。
その中のendpoints:
がApi Gatewayのエンドポイントになりますので、
先程SlackでAppを作った画面に戻り、そのエンドポイントをEvent Subscriptions画面のRequest URLと
Interactive Components画面のRequest URLに設定します。
それから、SlackのEvent Subscriptions画面のSubscribe to Bot EventsでBotが受信するイベントを設定します。
メンションを受信するならapp_mention
チャンネルのメッセージを受信するならmessage.channels
です。
Slackで確認する
とりあえず、Slackに適当なチャンネルを作り、先程作ったBotをそのチャンネルに招待しましょう。
/invite @bot名
そして、delete
やupdate
等メッセージを流すとBotが反応してくれるはずです。
お疲れ様でした!
次回
これでユーザー起点のイベントは動かせるようになったので、
次回はBot側から発信(通知)する仕組みを作っていきます。
これができると、アラートやデプロイ状況の通知に使えるようになりますね。
リンク
AWS Serverless Express
https://github.com/awslabs/aws-serverless-express
Microsoft BotFramework
https://github.com/Microsoft/botframework
botbuilder-adapter-slack
https://github.com/howdyai/botkit/tree/master/packages/botbuilder-adapter-slack
ServerlessFramework
https://serverless.com/