はじめに
社内のチャットなどで雑談や技術情報を共有するチャンネルを作っていることもあると思います。
弊社でもそんなチャンネルがあるのですが、ただ部屋を用意するだけでは一部の人が投稿するだけで、参加はしているけど直接質問でもされない限り発信をしない方も一定数は存在しています。
自ら発信しない人の中には、ただ業務として部屋に参加しているだけだしそこまで関わりたくないという人もいれば、人に聞かれれば答えるけど自分からは積極的に発信しない人など、発信しない(しづらい)理由はその人ごとにあると思います。1
今回は人に聞かれれば答えるけど自分からは積極的に発信しない人を後押しする為にSlack Appを作ったという話になります。
つくったもの
とりあえずSlackにした理由とかはあとにして、作ったものはこちらです。
部屋に追加した Bot(SlackApp)が部屋に参加してるユーザーにランダムで DM を送ります。
入力欄に回答を入力して投稿するとメッセージが回答済みのメッセージに入れ替わります。
投稿先への遷移ボタンと間違った場合の削除ボタンを加えています。


新しい方ではBolt.jsを削除してclaspでの管理に書き換えていたりボタンイベントを追加しています。
またGASでSlackのアクションイベントをフックする際のVerification Token
の検証についてはGoogle Apps Script (GAS) で Slack 連携を実装する前に知っておくとよい 5 つのことの記事を参考にさせていただきました。
作り直したプロジェクトはこちらです。
Chatty-for-GAS
前回作った時はREADMEに設定手順を箇条書きで書いていたので分かりづらかったと思い、手順を書き直しています。
設定手順を表示する(長いです)
環境
- node v16.0.0
- TypeScript v4.5.4
- clasp v2.4.1
設定
Slack App の登録
Slack Appでアプリ作成(Create New App
)する
作成時に From an app manifest (BETA)
を選択しておくと yml 貼るだけで権限登録の手続き減るのでおすすめです
対象のワークスペースを選択します

次に下の yaml を貼り付けて権限周りなどの設定の登録をします

yaml の中身
request_url
の値は後に Google Apps Script の公開 URL に変更します。
display_information:
name: Chatty
features:
bot_user:
display_name: Chatty
always_online: true
oauth_config:
scopes:
bot:
- chat:write
- im:history
- im:read
- im:write
- mpim:read
- mpim:write
- channels:history
- channels:read
- groups:history
- groups:read
- groups:write
settings:
interactivity:
is_enabled: true
request_url: https://script.google.com/
org_deploy_enabled: false
socket_mode_enabled: false
token_rotation_enabled: false
登録が終わったらCreate
します。

後でスプレッドシートの環境変数に登録する 2 つのトークンを作成、保存しておきます。
Slack Bot Token 取得
最初に Slack の Bot トークン(xoxb
で始まるトークン)を取得します。
サイドメニュー -> OAuth & Permissions
-> OAuth Tokens for Your Workspace
-> Install to Workspace
で作成できます。
ワークスペースに追加していきます。

無事にワークスペースに追加されるとトークンが取得できます。
Slack Verification Token 取得
次にVerification Token
を取得します。
これは最初から生成されているので値をコピーするだけです。
サイドメニュー -> Basic Information
-> App Credentials
-> Verification Token
から取得できます。
Google Apps Script API を有効にする
Google Apps Script API が有効でなければ有効化しておく必要があります。
ここからオンに切り替えできます。
clasp インストール と ログイン(初回のみ)
コードの管理がしやすいようにclaspを使用しています。
インストール
npm install -g @google/clasp
ログイン
clasp login --no-localhost
URL が出てくるのでアクセスして許可して、出てきたコードをコマンドプロンプトに入力します。
成功するとユーザールート階層に.clasprc.json
が作られます。
スプレッドシートとスクリプトプロジェクトの作成
このプロジェクトを clone してプロジェクト直下で
次のコマンドを実行するとマイドライブの下にスプレッドシートが作成されます。
clasp create --type sheets
成功するとスプレッドシートとスクリプトの URL が表示されます。
シートの編集
シートが作成されたら質問を記入します。
A 列の質問を読み取るようにしています。

プロジェクトの push と確認
まだ Apps Script 内も空なのでプロジェクトを push していきます。
clasp は TypeScript にも対応しているのでこのまま push すると変換してくれます。
clasp push
シートの拡張機能からか、次のコマンドでスクリプトページを開く事も可能です。
clasp open
スクリプトプロパティの登録
古いエディターの方で設定できるので切り替えていきます。
メニューからプロパティの各項目を設定していきます。

