匿名投稿Slack Appの作り方

# 概要

会社のSlackで匿名投稿App(bot)を作りました。
![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277107/d248b1e0-e3a4-1e9b-3fd5-e6db566c07cc.png)
作った主な理由は、スペシャリストチームへの質問や社内勉強会の質疑応答などで、実名だと質問しづらい場合もあるのでは？と思ったからです。（意見を言いにくい関係性、無知を晒すのがこわいなど）

Appが入力された通り発言するだけの簡単なアプリですが、デプロイまでの軌跡をメモとして残します。

# ソースコード
https://github.com/tonionagauzzi/slack-anonymous

# App作成手順
1. [Slack API](https://api.slack.com/apps/)のページで"Create a new app"します。
1. [Slack API](https://api.slack.com/apps/)の作成したAppのメニューで"OAuth & Permissions"を選び、Bot User OAuth Tokenをメモします。7.で使います。また、"Add an OAuth Scope"でアプリのアクセス権に`chat:write`と`commands`を追加します。
1. ローカルでNode.jsを使ってSlack Appのスクリプトを生成します。
  * ルートディレクトリに[package.json](https://github.com/tonionagauzzi/slack-anonymous/blob/master/package.json)を置き、`npm install`。
  * [./resources/api](https://github.com/tonionagauzzi/slack-anonymous/tree/master/resources/api)に投稿用の[slack_anonymous.js](https://github.com/tonionagauzzi/slack-anonymous/blob/master/resources/api/slack_anonymous.js)と削除用の[slack_anonymous_delete.js](https://github.com/tonionagauzzi/slack-anonymous/blob/master/resources/api/slack_anonymous_delete.js)の2つを置きます。スラッシュコマンドとの連携は8.で行います。
  * `npm run dev`でビルドすると、実行可能スクリプトが[./dist/api](https://github.com/tonionagauzzi/slack-anonymous/tree/master/dist/api)に書き出されます。
  * 5.で登場するNetlifyにビルドさせるための設定ファイル[Netlify.toml](https://github.com/tonionagauzzi/slack-anonymous/blob/master/netlify.toml)も作ってルートに置きます。
1. [GitHub](https://github.com/tonionagauzzi/slack-anonymous)にスクリプトをコミットします。
1. サーバーレスバックエンドの[Netlify](https://www.netlify.com/)に登録し、サイトを開設します。このとき"New site from Git"を選択し、GitHubと連携します。
1. [Netlify](https://www.netlify.com/)の作成したサイトのメニューで"Site settings"→"Functions"を選び、"Functions directory"に`dist/api`を登録します。
  * これでGitHubのmasterの./dist/apiがEndPointに自動デプロイされるようになります。
1. [Netlify](https://www.netlify.com/)の作成したサイトのメニューで"Site settings"→"Build & deploy"を選び、"Environment"に先ほどメモしたBot User OAuth Tokenを環境変数`SLACK_BOT_OAUTH_TOKEN`として登録します。
  * これが[JS側](https://github.com/tonionagauzzi/slack-anonymous/blob/master/resources/api/slack_anonymous.js#L10)に`process.env.SLACK_BOT_OAUTH_TOKEN`として渡され、Slackの認証に使われます。
1. [Slack API](https://api.slack.com/apps/)に戻り、"Slash Commands"でスラッシュコマンド`/anonymous`と`/anonymous-delete`を登録します。
  * "Request URL"には[Netlify](https://www.netlify.com/)のサイトのFunctionsから各スクリプトのEndPoint URLをコピーしてきます。


以上でAppは完成です。

# スラッシュコマンドの使い方

匿名投稿したいチャンネルにAppを招待すれば、`/anonymous`と`/anonymous-delete`がコマンドとして使えるようになります。

• `/anonymous メッセージ`  →メッセージを匿名で投稿
• `/anonymous-delete https://myworkspace.slack.com/archives/C026QN2BSUQ/p1624499864003700` →該当の匿名メッセージを削除

# 苦労した点

投稿機能で、[postMessageの引数のchannel](https://github.com/tonionagauzzi/slack-anonymous/blob/master/resources/api/slack_anonymous.js#L23)（宛先）に`/anonymous`を打ったチャンネルを動的に指定したくて、どうすればよいか最初わからなかったのですが、色々試した結果`body.channel_id`で解決しました。

削除機能でも、やはり[deleteの引数に指定するchannelとts](https://github.com/tonionagauzzi/slack-anonymous/blob/master/resources/api/slack_anonymous_delete.js#L18-L22)をどう取得するかが課題でしたが、[chat.deleteテストページ](https://api.slack.com/methods/chat.delete/test)で色々試して、URLを分解するやり方に気づきました。

> https://myworkspace.slack.com/archives/C026QN2BSUQ/p1624499864003700
> の場合はchannelはC026QN2BSUQ、tsは1624499864.003700

# 匿名投稿を導入して気づいたこと、決めたこと

* Slackには誰が入力中かわかる機能があるので、別の場所で書いてコピペした方が良い（この時点でやや使いづらい…）
* 返信スレッドでのカスタムスラッシュコマンドは現時点でSlack側が対応していない（[JS側では考慮した](https://github.com/tonionagauzzi/slack-anonymous/blob/master/resources/api/slack_anonymous.js#L8)のに…）
* 悪用防止のため発言ログをバックエンドに出力しようか悩んだ
  * 結局、誰が発言したかは管理者も知らないべきだと考え、使い手の善意に委ねることにした
* どんなチャンネルでも使っていいわけではない
  * 例えば給湯室の雑談やG&Nは、誰がどういう人か知れるきっかけなので匿名は適さない

# 参考にしたサイト

…は色々あったのですが、作成から記事執筆まで時間が経ちすぎて失念してしまいました。すみません。