slack_wait_for_reply
Ask a question in Slack and wait for a human response by polling a thread until reply appears or timeout occurs.
Instructions
Poll a thread waiting for a user reply. Posts an initial message if provided, then polls until a non-bot reply appears or timeout is reached. Use this when you need to ask the user a question and wait for their response via Slack.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | No | The Slack channel ID. Defaults to configured inbox channel. | |
| thread_ts | No | The timestamp of an existing thread to monitor. If not provided, message must be provided to start a new thread. | |
| message | No | Message to post (starts a new thread if thread_ts not provided, or posts to existing thread). | |
| poll_interval_seconds | No | Seconds between poll attempts. Default: 30 | |
| timeout_minutes | No | Maximum minutes to wait for a reply. Default: 15 |
Implementation Reference
- src/index.js:482-605 (handler)The handler implementation for the `slack_wait_for_reply` tool in src/index.js. It polls a Slack thread for new, non-bot messages until a reply is found or a timeout is reached.
case "slack_wait_for_reply": { const channelId = args.channel_id || DEFAULT_CHANNEL; let threadTs = args.thread_ts; const message = args.message; const pollInterval = (args.poll_interval_seconds || 30) * 1000; const timeoutMs = (args.timeout_minutes || 15) * 60 * 1000; if (!channelId) { return { content: [ { type: "text", text: "Error: No channel ID provided and no default channel configured.", }, ], }; } if (!threadTs && !message) { return { content: [ { type: "text", text: "Error: Either thread_ts or message must be provided.", }, ], }; } const botId = await getBotUserId(); // Post initial message if provided if (message) { const postResult = await slack.chat.postMessage({ channel: channelId, text: message, thread_ts: threadTs, // Will be undefined for new thread, which is fine }); // If this was a new thread, use the message ts as thread_ts if (!threadTs) { threadTs = postResult.ts; } } const startTime = Date.now(); let lastCheckedTs = threadTs; // Poll for replies while (Date.now() - startTime < timeoutMs) { await sleep(pollInterval); const result = await slack.conversations.replies({ channel: channelId, ts: threadTs, }); const messages = result.messages || []; // Find non-bot replies after our last check const newUserReplies = messages.filter( (msg) => msg.user !== botId && msg.ts !== threadTs && // Exclude parent message parseFloat(msg.ts) > parseFloat(lastCheckedTs) ); if (newUserReplies.length > 0) { // Found a reply! const latestReply = newUserReplies[newUserReplies.length - 1]; return { content: [ { type: "text", text: JSON.stringify( { success: true, reply_received: true, channel: channelId, thread_ts: threadTs, reply: { ts: latestReply.ts, text: latestReply.text, user: latestReply.user, date: new Date(parseFloat(latestReply.ts) * 1000).toISOString(), }, wait_duration_seconds: Math.round((Date.now() - startTime) / 1000), }, null, 2 ), }, ], }; } // Update last checked timestamp if (messages.length > 0) { lastCheckedTs = messages[messages.length - 1].ts; } } // Timeout reached return { content: [ { type: "text", text: JSON.stringify( { success: false, reply_received: false, reason: "timeout", channel: channelId, thread_ts: threadTs, timeout_minutes: args.timeout_minutes || 15, hint: "No reply received within the timeout period. You can call slack_read_thread later to check for replies.", }, null, 2 ), }, ], }; }