- SLACK_BOT_TOKEN
- SLACK_VERIFICATION_TOKEN
- CHANNEL_ID
- 投稿先のチャンネル ID メニューの
Open channel details
->about
の一番下などから取得できるC0
から始まる文字列になります。
- 投稿先のチャンネル ID メニューの
- BOT_ID
- Slack App の詳細で Bot の MemberID が取得できます
Bot の MemberID 取得場所

設定ができたら更新します。

GAS の公開
メニュー -> 公開 -> ウェブアプリケーションとして導入... を選択します

デプロイ画面でバージョンやアカウント、Who has access to the app の項目はAnyone, even anonymous
を選択します。

初回の公開時には許可の確認が求められます。
警告などが表示されますが、内容を確認しながら赤枠の項目から許可をしていきます。




無事に公開が完了すれば URL が取得できるのでこれを**Slack App の登録の request_url**に設定していきます。
yaml 内のrequest_urlの値を上書きして保存します。

動作確認
チャンネルを作成して、自分と Slack App を追加して関数(postQuestion)を実行すると冒頭の流れになります。

無事に動作しているなら、あとは定期実行などの処理を設定すれば完了です。
前に作ったBolt.jsのSlackApp
開発
Slack Appの作成は初めてでしたが、公式ページの入門ガイドで動きを把握してから、GitHubのTypeScriptで作られたプロジェクトのサンプルをベースに作りました。
Bolt 入門ガイド
GitHub bolt-js/examples/getting-started-typescript
Chatty
Slack Appの画面で登録設定さえしてもらえれば手元で動作確認は可能です。
手順はREADME.mdに記載しています。
質問を自分たちで編集したり、社内で運用する目的で作成したのでSlack Appディレクトリに公開はしていません。
あと、これは試作段階で用意したサンプルになります。
実際に運用しているプロジェクトは別にあります。
なぜSlackなのか
弊社はフルリモートワークなので、最初はチームの雰囲気を作りながら情報交換する流れを作れるかなと思い、GatherやTeamflowなどのバーチャルオフィスツールを導入しようかと考えましたが、開発メンバーはそれぞれ別のプロジェクトに参加していて、ミーティングの時間帯が違うことや、プロジェクトが忙しい時は参加するのは難しいかもという声も多くありました。
その中で社内で普段使用しているSlackでの情報共有が一番負担が少なくできそうという考えは共通していたので、Slackで情報交換する場をもっと活性化させていこうと考えた事がきっかけです。
Collaとの出会いと開発動機
活性化させるには情報発信に抵抗がある人たちにも投稿してもらいたいが、投稿依頼などするのも何か違うなと考えていたところ、弊社では元々別の雑談部屋にCollaを導入しているのを思い出し、人と比べてBotからの質問なら無視をしても気にならないし、質問された事を答えているという体なので何もないところから投稿するよりも心理的な負担が少なくなるかなと考えました。
雑談でのコミュニケーション活性化ならCollaの質問のバリエーションや機能が豊富で優れているのですが、質問パターンに雑談だけでなく技術に関わる質問も用意したかったのとCollaは回答を一定時間ストックするような仕様があった為、社内用に作成することにしました。
運用ルール
ざっくり決めたルールはこんな感じです。
- 質問Botはcronで週1回の営業日にチャンネル参加メンバーの中からランダムで数名抽出する(毎回全員に送るようなことはしない)
- 質問はランダムで選ばれるが、他の質問を要求できるので答えれる質問だけに答えれば良い
- Botからの質問は答えたいときに回答してOK(気分が乗らない時は無視しても良い)
ゆるく情報交換できる文化の土台ができればとよいと考えているので、部屋に参加してもらう以外の強制は極力しない方針にしています。
こういった事を始めるときには、ある程度の強制力もないと難しく失敗してしまうこともあるのですが、個人がガチガチに決めたルールで作られた場よりも、少しの決まりだけで時間をかけながら徐々に自分たちに合った形ができあがってくる方が理想に近かった為、ゆるいルールで進めています。
運用してみて
導入したばかりなので結果はこれから見えてくると思います。
ある程度は作り替えていければと考えていますが、チームに合わなければ全く別の方法に変更もしていくと思います。
おわりに
弊社もこれからずっとリモートワークが続いていくので全てのことがオンラインで成り立つように今後も色々と取り組んでいきたいです。
今回の事もこれだけで全てが上手くいくとは考えていませんが、目に見えるところから少しづつ変化をつけていければと思います。
-
そもそも心理的安全性が低い環境だと...というのはあるかと思いますが、今のチームは低い状態ではないです。オンラインで会話する時も話のタネがあれば雑談で盛り上がったりしている状態なのでどちらかというと高めな方だと思っています。 ↩