-
Notifications
You must be signed in to change notification settings - Fork 18
bridge: add π on receive and β on reply emoji reactions #167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -149,6 +149,37 @@ const threadLookup = new Map(); | |
| let threadCounter = 0; | ||
| const MAX_THREADS = 10_000; | ||
|
|
||
| // Track inbound message timestamps pending a β reaction. | ||
| // Key: "channel:thread_ts" (the thread root), Value: { channel, messageTs, receivedAt } | ||
| // When the agent replies via /send with a matching thread_ts, we react with β | ||
| // on the original inbound message and remove the entry. | ||
| const pendingAckReactions = new Map(); | ||
| const PENDING_ACK_TTL_MS = 10 * 60 * 1000; // 10 minutes | ||
|
|
||
| /** | ||
| * When the agent sends a reply in a thread, resolve the pending ack by | ||
| * adding a β reaction to the original inbound message and removing the entry. | ||
| * Also prunes expired entries. | ||
| */ | ||
| function resolveAckReaction(channel, threadTs) { | ||
| const now = Date.now(); | ||
| // Prune expired entries while we're here | ||
| for (const [key, entry] of pendingAckReactions) { | ||
| if (now - entry.receivedAt > PENDING_ACK_TTL_MS) { | ||
| pendingAckReactions.delete(key); | ||
| } | ||
| } | ||
|
|
||
| const threadKey = `${channel}:${threadTs}`; | ||
| const pending = pendingAckReactions.get(threadKey); | ||
| if (!pending) return; | ||
|
|
||
| pendingAckReactions.delete(threadKey); | ||
| _react(pending.channel, pending.messageTs, "white_check_mark").catch((err) => { | ||
| logWarn(`β check reaction failed: ${err.message}`); | ||
| }); | ||
| } | ||
|
|
||
| let socketPath = null; | ||
|
|
||
| let cryptoState = null; | ||
|
|
@@ -695,6 +726,21 @@ async function handleUserMessage(userMessage, event) { | |
| logWarn(`β οΈ Suspicious patterns from <@${event.user}>: ${suspicious.join(", ")}`); | ||
| } | ||
|
|
||
| // React with π immediately so the user knows we saw their message. | ||
| const ackChannel = event.channel; | ||
| const ackMessageTs = event.ts; | ||
| _react(ackChannel, ackMessageTs, "eyes").catch((err) => { | ||
| logWarn(`π eyes reaction failed: ${err.message}`); | ||
| }); | ||
|
|
||
| // Track this message so we can add β when the agent replies. | ||
| const threadKey = `${ackChannel}:${event.thread_ts || ackMessageTs}`; | ||
| pendingAckReactions.set(threadKey, { | ||
| channel: ackChannel, | ||
| messageTs: ackMessageTs, | ||
| receivedAt: Date.now(), | ||
| }); | ||
|
Comment on lines
+737
to
+742
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if a user sends multiple messages in the same thread before the agent replies, only the last message gets β
(each message overwrites the previous entry since they share the same Prompt To Fix With AIThis is a comment left during a code review.
Path: slack-bridge/broker-bridge.mjs
Line: 737-742
Comment:
if a user sends multiple messages in the same thread before the agent replies, only the last message gets β
(each message overwrites the previous entry since they share the same `channel:thread_ts` key). consider whether this is intentional or if individual messages should be tracked using `channel:messageTs` as the key instead
How can I resolve this? If you propose a fix, please make it concise.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Intentional β the β signals "the agent replied to this thread", not "the agent processed this specific message." Each individual message already gets its own π on arrival, so you can tell which ones were seen. Putting β on every queued message in a burst would look noisy. Responded by pi using anthropic/claude-sonnet-4-20250514. |
||
|
|
||
| refreshSocket(); | ||
| const currentSocket = socketPath; | ||
| if (!currentSocket) { | ||
|
|
@@ -988,6 +1034,11 @@ function startApiServer() { | |
| actionRequestBody: { text: safeText }, | ||
| }); | ||
|
|
||
| // If this is a threaded reply, check for a pending β ack reaction. | ||
| if (thread_ts) { | ||
| resolveAckReaction(channel, thread_ts); | ||
| } | ||
|
|
||
| res.writeHead(200, { "Content-Type": "application/json" }); | ||
| res.end(JSON.stringify({ ok: true, ts: result.ts })); | ||
| return; | ||
|
|
@@ -1020,6 +1071,9 @@ function startApiServer() { | |
| actionRequestBody: { text: safeText }, | ||
| }); | ||
|
|
||
| // Check for a pending β ack reaction on the /reply path too. | ||
| resolveAckReaction(thread.channel, thread.thread_ts); | ||
|
|
||
| res.writeHead(200, { "Content-Type": "application/json" }); | ||
| res.end(JSON.stringify({ ok: true, ts: result.ts })); | ||
| return; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same threading behavior as broker-bridge: multiple messages in one thread before agent reply will only mark the last one with β
Prompt To Fix With AI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same answer as the broker-bridge comment β this is intentional. π marks each individual message, β marks the thread as responded-to. Only the most recent message in a burst gets the checkmark, which avoids visual noise.
Responded by pi using anthropic/claude-sonnet-4-20250514.