BotMan Slack交互式消息多次点击失效及用户识别问题求助
Let's tackle your two problems one by one with concrete, actionable fixes:
1. Enabling Multiple Clicks on Interactive Messages
The core issue here is that you're using a Conversation to handle button interactions. BotMan Conversations have a finite lifecycle—once a user clicks a button and the conversation completes, any subsequent clicks will trigger the fallback logic because the conversation session is closed.
To support repeated button clicks, we need to send a standalone interactive message and handle all clicks via a global interactive listener instead of a Conversation.
Step 1: Update Message Sending Logic (BotSlackController)
Replace the startConversation call with direct message sending to bypass the conversation lifecycle:
public function sendControllerBot(Request $request) { $botman = app('botman'); $target_id = $request['slackUserId']; // Use channel ID if sending to a public channel $question = Question::create("Hello, How are you?") ->fallback('Unable to process this request') ->callbackId('persistent_health_check') // Unique callback ID for our listener ->addButtons([ Button::create('I am fine')->value('fine'), Button::create('Not good')->value('no_good'), Button::create('Do not disturb')->value('wont_disturb') ]); // Send the interactive message directly to the target user/channel $botman->say($question, $target_id, \BotMan\Drivers\Slack\SlackDriver::class); }
Step 2: Add Global Interactive Listener
In your BotMan routes file (typically routes/botman.php), add a listener for the callback ID we defined. This will catch every button click for that message, regardless of how many times users interact with it:
$botman->hearsInteractiveMessage('persistent_health_check', function ($bot, $payload) { // Extract key data from the Slack payload $selected_option = $payload['actions'][0]['value']; $clicker_id = $payload['user']['id']; // Reply to the channel, mentioning the user in public channels $bot->reply("Hey <@{$clicker_id}>! I received your response: *{$selected_option}*"); });
2. Getting the User ID of the Button Clicker
Slack includes the clicker's full information directly in the interactive payload, so you don't need extra calls to fetch it:
$payload['user']['id']: The Slack ID of the user who clicked the button$payload['user']['name']: The user's Slack username
You can even pair this with your existing getSlackUsers() method to get their real name:
// Inside the listener callback $slack_users = app(\App\Http\Controllers\BotSlackController::class)->getSlackUsers(); $clicker_info = collect($slack_users)->firstWhere('id', $clicker_id); $real_name = $clicker_info['name'] ?? $clicker_name; $bot->reply("Hey {$real_name}! Your response was: *{$selected_option}*");
Bonus: Persisting User Selection History
If you need to track each user's past choices, use BotMan's built-in user storage:
$botman->hearsInteractiveMessage('persistent_health_check', function ($bot, $payload) { $clicker_id = $payload['user']['id']; $selected_option = $payload['actions'][0]['value']; // Save the latest selection to user storage $bot->userStorage()->save([ 'last_health_status' => $selected_option, 'updated_at' => now()->toDateTimeString() ]); // Retrieve and display the previous selection $user_data = $bot->userStorage()->find(); $previous_status = $user_data['last_health_status'] ?? 'no previous response'; $bot->reply("Hey <@{$clicker_id}>! Your current status: *{$selected_option}* (previous: *{$previous_status}*)"); });
内容的提问来源于stack exchange,提问作者Lohith

