Firebase + Spreadsheet で Slack Bot を作ったら社内用語辞典の運用が3倍楽しくなった話
最近作った Slack Bot が好評だったのでまとめてみました!
どこの Slack ワークスペースでも導入できるように詳細に設定方法も記載しています。
🛠 作ったもの
tell-me-bot(社内では tell-me-paccho)という、社内用語辞典をいい感じに管理してくれる Slack Bot を作りました。
社内ではもともと Spreadsheet で社内用語を管理していたのですが、メンテナンスする人が限られ、あまり積極的には利用されていない状況でした。
そんな時に@しかじろうさんのこちらの記事を発見して、これはおもしろいアイデアだと思い、Firebase + Bolt(TypeScript)にて作ってみました(アイデアをくれた@しかじろうさんに感謝🙏)。元記事の機能を参考に+αの機能も色々実装しています。
構成
Cloud Functions for Firebase で Slack アプリのフレームワークである Bolt.js を動かし、Slack の Event API や Action API のリクエストに応じて社内用語辞典の Spreadsheet を操作しています。
また、後述する曖昧検索の実現のために、Fuse.js を内部的に利用しています。
Spreadsheet との通信は Cloud Functions のサービスアカウトを利用して googlea-api-nodejs-client を使っています。
DB として Firestore ではなく Spreadsheet を使った理由はこちらです。
- もともと社内用語辞典が Spreadsheet で管理されていたのでそれをそのまま使える
- エンジニア以外でも誰でも手軽に辞書データを直接追加・編集・削除を出来る(重要!)
- Slack のインタフェースで編集・削除の機能を実装するのが面倒
実装も全て GitHub で公開しています(⭐を貰えると泣いて喜びます)。
💡 機能詳細
tell-me-bot の機能を紹介します。
用語の検索
完全一致する用語を tell-me-bot にメンションした場合は、即結果が表示されます。もし説明が間違っていた場合は、メッセージ記載の Spreadsheet のリンクから編集できます。
曖昧検索への対応
もし、完全一致はしないけれども似たような単語がある場合は、候補を表示します。候補のボタンを押すと、その用語の説明を答えてくれます。
内部的には Fuse.js の Fuzzy Search を利用しています。
これがこのボットの一番の売りの機能です。曖昧な問いかけからも正確な情報を取得できます。
用語の追加
もし曖昧検索の結果が間違っていたり、検索に該当する用語がない場合は、Slack のモーダルから用語を新規に追加することもできます(Spreadsheet を直接編集することでも可能です)。
手軽に追加できるので、気づいたときにどんどん用語を増やすことができます。
質問チャネルへの代理質問(Optional)
用語を新規に登録しようにも、用語の意味がわからない場合が多いですよね。その場合は、社内の質問チャネルに tell-me-bot が代理質問する機能もあります。
自分の所属する LAPRAS社 では、#ask-anything
という以下の理念で運用されているチャネルがあるのでそこに質問を投げるようにしています。
#ask-anything
LAPRASに関するあらゆることについて、誰でもなんでもいつでも何回でも質問してよいチャンネル。大事なことは、質問されたことにLAPRASの誰かがかならず反応すること。反応は早ければ早いほどよい(回答が得られなくても仕方ない。反応があることがだいじ)。
実際に以下のように投げられて、都度専門知識をもつメンバーが用語を登録してくれてとても助かっています。
質問したチャネル | ask-anythingチャネル |
---|---|
💬 社内の声
会社の Slack でも嬉しい声を頂いたので一部紹介します!
やはり使って感想をもらえるのは開発者として一番嬉しいですね😆
社内の声 |
---|
実際に社内用語辞典は急速に充実していっています。
個人開発のアプリを気軽に紹介できて、ポジティブなフィードバックを貰える社内環境はとても良いなーと思っています。
👨💻 設定方法
基本的にコードは全て公開しているので、以下手順でどの Slack にも導入できるはずです。
事前準備
事前に以下を準備します。
-
Firebase CLI
- 任意のシェルでセットアップしておいてください
- 空の Firebase プロジェクト
- Blaze プラン(従量課金プラン)にプラン変更してください
- 任意の Spreadsheet
- 1 枚目のシートの A1 に用語、B1 に説明というヘッダーを追加しておいてください
- Spreadsheet の ID をメモしておいてください(参考)
Slack APPの作成(1)
Slack の Your Apps にアクセスして Create New App
を押します。
選択後表示されるモーダルで From app manifest
を選択します。
次にアプリを追加する Slack ワークスペースを選択します。
次に manifest の入力欄が表示されるので以下を入力します。
display_information:
name: tell-me-bot
description: tell-me-bot
background_color: "#323336"
features:
bot_user:
display_name: tell-me-bot
always_online: true
oauth_config:
scopes:
bot:
- app_mentions:read
- chat:write
- im:history
- im:read
- im:write
- users:read
- channels:read
settings:
event_subscriptions:
request_url: https://example.com
bot_events:
- app_mention
- message.im
interactivity:
is_enabled: true
request_url: https://example.com
org_deploy_enabled: false
socket_mode_enabled: false
is_hosted: false
token_rotation_enabled: false
最後に確認が表示されるので、create ボタンを押せばアプリが作成されます。
アプリが作成されたら以下 2 の値をメモしておきます。
- Basic Information > App Credentials の
Signin Secret
- OAuth & Permission > OAuth Tokens for Your Workspace の
Bot User OAuth Token
この値は次の Firebase の設定で使います。
また、App Home > Show Tabs から Message Tab の設定を ON にしてAllow users to send Slash commands and messages from the messages tab
にチェックしてください。これを設定することで、tell-me-bot との DM でも社内用語辞典の操作が行えるようになります。
Firebase プロジェクトのデプロイ
tell-me-bot のリポジトリを任意のディレクトリでクローンします。
$ git clone https://github.com/kawamataryo/tell-me-bot
$ cd tell-me-bot
最初に Firebase CLI でプロジェクトの設定を行います。
プロジェクトの ID は firebase projects:list
で確認できます。
$ firebase use <事前準備で作成したプロジェクトのID>
そして Firebase の環境変数を設定します。
ここで今まででメモしてきた値を設定します。
# Slack APPの作成でメモしたBot User OAuth Tokenの値
$ firebase functions:config:set slack.bot_token="xxxx"
# Slack APPの作成でメモしたSignin Secretの値
$ firebase functions:config:set slack.signin_secret="xxxx"
# 質問チャネルがある場合は、質問チャネルのIDを指定。ない場合は空文字を指定。
$ firebase functions:config:set slack.ask_channel_id=""
# 事前準備で用意したSpreadsheetのID
$ firebase functions:config:set sheet.id="xxxx"
次に functions ディレクトリの依存モジュールを install します。
$ npm --prefix ./functions i
最後にデプロイです。
$ npm --prefix ./functions run deploy
完了後のログで functions の URL が確認できるのでメモします。
GCPの設定
GCP のダッシュボードにアクセスし、Firebase で作成したプロジェクトを指定してください。
そしてメニューから Google Sheets API を開き有効化します。
これは tell-me-bot の内部で Spreadsheet の操作に Google Sheet API を利用しているためです。
次に、メニューからサービスアカウントを開きます。
2 つのサービスアカウントが作成されていると思うので、App Engine default service account
の方のメールアドレスをメモします。
最後に、事前準備で作成した Spreadsheet を開き、先程メモしたアカウントに対して編集権限を設定します。
これで GCP 側の準備は完了です。
Slack APPの設定(2)
Slack APP に戻り、App Manifest を開きます。
そこで、manifest の設定で以前example.com
としていた箇所を、先程メモした fucntions の デプロイURL/events
を記載します。必ず後ろに/events
をつけてください。
そして Save Change を押します。ここで上部に Verify Error と出る場合は functions の環境変数の設定か URL が間違っている可能性があるので確認してください。functions の log を見るとわかりやすいです。
最後に Slack APP を指定のワークスペースにインストールします。
Install App から Install Workspace
を実行してください。
動作確認
インストールした Slack Work スペースの任意のチャネルに tell-me-bot を追加してメンションしてみてください。
bot が答えてくれれば全て完了です。もしエラーが出る場合は Firebase のログを確認してください。
おわりに
個人的にもとても便利で、どの会社にもあって良いなと思ってます。使ってもらえると嬉しいです!
設定方法に詰まりましたら、気軽に Twitter DM か記事コメントで連絡ください。ベストエフォートでサポートします!
Discussion
僕のやつより100万倍ちゃんとしてる!!!!!!!!!!
うおお!しかじろうさん!!
ありがとうございます!!
しかじろうさんの記事ありきで開発スタートしたので本当に感謝です🙏
めっちゃ良いアイディアだと思いました!
記事を参考に導入させていただきました。
大変便利で感謝しております。
実用しておりまして、1点困ったことが起きましたのでご相談です。
もしよろしければ回答いただけますと幸いです。
鍵付きのプライベートチャネルでもtell-me-botを使えるようにしたいです。
鍵付きのプライベートチャネルでもほぼ問題なく利用できますが、
「曖昧検索への対応」の候補をクリックした時だけエラーメッセージが表示されます。
※通常のパブリックチャネルでは問題ありません。
確認してみました。
何かの権限が足りない、と言われているのはわかりましたが、
(非エンジニアのおじさんでは)具体的にどこを修正すればいいのか検討がつかず、
こちらにコメントさせていただきました。
使ってもらえて嬉しいです!
おっしゃるとおり権限が足りないようです!
エラーメッセージに以下のような記載があるので、
groups:read'
を App ManifestのScopes/bot 以下の部分に追記してください!変更後、おそらくSlackアプリの再インストールを促されるので、そちらもお願いします。
社内言語の共通化を現在行なっているのですが、こちら大変参考になり、導入を検討しています。
slackbotの通知のテキスト内容を変更したいのですが、こちらforkしてテキストなどの改変を加えてもよろしいでしょうか?
返信遅れてすいません!!
もちろん大丈夫です!!!
記事を参考に導入を検討しているのですが、エラーが出て導入ができないです;;
Error: Error occurred while parsing your function triggers.
TypeError: Cannot read properties of undefined (reading 'key')
at Object.<anonymous> (/Users/kensuke/Downloads/bot/tell-me-bot-main/functions/lib/v1/bolt/app.js:73:53)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/Users/kensuke/Downloads/bot/tell-me-bot-main/functions/lib/v1/index.js:23:27)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
具体的にどこを修正すればいいのかわからず、
こちらにコメントさせていただきました。
よろしくお願い致します
この記事を書いた後に、追加したChatGPT機能の影響で、OpenAIのキーを設定していない場合に落ちるようになっていました😅
以下の変更をしてみてください。
ありがとうございます!!
無事デプロイできたので、試したのですが、同じようなログが出でしまいました😅
何度もすみません
UnknownError: Cannot read properties of undefined (reading 'key')
at asCodedError (/workspace/node_modules/@slack/bolt/dist/errors.js:35:12)
at App.handleError (/workspace/node_modules/@slack/bolt/dist/App.js:613:57)
at App.processEvent (/workspace/node_modules/@slack/bolt/dist/App.js:598:25)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async ExpressReceiver.requestHandler (/workspace/node_modules/@slack/bolt/dist/receivers/ExpressReceiver.js:239:13) {
code: 'slack_bolt_unknown_error',
original: TypeError: Cannot read properties of undefined (reading 'key')
at /workspace/lib/v1/bolt/events/useMentionEvent.js:35:27
at /workspace/node_modules/@slack/bolt/dist/App.js:575:33
at invokeMiddleware (/workspace/node_modules/@slack/bolt/dist/middleware/process.js:20:16)
at next (/workspace/node_modules/@slack/bolt/dist/middleware/process.js:13:29)
at Array.<anonymous> (/workspace/node_modules/@slack/bolt/dist/middleware/builtin.js:233:15)
at invokeMiddleware (/workspace/node_modules/@slack/bolt/dist/middleware/process.js:12:53)
at next (/workspace/node_modules/@slack/bolt/dist/middleware/process.js:13:29)
at Array.onlyEvents (/workspace/node_modules/@slack/bolt/dist/middleware/builtin.js:63:11)
at invokeMiddleware (/workspace/node_modules/@slack/bolt/dist/middleware/process.js:12:53)
at processMiddleware (/workspace/node_modules/@slack/bolt/dist/middleware/process.js:22:12)
}
あー。なるほど。他にも参照しているところがあったようです。
以下の変更を試してください。
何度も質問して申し訳ないのですが
consoleのログで、エラーが起きてるのですが、2時間悩んでいまして、質問させていただきました
よろしくお願い致します
なお、環境変数が登録できないのですが、対象をお教えいただきたいです
Please deploy your functions for the change to take effect by running firebase deploy --only functions
エラーの件は、スプレッドシートのURLが間違っているか、GCPのサービスアカウントに編集権限がないのだと思います。
記事のGCPの設定の欄をご確認ください。
これはどの環境変数の件を指しているのでしょうか?