name: kaopu description: "Scan all Slack channels and DMs for unresponded messages — conversations where the bot owes a reply. Use when asked to 'check unreplied messages', 'kaopu', 'kaopu scan', 'what haven't I responded to', '有没有漏回的', '靠谱检查', or any request to find dropped conversations. Produces an actionable digest with Resume/Mark Done buttons."
Kaopu — 事事有回音,件件有着落
Scan Slack channels and DMs to find conversations where the bot hasn't responded. Present an actionable digest so nothing falls through the cracks.
Trigger
User says: kaopu, kaopu scan, check unreplied, 靠谱, 有没有漏回的, or similar.
Scan Scope
Scan all channels the bot is in plus all DMs.
Detection Rules
A conversation needs a response if it matches any of these conditions AND the bot hasn't responded:
What counts as "needs response"
| Context | Condition |
|---|---|
| DM | Every human message |
| Group — @mention | Any message that @mentions the bot |
| Group — active thread | Thread where bot previously participated, and a human sent the latest message |
| Group — solo channel | Channel with only 1 human member — every message |
What counts as "responded" (satisfied — skip)
A conversation is satisfied if ANY of these is true:
- Bot sent the last message in the thread/conversation
- Human's last message is a social closing: contains only thanks/ok/emoji (e.g.
谢谢,好的,thanks,ok,👍,🙏, single emoji) - The last message OR thread root has a ✅ (
:white_check_mark:) reaction - Bot's last reply was
NO_REPLYorHEARTBEAT_OK
Edge cases
- System messages, bot messages from other bots, join/leave notifications → skip
- Messages older than 7 days with no thread activity → skip (stale)
- If the bot was the one who started the thread and no human replied → skip
Execution Procedure
Step 1: Gather channel list
Read ~/.openclaw/workspace/known-channels.json to get all known channels. Also use message(action=read) on recent DMs.
For each channel, note:
requireMention: if true, only scan for @mentions and bot-participated threadsusers: the human members (if only 1, treat as solo channel)
Step 2: Scan each channel
For each channel/DM, use message(action=read, channel=slack, target=<channelId>, limit=50) to fetch recent messages.
For each message, evaluate:
- Is it a candidate per the detection rules above?
- If it has a thread (
thread_ts), read the thread to check last reply - Apply the "responded" checks
Collect all unresponded items.
Step 3: Categorize by age
| Bucket | Age |
|---|---|
| 🔴 Recent | < 24 hours |
| 🟡 This week | 1-7 days |
| ⚪ Stale | > 7 days (mention count only) |
Step 4: Rank by priority
Before presenting, rank all unresponded items by priority:
Priority scoring (higher = more important):
- Recency: < 1h = +5, < 6h = +4, < 24h = +3, 1-3d = +2, 3-7d = +1
- @mention of bot = +3
- Has a question mark or explicit request = +2
- Thread where bot participated before (dropped mid-conversation) = +3
- Solo channel (only 1 human) = +1
- Multiple unanswered messages from same user in same thread = +1 per extra msg
Select Top 5 from the ranked list.
Step 5: Present digest
Format as a Slack message to the current channel with:
📋 *Kaopu Scan — [total] unresponded*
⭐ *Top 5 建议优先回复:*
1. [#channel] — [time ago]
→ "[first 80 chars]..."
_原因: [why this is high priority, e.g. "直接 @mention + 提问"]_
2. ...
3. ...
4. ...
5. ...
📊 *全量统计:*
🔴 < 24h: [n] 条 | 🟡 1-7d: [n] 条 | ⚪ 7d+: [n] 条
After the digest text, send interactive buttons using the message tool's interactive parameter with these options:
Resume Top 5— Resume only the top 5 priority itemsResume Top 5 & Mark Others Done— Resume top 5, mark all remaining with ✅Mark All Done ✅— Add ✅ reaction to all listed messagesResume All ([N])— Resume every unresponded conversation (show count)
Step 6: Handle button callbacks
When user clicks:
- Resume Top 5: For each of the top 5 conversations, read the thread/context, then send a brief follow-up asking if the user needs continuation. Use the conversation's language (Chinese if Chinese context, English otherwise).
- Resume Top 5 & Mark Others Done: Resume top 5 as above, then add ✅ reaction to all other items.
- Mark All Done: Add ✅ reaction to each listed message using
message(action=react, emoji=white_check_mark, messageId=<id>). - Resume All: Same as Resume Top 5 but for all items. Warn if count > 10 ("这会发送 [N] 条跟进消息,确认吗?").
Output Rules
- Split into two messages: First message = Top 5 list with details. Second message = action buttons. This avoids Slack truncating long messages with interactive blocks.
- Use
<URL|text>format for any Slack links (never bare URLs) - Channel references: use
<#CHANNEL_ID>format for clickable channel links - Keep message compact — no more than 20 lines for the digest
- If zero unresponded: reply "✅ 全部已回复,靠谱!" and nothing else
Limitations
- Cannot scan channels the bot hasn't been added to
- Thread depth limited to what
message(action=read)returns - Rate limits: scan channels serially, not in parallel bursts