Slack Socket模式下Modal提交报错"连接失败,请重试"求助
问题描述
在Slack Socket模式下开发/bugreport命令,触发Bug报告Modal填写完成后点击提交,客户端无任何操作,反而返回“We had some trouble connecting. Try again?”错误。代码本身能正常运行,但提交后的逻辑完全未执行。相关代码如下:
app.command("/bugreport", async ({ command, ack, say}) => { try { await ack(); app.client.dialog.open( { "trigger_id": command.trigger_id, "dialog": { "callback_id": "bug-report", "title": "Make an issue", "submit_label": "Report", "notify_on_cancel": true, "elements": [ { "type": "text", "label": "Your Name", "name": "username" }, { "type": "select", "label": "Issue Severity", "name": "severity", "options": [ { "label": "Minor", "value": "minor" }, { "label": "Moderate", "value": "moderate" }, { "label": "Urgent", "value": "urgent" }, { "label": "Critical", "value": "critical" } ] }, { "label": "Description", "name": "description", "type": "textarea", "hint": "Describe the bug in this section. Be thorough and explain the exact cause of the bug" }, { "label": "Bug timeline", "name": "timeline", "type": "text", "placeholder": "When did this issue first appear" }, { "label": "Expected Behaviour", "name": "excpectedBehaviour", "type": "textarea", "hint": "Detail what you expected the code to do. Just what it was meant to do." }, { "label": "Actual Behaviour", "name": "actualBehaviour", "type": "textarea", "hint": "What actually happened, what was different." }, { "label": "Steps to reproduce", "name": "steps", "type": "textarea", "placeholder": "1. [First Step]...\n 2. [Second Step]... \n 3. [And so on]... \n" }, { "label": "Additional Information", "name": "additionalInformation", "type": "textarea", "hint": "Anything extra to include." } ] } } ) } catch (error) { console.log("err") console.error(error); } }); app.event("dialog_submission", async ({ event, context }) => { // Extract the values from the submission payload const { username, severity, description, timeline, expectedBehaviour, actualBehaviour, steps, additionalInformation } = event.submission; if (event.callback_id === "bug-report") { // Use the Octokit library to create an issue in the repository try { const issue = await octokit.issues.create({ owner: "my-github-username", repo: currentRepository, title: `${severity} issue reported by ${username}`, body: `Description: ${description} Timeline: ${timeline} Expected Behaviour: ${expectedBehaviour} Actual Behaviour: ${actualBehaviour} Steps to reproduce: ${steps} Additional information: ${additionalInformation}` }); console.log(`Created issue ${issue.data.number}`); } catch (error) { console.error(`Failed to create issue: ${error.message}`); } // Use the respond() function to send a response to the user try { await app.client.chat.postMessage({ token: context.botToken, channel: event.channel.id, text: "Thank you for your bug report! We will review it and take appropriate action." }); } catch (error) { console.error(`Failed to send response: ${error.message}`); } }else{ console.log("what") } });
排查原因与解决办法
核心问题
- 旧版Dialog API已淘汰:
dialog.open是Slack旧版API,在Socket模式下兼容性极差,提交时会触发连接错误。当前Slack官方推荐使用Modals API(views.open)。 - 事件监听不匹配:旧版
dialog_submission事件在Socket模式下不会触发,需要替换为新版view_submission事件。 - 字段拼写错误:Modal中
Expected Behaviour对应的字段名写成了excpectedBehaviour(多了一个c),和后续提取的expectedBehaviour不匹配,会导致数据获取失败。 - 缺少Ack响应:处理
view_submission事件时必须调用ack(),否则Slack会判定请求超时,返回连接错误提示。
修正后的完整代码
app.command("/bugreport", async ({ command, ack, client }) => { try { await ack(); // 使用新版Modals API打开弹窗 await client.views.open({ trigger_id: command.trigger_id, view: { "type": "modal", "callback_id": "bug-report", "title": { "type": "plain_text", "text": "Make an issue" }, "submit": { "type": "plain_text", "text": "Report" }, "close": { "type": "plain_text", "text": "Cancel" }, // 存储频道ID,后续提交时使用 "private_metadata": command.channel_id, "blocks": [ { "type": "input", "element": { "type": "plain_text_input", "action_id": "username" }, "label": { "type": "plain_text", "text": "Your Name" } }, { "type": "input", "element": { "type": "static_select", "action_id": "severity", "options": [ { "text": { "type": "plain_text", "text": "Minor" }, "value": "minor" }, { "text": { "type": "plain_text", "text": "Moderate" }, "value": "moderate" }, { "text": { "type": "plain_text", "text": "Urgent" }, "value": "urgent" }, { "text": { "type": "plain_text", "text": "Critical" }, "value": "critical" } ] }, "label": { "type": "plain_text", "text": "Issue Severity" } }, { "type": "input", "element": { "type": "plain_text_input", "action_id": "description", "multiline": true }, "label": { "type": "plain_text", "text": "Description" }, "hint": { "type": "plain_text", "text": "Describe the bug in this section. Be thorough and explain the exact cause of the bug" } }, { "type": "input", "element": { "type": "plain_text_input", "action_id": "timeline" }, "label": { "type": "plain_text", "text": "Bug timeline" }, "placeholder": { "type": "plain_text", "text": "When did this issue first appear" } }, { "type": "input", "element": { "type": "plain_text_input", "action_id": "expectedBehaviour", "multiline": true }, "label": { "type": "plain_text", "text": "Expected Behaviour" }, "hint": { "type": "plain_text", "text": "Detail what you expected the code to do. Just what it was meant to do." } }, { "type": "input", "element": { "type": "plain_text_input", "action_id": "actualBehaviour", "multiline": true }, "label": { "type": "plain_text", "text": "Actual Behaviour" }, "hint": { "type": "plain_text", "text": "What actually happened, what was different." } }, { "type": "input", "element": { "type": "plain_text_input", "action_id": "steps", "multiline": true }, "label": { "type": "plain_text", "text": "Steps to reproduce" }, "placeholder": { "type": "plain_text", "text": "1. [First Step]...\n 2. [Second Step]... \n 3. [And so on]... \n" } }, { "type": "input", "element": { "type": "plain_text_input", "action_id": "additionalInformation", "multiline": true }, "label": { "type": "plain_text", "text": "Additional Information" }, "hint": { "type": "plain_text", "text": "Anything extra to include." } } ] } }); } catch (error) { console.log("err") console.error(error); } }); // 监听新版view_submission事件 app.view("bug-report", async ({ ack, view, context }) => { // 必须先调用ack()响应Slack请求,避免超时错误 await ack(); // 从view中提取提交的数据 const values = view.state.values; const username = values.username.username.value; const severity = values.severity.severity.selected_option.value; const description = values.description.description.value; const timeline = values.timeline.timeline.value; const expectedBehaviour = values.expectedBehaviour.expectedBehaviour.value; const actualBehaviour = values.actualBehaviour.actualBehaviour.value; const steps = values.steps.steps.value; const additionalInformation = values.additionalInformation.additionalInformation.value; // 创建GitHub Issue try { const issue = await octokit.issues.create({ owner: "my-github-username", repo: currentRepository, title: `${severity} issue reported by ${username}`, body: `Description: ${description} Timeline: ${timeline} Expected Behaviour: ${expectedBehaviour} Actual Behaviour: ${actualBehaviour} Steps to reproduce: ${steps} Additional information: ${additionalInformation}` }); console.log(`Created issue ${issue.data.number}`); } catch (error) { console.error(`Failed to create issue: ${error.message}`); } // 发送反馈消息给用户 try { await app.client.chat.postMessage({ token: context.botToken, channel: view.private_metadata, text: "Thank you for your bug report! We will review it and take appropriate action." }); } catch (error) { console.error(`Failed to send response: ${error.message}`); } });
额外说明
- 新版Modals API使用
blocks结构定义弹窗内容,需遵循Slack官方规范编写。 - 通过
private_metadata字段存储用户触发命令的频道ID,确保提交时能准确发送反馈消息。 - 确保Slack App已申请
commands、chat:write、users:read等必要权限,避免API调用失败。
内容的提问来源于stack exchange,提问作者Dougal McSmith
相关产品推荐
相关产品推荐

