はじめに
Slack上で、「人の目を気にせず気軽に発言できる」環境を作ることで心理的安全性を確保し、コミュニケーションの活性化につなげたい、という考えから匿名で投稿できる仕組みを作りたいと思っていました。
残念ながらSlackの標準機能では匿名投稿できる機能はないですが、ワークフローやショートカットを使って匿名投稿のような仕組みを構築することは可能です。ただ、次のような課題を感じました:
-
ショートカットやワークフローは他のチャンネルからも見えてしまう
→ 特定のチャンネルでのみ使わせたい用途には不向き。 -
「⚡」メニューや「/コマンド」はUI的に分かりづらく気軽に使えない
→ 「/コマンド」は打ち間違いにより、「〇〇さんが入力中です」が表示される危険性がある
そこで今回は、以下の構成で特定のプライベートチャンネルに限定した匿名で投稿できる機能を作ってみました。:
- Slack上に「匿名投稿ボタン」を設置し、モーダルから投稿内容を送信することで視覚的に使いやすく
- 送信した内容はbotが代わりに投稿(匿名投稿)
- 投稿内容には Gemini を使ってAIが自動で返信
- 投稿先のチャンネルはプライベートチャンネルに限定
実装には Python と slack_bolt ライブラリを使用し、モーダルを使ったUIと匿名投稿の処理をシンプルな構成で実現しています。
本記事では、サーバーは使用せず、Slack Botはソケットモードで構築し、Google Colab上から実行 する方法で紹介します。
Slackアプリの設定
この章では、匿名投稿ボットを動かすために必要なSlackアプリの作成と設定手順を紹介します。
今回は ソケットモード(Socket Mode) を利用し、Google Colab上でBotを動かす構成を取っています。
1. Slackアプリの作成
- Slack APIページにアクセスし、「Create New App」をクリック
- 「From scratch」を選択し、任意のアプリ名とワークスペースを入力して作成
2. Socket Mode を有効化
- 左サイドバーから "Socket Mode" を選択
- 「Enable Socket Mode」をONにする
- 表示されたモーダル中の「Token Name」に任意の名前を入力し、「Generate」をクリック
- 発行された App Token(
xapp-...)を控えておく
※Colab 側でSLACK_APP_TOKENとして使用します
3. Bot Tokenのスコープ設定(OAuth & Permissions)
- 左サイドバーから "OAuth & Permissions" を選択
- Bot Token Scopes に以下のスコープを追加:
| スコープ名 | 用途 |
|---|---|
chat:write |
Botがメッセージを投稿するため |
chat:write:customize |
Botによる匿名投稿時にBotの表示名やアイコンをカスタマイズするため |
app_mentions:read |
Geminiによる返信処理のため |
group:history |
Geminiによる返信処理のため |
- ページ上部の「Install to "Workspace名"」からインストールし、Bot Token(
xoxb-...)を取得
※Colab 側でSLACK_BOT_TOKENとして使用します
4. イベント購読設定
- Event Subscriptions を開いて「Enable Events」をON
-
Subscribe to bot events に以下を追加:
app_mention
- ページ下部の「Save Changes」をクリックし保存
5. プライベートチャンネルへの追加
以下のコマンドをプライベートチャンネルで実行して、Botを追加してください:
/invite @ボット名
> 例: `/invite @anon-bot`
匿名投稿モーダルと投稿処理の実装
前章でSlackアプリの設定が完了したので、ここからは以下の機能を実装していきます:
- 匿名投稿用のボタン付きメッセージをチャンネルに設置する
- ボタンを押すとモーダル(投稿フォーム)が表示される
- モーダル送信でBotが匿名名義で投稿し、Geminiによる生成した返答を送信する
- 通常投稿でBotにメンションされた際にもAIがスレッドで自動返信する
1. 環境変数とライブラリの準備
SlackやGeminiのAPIキーなどの変数をシークレットに登録しておきます。
✅ Colabの「シークレット」に登録しておくもの
| 変数名 | 説明 |
|---|---|
GOOGLE_API_KEY |
Gemini APIのキー(Google Cloudから発行) |
SLACK_BOT_TOKEN |
SlackのBot Token(xoxb-...) |
SLACK_APP_TOKEN |
SlackのApp Token(xapp-...) |
CHANNEL_ID |
匿名投稿を送るチャンネルのID |
✅ ライブラリのインストール
!pip install slack_bolt
2. Geminiモデルの初期化
匿名投稿やメンションへの応答に使うAIとして、Google の Gemini モデルを初期化します。
import google.generativeai as genai
from google.colab import userdata
genai.configure(api_key=userdata.get("GOOGLE_API_KEY"))
model = genai.GenerativeModel("gemini-2.0-flash")
3. 匿名投稿ボタンをSlackに設置
Slackチャンネルに、匿名投稿用のボタンを設置します。
このボタンを押すことで、モーダル(入力フォーム)が起動します。
from slack_sdk import WebClient
SLACK_BOT_TOKEN = userdata.get("SLACK_BOT_TOKEN")
CHANNEL_ID = userdata.get("CHANNEL_ID")
client = WebClient(token=SLACK_BOT_TOKEN)
# 匿名投稿ボタン付きブロック
ANON_POST_BLOCK = [
{
"type": "section",
"text": {"type": "mrkdwn", "text": "*匿名で新規投稿できます*"},
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {"type": "plain_text", "text": "匿名投稿する"},
"action_id": "open_anon_modal",
"value": "root_post"
}
]
}
]
# 初回のみ実行(すでに投稿済みの場合はコメントアウト)
response = client.chat_postMessage(
channel=CHANNEL_ID,
text="匿名投稿はこちらから",
blocks=ANON_POST_BLOCK
)
4. Slack Botの初期化(Socket Mode)
Slack Bot のイベント処理を行うために、slack_bolt を用いてアプリを初期化します。
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
app = App(token=SLACK_BOT_TOKEN)
5. BotにメンションされたらAIで返信
Botがメンションされた際、Gemini を使って返信する機能を実装します。
スレッド内に返信されるように thread_ts を指定します。
@app.event("app_mention")
def echo_message(event, say):
thread_ts = event.get("thread_ts") or event.get("ts")
response = model.generate_content(event["text"])
say(thread_ts=thread_ts, text=response.text)
6. ボタン押下でモーダル(投稿フォーム)を表示
ボタンを押すと、Slackにモーダル(入力フォーム)を表示する処理です。
@app.action("open_anon_modal")
def open_modal(ack, body, client):
ack()
client.views_open(
trigger_id=body["trigger_id"],
view={
"type": "modal",
"callback_id": "submit_anon_post",
"title": {"type": "plain_text", "text": "匿名投稿"},
"submit": {"type": "plain_text", "text": "投稿する"},
"close": {"type": "plain_text", "text": "キャンセル"},
"blocks": [
{
"type": "input",
"block_id": "post_block",
"element": {
"type": "plain_text_input",
"action_id": "anon_text",
"multiline": True
},
"label": {"type": "plain_text", "text": "投稿内容"}
}
]
}
)
7. モーダル送信 → Botが匿名で投稿+AIで返信
モーダルから送信された投稿内容を、Botが代わりに"匿名ユーザー"という名前で投稿し、Geminiで自動返信します。
@app.view("submit_anon_post")
def handle_submit(ack, body, client):
ack()
post_text = body["view"]["state"]["values"]["post_block"]["anon_text"]["value"]
# 匿名としてBotが投稿
anon_post = client.chat_postMessage(
channel=CHANNEL_ID,
text=post_text,
username="匿名ユーザー",
icon_emoji=":bust_in_silhouette:"
)
# 注意:
# Botによる投稿にはBot自身が反応しない仕様のため、
# メンションなどを含んでいてもeventハンドラ(@app.eventなど)は発火しません。
# よって、ここで投稿直後にGeminiによる自動返信を行っています
response = model.generate_content(post_text)
client.chat_postMessage(
channel=CHANNEL_ID,
thread_ts=anon_post["ts"],
text=response.text,
)
8. Botを起動する
Slackアプリをソケットモードで起動します。Colabの最後に記述してください。
if __name__ == "__main__":
SocketModeHandler(app, userdata.get("SLACK_APP_TOKEN")).start()
9. 動作確認
「匿名投稿する」ボタンをクリック

表示されるモーダルに投稿内容を入力し、「投稿する」ボタンをクリック

すると入力した内容が「匿名ユーザー」として投稿される。

スレッドに返信が来ている。

おわりに
Slackのショートカットやワークフローと異なり、 「特定のチャンネルでのみ匿名投稿を受け付けたい」 という要件を満たすために、ボタンブロックを使った実装としました。
イケてない点・注意点
実装してみて感じた、運用上の課題や制約も共有しておきます。
-
投稿が増えると、匿名投稿ボタンがタイムラインに流れて見つけにくくなる
→ 匿名ボタンを含むメッセージは、右上の「...」メニューから「ピン留め」しておくとアクセスしやすくなります -
モーダル内ではマークダウン(太字、リンク、箇条書きなど)の書式が使えない
→ 投稿内容を整えたい場合は、記号(*・-など)を使って簡易的に表現できますが、投稿後の整形はされないため、Bot投稿時に整形処理を挟む必要があります
次回は、 匿名スレッド内で匿名返信 できるようにしていきます。
「Slackでボタンとモーダルを使って匿名投稿機能を作ってみた【スレッド投稿編】」
