fix: remove ack reactions after reply (#633) (thanks @levifig)

This commit is contained in:
Peter Steinberger
2026-01-10 02:11:51 +01:00
parent b5858c0148
commit 38e2362be6
8 changed files with 108 additions and 74 deletions

View File

@@ -977,17 +977,19 @@ export function createDiscordMessageHandler(params: {
}
return false;
};
let didAddAckReaction = false;
if (shouldAckReaction()) {
reactMessageDiscord(message.channelId, message.id, ackReaction, {
rest: client.rest,
}).catch((err) => {
logVerbose(
`discord react failed for channel ${message.channelId}: ${String(err)}`,
);
});
didAddAckReaction = true;
}
const ackReactionPromise = shouldAckReaction()
? reactMessageDiscord(message.channelId, message.id, ackReaction, {
rest: client.rest,
}).then(
() => true,
(err) => {
logVerbose(
`discord react failed for channel ${message.channelId}: ${String(err)}`,
);
return false;
},
)
: null;
const fromLabel = isDirectMessage
? buildDirectLabel(author)
@@ -1208,13 +1210,22 @@ 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 (removeAckAfterReply && ackReactionPromise && ackReaction) {
const ackReactionValue = ackReaction;
void ackReactionPromise.then((didAck) => {
if (!didAck) return;
removeReactionDiscord(
message.channelId,
message.id,
ackReactionValue,
{
rest: client.rest,
},
).catch((err) => {
logVerbose(
`discord: failed to remove ack reaction from ${message.channelId}/${message.id}: ${String(err)}`,
);
});
});
}
if (

View File

@@ -913,6 +913,7 @@ export async function monitorSlackProvider(opts: MonitorSlackOpts = {}) {
const rawBody = (message.text ?? "").trim() || media?.placeholder || "";
if (!rawBody) return;
const ackReaction = resolveAckReaction(cfg, route.agentId);
const ackReactionValue = ackReaction ?? "";
const removeAckAfterReply = cfg.messages?.removeAckAfterReply ?? false;
const shouldAckReaction = () => {
if (!ackReaction) return false;
@@ -928,18 +929,27 @@ export async function monitorSlackProvider(opts: MonitorSlackOpts = {}) {
}
return false;
};
let didAddAckReaction = false;
if (shouldAckReaction() && message.ts) {
reactSlackMessage(message.channel, message.ts, ackReaction, {
token: botToken,
client: app.client,
}).catch((err) => {
logVerbose(
`slack react failed for channel ${message.channel}: ${String(err)}`,
);
});
didAddAckReaction = true;
}
const ackReactionMessageTs = message.ts;
const ackReactionPromise =
shouldAckReaction() && ackReactionMessageTs && ackReactionValue
? reactSlackMessage(
message.channel,
ackReactionMessageTs,
ackReactionValue,
{
token: botToken,
client: app.client,
},
).then(
() => true,
(err) => {
logVerbose(
`slack react failed for channel ${message.channel}: ${String(err)}`,
);
return false;
},
)
: null;
const roomLabel = channelName ? `#${channelName}` : `#${message.channel}`;
@@ -1160,14 +1170,18 @@ export async function monitorSlackProvider(opts: MonitorSlackOpts = {}) {
`slack: delivered ${finalCount} reply${finalCount === 1 ? "" : "ies"} to ${replyTarget}`,
);
}
if (removeAckAfterReply && didAddAckReaction && ackReaction && message.ts) {
removeSlackReaction(message.channel, message.ts, ackReaction, {
token: botToken,
client: app.client,
}).catch((err) => {
logVerbose(
`slack: failed to remove ack reaction from ${message.channel}/${message.ts}: ${String(err)}`,
);
if (removeAckAfterReply && ackReactionPromise && ackReactionMessageTs) {
const messageTs = ackReactionMessageTs;
void ackReactionPromise.then((didAck) => {
if (!didAck) return;
removeSlackReaction(message.channel, messageTs, ackReactionValue, {
token: botToken,
client: app.client,
}).catch((err) => {
logVerbose(
`slack: failed to remove ack reaction from ${message.channel}/${message.ts}: ${String(err)}`,
);
});
});
}
};

View File

@@ -591,28 +591,31 @@ export function createTelegramBot(opts: TelegramBotOptions) {
}
return false;
};
let didAddAckReaction = false;
if (shouldAckReaction() && msg.message_id) {
const api = bot.api as unknown as {
setMessageReaction?: (
chatId: number | string,
messageId: number,
reactions: Array<{ type: "emoji"; emoji: string }>,
) => Promise<void>;
};
if (typeof api.setMessageReaction === "function") {
api
.setMessageReaction(chatId, msg.message_id, [
const api = bot.api as unknown as {
setMessageReaction?: (
chatId: number | string,
messageId: number,
reactions: Array<{ type: "emoji"; emoji: string }>,
) => Promise<void>;
};
const reactionApi =
typeof api.setMessageReaction === "function"
? api.setMessageReaction.bind(api)
: null;
const ackReactionPromise =
shouldAckReaction() && msg.message_id && reactionApi
? reactionApi(chatId, msg.message_id, [
{ type: "emoji", emoji: ackReaction },
])
.catch((err) => {
logVerbose(
`telegram react failed for chat ${chatId}: ${String(err)}`,
);
});
didAddAckReaction = true;
}
}
]).then(
() => true,
(err) => {
logVerbose(
`telegram react failed for chat ${chatId}: ${String(err)}`,
);
return false;
},
)
: null;
let placeholder = "";
if (msg.photo) placeholder = "<media:image>";
@@ -857,21 +860,20 @@ export function createTelegramBot(opts: TelegramBotOptions) {
markDispatchIdle();
draftStream?.stop();
if (!queuedFinal) return;
if (removeAckAfterReply && didAddAckReaction && msg.message_id) {
const api = bot.api as unknown as {
setMessageReaction?: (
chatId: number | string,
messageId: number,
reactions: Array<{ type: "emoji"; emoji: string }>,
) => Promise<void>;
};
if (typeof api.setMessageReaction === "function") {
api.setMessageReaction(chatId, msg.message_id, []).catch((err) => {
if (
removeAckAfterReply &&
ackReactionPromise &&
msg.message_id &&
reactionApi
) {
void ackReactionPromise.then((didAck) => {
if (!didAck) return;
reactionApi(chatId, msg.message_id, []).catch((err) => {
logVerbose(
`telegram: failed to remove ack reaction from ${chatId}/${msg.message_id}: ${String(err)}`,
);
});
}
});
}
};