Botkit-Slack交互式消息:如何获取所有操作的选中值?
如何获取Slack交互式选择框的所有选中值
首先得明确一点:Slack的交互式组件回调默认只会返回当前被修改的那个选择框的选中值,不会自动带上其他选择框的历史选择。要拿到所有选择框的完整值,你得自己维护用户的选择状态,下面给你两种实用的实现思路:
思路一:用存储(内存/数据库)维护用户会话状态
这是最通用的方案,适合大多数场景:
- 初始化状态存储:可以用内存对象(开发测试用)或者数据库(生产环境推荐,比如Redis、MongoDB)来保存每个用户的选择记录,键可以用用户ID(
payload.user.id)来唯一标识。 - 回调时更新状态:每次收到回调请求时,先取出该用户之前的选择状态,再用当前操作的选择框名称和值更新状态对象,这样就能得到包含所有选择的完整值了。
给你结合你的代码写个示例(用内存存储做演示):
// 开发环境用内存存储,生产环境替换成数据库 const userSelectionStore = {}; function interactive_messages_callback(req, res) { const payload = JSON.parse(req.body.payload); const userId = payload.user.id; const currentAction = payload.actions[0]; // 初始化用户的选择状态(如果是第一次操作) if (!userSelectionStore[userId]) { userSelectionStore[userId] = {}; } // 更新当前选择框的值 userSelectionStore[userId][currentAction.name] = currentAction.selected_options[0].value; // 现在userSelectionStore[userId]就是你要的完整值! // 比如:{ os_type_selection: 'osx', day_selection: '2' } console.log('所有选中值:', userSelectionStore[userId]); // 可选:给用户返回更新后的状态提示 res.send({ text: `已选择:系统=${userSelectionStore[userId].os_type_selection || '未选'},日期=${userSelectionStore[userId].day_selection || '未选'}`, attachments: payload.attachments // 保留原选择框让用户继续修改 }); }
思路二:把状态附加到消息的Callback ID里
如果不想用外部存储,也可以把当前选择状态编码后放到消息的callback_id里,每次更新消息时同步更新这个ID:
- 初始发送消息时:把初始状态(空对象)编码成JSON,拼接到
callback_id里,比如question_session|{"os_type_selection":"","day_selection":""}。 - 回调时解析状态:收到回调后,拆分
callback_id拿到之前的状态JSON,解析成对象后更新当前选择值,再把新状态重新编码拼接到新的callback_id里,更新Slack消息。
示例代码片段:
// 初始发送消息的修改 bot.reply(message, { attachments: [ { "title": "Question 1", "callback_id": "question_session|{\"os_type_selection\":\"\",\"day_selection\":\"\"}", "attachment_type": "default", "actions": [ { "name": "os_type_selection", "text": "Pick a game...", "type": "select", "options": [ { "text": "Mac OS X", "value": "osx" }, { "text": "Windows", "value": "windows" } ] } ] }, // 第二个附件可以共用同一个callback_id,或者保持一致的状态拼接方式 { "title": "Question 2", "callback_id": "question_session|{\"os_type_selection\":\"\",\"day_selection\":\"\"}", "attachment_type": "default", "actions": [ { "name": "day_selection", "text": "Pick a day...", "type": "select", "options": [/* 你的选项 */] } ] } ] }); // 回调函数里的处理 function interactive_messages_callback(req, res) { const payload = JSON.parse(req.body.payload); const [sessionId, stateJson] = payload.callback_id.split('|'); const currentValues = JSON.parse(stateJson); const currentAction = payload.actions[0]; // 更新当前选择值 currentValues[currentAction.name] = currentAction.selected_options[0].value; // 生成新的callback_id const newCallbackId = `${sessionId}|${JSON.stringify(currentValues)}`; // 更新消息,把新的callback_id带上 res.send({ text: `当前选择:系统=${currentValues.os_type_selection},日期=${currentValues.day_selection}`, attachments: payload.attachments.map(att => ({ ...att, callback_id: newCallbackId })) }); }
两种方案各有优劣:第一种适合多步骤、跨消息的交互,状态持久化更可靠;第二种不需要外部存储,适合简单的单消息多选择框场景。你可以根据自己的业务需求选~
内容的提问来源于stack exchange,提问作者dallion
相关产品推荐
相关产品推荐

