diff --git a/extensions/telegram/src/bot-updates.ts b/extensions/telegram/src/bot-updates.ts index 4b08c747f8f..15cb32f5f94 100644 --- a/extensions/telegram/src/bot-updates.ts +++ b/extensions/telegram/src/bot-updates.ts @@ -3,8 +3,11 @@ import { createDedupeCache } from "openclaw/plugin-sdk/infra-runtime"; import type { TelegramContext } from "./bot/types.js"; const MEDIA_GROUP_TIMEOUT_MS = 500; -const RECENT_TELEGRAM_UPDATE_TTL_MS = 5 * 60_000; -const RECENT_TELEGRAM_UPDATE_MAX = 2000; +// Dedup cache TTL must survive the longest possible polling restart cycle +// (backoff up to 30s × multiple attempts + 90s stall threshold + 15s grace). +// 30 minutes keeps entries alive well past any realistic restart window (#46674). +const RECENT_TELEGRAM_UPDATE_TTL_MS = 30 * 60_000; +const RECENT_TELEGRAM_UPDATE_MAX = 5000; export type MediaGroupEntry = { messages: Array<{ diff --git a/extensions/telegram/src/polling-session.ts b/extensions/telegram/src/polling-session.ts index 59cbec7d589..b272849fca9 100644 --- a/extensions/telegram/src/polling-session.ts +++ b/extensions/telegram/src/polling-session.ts @@ -177,8 +177,12 @@ export class TelegramPollingSession { } try { await bot.api.getUpdates({ offset: lastUpdateId + 1, limit: 1, timeout: 0 }); - } catch { + } catch (err) { // Non-fatal: runner middleware still skips duplicates via shouldSkipUpdate. + // Log a warning so operators can diagnose duplicate-message issues (#46674). + this.opts.log( + `[telegram] failed to confirm persisted offset ${lastUpdateId}: ${formatErrorMessage(err)}; relying on dedup cache.`, + ); } }