0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Slackでボタンとモーダルを使って匿名投稿機能を作ってみた【スレッド投稿編】

Posted at

はじめに

前回の記事では、Slackの特定プライベートチャンネルに「匿名投稿ボタン」を設置し、モーダルから送信することで、Botが代わりに投稿してくれる 匿名投稿機能 を実装しました。

今回はその続編として、匿名スレッドで匿名返信できる機能 を追加します。
実装は前回のコードを修正する形で進めていきます。

機能の流れ

  1. ユーザーが匿名投稿を行う
  2. Geminiによる自動返信後に「匿名で返信する」ボタンを送信する
  3. ボタンを押すとモーダルが表示され、返信内容を入力
  4. Botがそのスレッド内に匿名で代理投稿
  5. 2~の繰り返し

スレッド返信ボタンの追加

まず、前回のhandle_submit関数内で投稿に対する返信処理後に、スレッド内返信用のボタンブロックボタンの送信処理を追加します。

@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:"
    )

    # Geminiで自動返信
    response = model.generate_content(post_text)
    client.chat_postMessage(
        channel=CHANNEL_ID,
        thread_ts=anon_post["ts"],
        text=response.text,
    )
    
    # --- 追加ここから ---
    
    # スレッド内匿名返信ボタン
    THREAD_REPLY_BLOCK = [
        {
            "type": "actions",
            "elements": [
                {
                    "type": "button",
                    "text": {"type": "plain_text", "text": "匿名で返信する"},
                    "action_id": "open_thread_reply_modal",
                    "value": anon_post["ts"],
                }
            ]
        }
    ]

    # スレッド内匿名返信ボタンの送信
    client.chat_postMessage(
        channel=CHANNEL_ID,
        thread_ts=anon_post["ts"],
        blocks=THREAD_REPLY_BLOCK,
        text="匿名で返信できます"
    )
    
    # --- 追加ここまで ---

スレッド返信用モーダルを表示する

次に、スレッド返信ボタンが押されたときにモーダルを開く処理を追加します。

@app.action("open_thread_reply_modal")
def open_reply_modal(ack, body, client):
    ack()
    thread_ts = body["message"].get("thread_ts")
    client.views_open(
        trigger_id=body["trigger_id"],
        view={
            "type": "modal",
            "callback_id": "submit_thread_reply",
            "private_metadata": thread_ts,
            "title": {"type": "plain_text", "text": "匿名スレッド返信"},
            "submit": {"type": "plain_text", "text": "返信する"},
            "close": {"type": "plain_text", "text": "キャンセル"},
            "blocks": [
                {
                    "type": "input",
                    "block_id": "reply_block",
                    "element": {
                        "type": "plain_text_input",
                        "action_id": "reply_text",
                        "multiline": True
                    },
                    "label": {"type": "plain_text", "text": "返信内容"}
                }
            ]
        }
    )

モーダル送信 → Botがスレッド内に返信

モーダルで送信された内容を、Botが指定されたスレッドに匿名で投稿します。

@app.view("submit_thread_reply")
def handle_thread_reply(ack, body, client):
    ack()
    reply_text = body["view"]["state"]["values"]["reply_block"]["reply_text"]["value"]
    thread_ts = body["view"]["private_metadata"]

    # 匿名としてスレッドに投稿
    reply = client.chat_postMessage(
        channel=CHANNEL_ID,
        thread_ts=thread_ts,
        text=reply_text,
        username="匿名ユーザー",
        icon_emoji=":bust_in_silhouette:"
    )

    # Geminiで返信
    response = model.generate_content(reply_text)
    client.chat_postMessage(
        channel=CHANNEL_ID,
        thread_ts=thread_ts,
        text=response.text,
    )

動作確認

新規投稿 → Botが匿名投稿+返信用ボタンを表示
image.png

「匿名で返信する」ボタンをクリックし、表示されたモーダルに内容を入力して送信
image.png

スレッド内に「匿名ユーザー」としてBotが投稿し、Geminiによる生成回答が返ってくる
image.png

おわりに

これで、「匿名投稿」+「スレッド内匿名投稿」が可能になりました。
匿名投稿を実現する一つの方法として参考になれば嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?