feat: add removeAckAfterReply option for Discord, Slack, and Telegram

Add `messages.removeAckAfterReply` config option to automatically remove
acknowledgment reactions after the bot sends a reply, reducing visual
clutter while still providing immediate feedback.

Platforms: Discord, Slack, Telegram

Implementation:
- Added removeAckAfterReply boolean field to MessagesConfig (default: false)
- Track ack reaction state in all three platform handlers
- Remove ack reaction after successful reply delivery
- Graceful error handling with verbose logging

Platform-specific:
- Discord: uses removeReactionDiscord()
- Slack: uses removeSlackReaction()
- Telegram: uses setMessageReaction() with empty array

Closes #627
This commit is contained in:
Levi Figueira
2026-01-10 00:31:12 +00:00
committed by Peter Steinberger
parent a29f5dda2e
commit b5858c0148
5 changed files with 53 additions and 2 deletions

View File

@@ -74,7 +74,11 @@ import {
waitForDiscordGatewayStop,
} from "./monitor.gateway.js";
import { fetchDiscordApplicationId } from "./probe.js";
import { reactMessageDiscord, sendMessageDiscord } from "./send.js";
import {
reactMessageDiscord,
removeReactionDiscord,
sendMessageDiscord,
} from "./send.js";
import { normalizeDiscordToken } from "./token.js";
export type MonitorDiscordOpts = {
@@ -958,6 +962,7 @@ export function createDiscordMessageHandler(params: {
return;
}
const ackReaction = resolveAckReaction(cfg, route.agentId);
const removeAckAfterReply = cfg.messages?.removeAckAfterReply ?? false;
const shouldAckReaction = () => {
if (!ackReaction) return false;
if (ackReactionScope === "all") return true;
@@ -972,6 +977,7 @@ export function createDiscordMessageHandler(params: {
}
return false;
};
let didAddAckReaction = false;
if (shouldAckReaction()) {
reactMessageDiscord(message.channelId, message.id, ackReaction, {
rest: client.rest,
@@ -980,6 +986,7 @@ export function createDiscordMessageHandler(params: {
`discord react failed for channel ${message.channelId}: ${String(err)}`,
);
});
didAddAckReaction = true;
}
const fromLabel = isDirectMessage
@@ -1201,6 +1208,15 @@ export function createDiscordMessageHandler(params: {
`discord: delivered ${finalCount} reply${finalCount === 1 ? "" : "ies"} to ${replyTarget}`,
);
}
if (removeAckAfterReply && didAddAckReaction && ackReaction) {
removeReactionDiscord(message.channelId, message.id, ackReaction, {
rest: client.rest,
}).catch((err) => {
logVerbose(
`discord: failed to remove ack reaction from ${message.channelId}/${message.id}: ${String(err)}`,
);
});
}
if (
isGuildMessage &&
shouldClearHistory &&