Problem
Telegram messages can be redelivered after gateway restarts, getUpdates conflicts, or network reconnects. This causes the same message to be processed multiple times, spamming sessions with duplicates.
Evidence: A single "Hello" message (ID 1687) was delivered 10+ times to a session over 25 minutes.
Solution
Add seenMessages map (matching the pattern already used in Slack adapter - see src/slack/monitor.ts:501-512) to track chatId:messageId pairs and skip already-processed messages.
Patch
From 32caa8755ca000c439f79c5c1c083556604261b9 Mon Sep 17 00:00:00 2001
From: youbiak <x.x@gmail.com>
Date: Fri, 9 Jan 2026 18:30:35 +0000
Subject: [PATCH] fix(telegram): add message deduplication to prevent duplicate
processing
Telegram messages can be redelivered after gateway restarts, getUpdates
conflicts, or network reconnects. This causes the same message to be
processed multiple times, spamming sessions with duplicates.
Add seenMessages map (matching the pattern used in Slack adapter) to
track chatId:messageId pairs and skip already-processed messages.
- Track up to 500 recent messages
- Auto-cleanup entries older than 60 seconds
- Log skipped duplicates in verbose mode
---
src/telegram/bot.ts | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/src/telegram/bot.ts b/src/telegram/bot.ts
index 52461ef5..9b151598 100644
--- a/src/telegram/bot.ts
+++ b/src/telegram/bot.ts
@@ -172,6 +172,26 @@ export function createTelegramBot(opts: TelegramBotOptions) {
const mediaGroupBuffer = new Map<string, MediaGroupEntry>();
+ // Message deduplication - prevents reprocessing messages after restarts/reconnects
+ const seenMessages = new Map<string, number>();
+ const isMessageSeen = (chatId: number, messageId: number): boolean => {
+ const key = `${chatId}:${messageId}`;
+ if (seenMessages.has(key)) return true;
+ seenMessages.set(key, Date.now());
+ // Cleanup old entries to prevent memory growth
+ if (seenMessages.size > 500) {
+ const cutoff = Date.now() - 60_000;
+ for (const [entry, seenAt] of seenMessages) {
+ if (seenAt < cutoff || seenMessages.size > 450) {
+ seenMessages.delete(entry);
+ } else {
+ break;
+ }
+ }
+ }
+ return false;
+ };
+
const cfg = opts.config ?? loadConfig();
const account = resolveTelegramAccount({
cfg,
@@ -992,6 +1012,12 @@ export function createTelegramBot(opts: TelegramBotOptions) {
const msg = ctx.message;
if (!msg) return;
+ // Skip duplicate messages (can happen after restarts/reconnects)
+ if (isMessageSeen(msg.chat.id, msg.message_id)) {
+ logVerbose(`Skipping duplicate telegram message ${msg.chat.id}:${msg.message_id}`);
+ return;
+ }
+
const chatId = msg.chat.id;
const isGroup =
msg.chat.type === "group" || msg.chat.type === "supergroup";
--
2.43.0
Testing
Tested locally - gateway restart no longer causes duplicate message processing.
Problem
Telegram messages can be redelivered after gateway restarts, getUpdates conflicts, or network reconnects. This causes the same message to be processed multiple times, spamming sessions with duplicates.
Evidence: A single "Hello" message (ID 1687) was delivered 10+ times to a session over 25 minutes.
Solution
Add
seenMessagesmap (matching the pattern already used in Slack adapter - seesrc/slack/monitor.ts:501-512) to trackchatId:messageIdpairs and skip already-processed messages.Patch
Testing
Tested locally - gateway restart no longer causes duplicate message processing.