Telegram Bot Duplicate Replies: Deduplicate Updates Before Calling the Model
Use Telegram update IDs and delivery rules to separate event acceptance, model generation, and sending, including restart and uncertain-send cases.

One question produces two bot replies. The model may not be the cause: an update can be delivered again, multiple workers can accept it, or a successful send can lose its acknowledgement. Record event acceptance, generation, and sending separately so the fix targets the stage that duplicated work.
This guide was checked on November 10, 2026. The Telegram Bot API page listed Bot API 10.4, November 9, as its latest change. The examples are public teaching records; we did not connect a real bot or reproduce a framework defect.
Use the platform's delivery contract
The Update definition describes update_id as useful for ignoring repeated updates and restoring order. Confirmation differs by delivery method:
- With
getUpdates, an update is confirmed when a later request uses anoffsetgreater than itsupdate_id. Recalculate the offset after each response. - With webhooks, Telegram posts updates to the configured endpoint. A response outside
2XYtriggers retries. Do not invent a fixed retry schedule that the documentation does not promise.
getUpdates does not work while an outgoing webhook is configured. Inspect the active method before changing it, and do not drop pending updates merely to clear a duplication symptom.
The documentation also says that after at least a week without new updates, the next identifier is chosen randomly. A permanent highest-seen threshold is therefore not a complete future-event filter. Deduplicating identity and restoring sequence are separate operations.
Accept durably before calling the model
Validate the source and structure using the platform's supported mechanism. Then accept the event under a namespace such as bot identity + update_id, persist a job, and let a worker handle generation.
Acknowledging a webhook before storing anything durable can lose the task on a crash. Waiting for generation and delivery before responding ties slow work to the delivery request. A useful boundary is to acknowledge after reliable acceptance, then recover later processing failures within your own task system.
The deduplication record and job creation need a shared reliable transaction boundary. Concurrent delivery of one event should create one job; a duplicate already accepted durably can be acknowledged without another model call. A database unique constraint is one implementation option.
This record is a teaching design, not a native Telegram Update:
{
"event_key": "demo-bot:1001",
"state": "accepted",
"generation_ref": null,
"send_state": "not_started",
"sent_message_ref": null
}
An in-memory seen_ids set does not survive restarts or coordinate instances. Interrupted jobs also need a reclaim mechanism. Deleting the acceptance record to recover processing can turn a redelivery into a second full execution.
Input deduplication does not settle an uncertain send
One generation can still produce two send attempts. If Telegram accepts a send but the local caller loses the response, event deduplication cannot tell that caller whether a message exists.
Persist the returned message reference on confirmed success. For an uncertain result, use a distinct pending_confirmation state and inspect available records. Pause for human resolution if there is no reliable way to establish the outcome. Do not assume sendMessage honors an arbitrary business-idempotency header, or regenerate the answer to conceal uncertainty about delivery.
The side-effect recovery guide covers the same business boundary. Other platforms have different event identities and acknowledgement rules; Telegram's update_id cannot simply be copied into a Feishu or QQ integration.
Verify restart and concurrency behavior
In an isolated bot or local event substitute, check repeated delivery, concurrent acceptance, restart after job persistence, and a lost send acknowledgement. Inspect job count, model-call count, send attempts, and visible messages separately.
We did not run these platform checks, and the research did not establish a current widespread Chinese-community incident. This is a durable-delivery method grounded in the official contract. Use the Hermes Telegram setup guide and connection basics for prerequisites.
Nbility logs can reveal multiple model requests but do not replace bot acceptance or delivery records. Prepare a redacted support record without bot tokens, chat content, or real participant details before investigating the duplicate stage.


