Skip to content

fix(telegram): prevent duplicate equivalent payload sends per turn#30478

Closed
Sid-Qin wants to merge 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/30316-telegram-duplicate-messages
Closed

fix(telegram): prevent duplicate equivalent payload sends per turn#30478
Sid-Qin wants to merge 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/30316-telegram-duplicate-messages

Conversation

@Sid-Qin
Copy link
Copy Markdown
Contributor

@Sid-Qin Sid-Qin commented Mar 1, 2026

Summary

  • add per-dispatch payload deduplication in Telegram reply delivery so semantically identical text/media payloads are only sent once
  • use a normalized dedupe key (text + media list + reply target) to guard duplicate sends even when audioAsVoice differs for the same attachment
  • keep delivery accounting consistent by marking deduped repeats as already delivered

Test plan

  • pnpm exec vitest run src/telegram/bot-message-dispatch.test.ts
  • added regression case: dedupes equivalent media finals within one dispatch turn

Fixes #30316

Prevent duplicate Telegram sends when dispatcher emits semantically identical payloads in the same turn by keying delivered text/media content and skipping repeats, including voice-vs-audio flag drift for the same attachment.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 687ce1adbf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +407 to +410
return JSON.stringify({
text,
mediaList,
replyToId: payload.replyToId ?? null,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include button metadata in payload dedupe key

buildDeliveredPayloadKey only hashes text, mediaList, and replyToId, so two payloads with different channelData.telegram.buttons are treated as duplicates and the latter send is skipped. In Telegram delivery, those buttons are part of the outbound reply_markup, so this can drop intended inline keyboards when the same text/media is resent with updated actions in the same dispatch turn, leaving users without the expected controls.

Useful? React with 👍 / 👎.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 1, 2026

Greptile Summary

This PR adds per-dispatch deduplication to prevent semantically identical Telegram payloads from being sent multiple times within the same turn. The implementation introduces a buildDeliveredPayloadKey function that creates a normalized key from text, media URLs, and reply target, while intentionally excluding the audioAsVoice flag to catch duplicates regardless of delivery format.

Key changes:

  • Deduplication uses a Set to track delivered payload keys within each dispatch turn
  • The dedupe key is based on trimmed text, media list, and replyToId only
  • When a duplicate is detected, it logs the skip and marks as delivered without re-sending
  • Keys are only added to the Set after successful delivery, allowing retries on failures
  • Test coverage validates the specific scenario of duplicate voice messages with different audioAsVoice values

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is clean and focused, with proper null handling, correct Set-based deduplication scoped to a single dispatch turn, and appropriate test coverage. The logic correctly handles edge cases like delivery failures (keys only added on success) and empty payloads (returns null key). The intentional exclusion of audioAsVoice from the dedupe key is well-documented and solves the stated problem.
  • No files require special attention

Last reviewed commit: 687ce1a

Youhai020616 pushed a commit to Youhai020616/openclaw that referenced this pull request Mar 4, 2026
Add channel-agnostic outbound message deduplication to fix duplicate
message delivery across Telegram, WhatsApp, and all other channels.

Layer 1 (Cross-turn TTL dedup): Process-level 30s TTL cache skips
identical payloads recently sent to the same recipient — covers queue
race conditions, cron announce repeats, and tool execution races.

Layer 2 (Text self-duplication): Normalization step detects and fixes
paragraph-level and full-text repetition before delivery — covers
BlueBubbles streaming concatenation bug.

Key design:
- channelData fingerprint (sorted JSON) included in dedup key
- Resolved replyToId (payload-level ?? dispatch-level fallback)
- JSON.stringify array key format to prevent delimiter collisions
- Only registers after successful delivery (failed sends can retry)

Fixes openclaw#30316, openclaw#25192
Supersedes openclaw#30478
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Telegram duplicate messages - text and audio sent twice

2 participants