#20155: feat(telegram): add tg-network-guard transcript status + reply flow
size: XL
## Summary
- add a new optional extension: `tg-network-guard`
- show immediate Telegram feedback for inbound voice notes with `Transcribing...`
- post a real, copyable `Transcript:` reply message after transcription completes
- update the transcribing status message to `Transcribed.`
- keep retries constrained to retry-safe Telegram endpoints only
- add a focused extension test for inline media-path and metadata media-path cases
## Why this change
Transcription can look silent/stuck when media-path materialization or network timing is slow. This change gives users immediate confirmation that transcription started, and then returns an actual text reply they can copy later.
That directly solves a practical UX pain: users with long voice notes (often 1+ minute) shouldn’t need to replay audio just to recover what they said. The transcript reply is especially useful for users without premium voice tooling who still need searchable/copyable text history.
## Scope and risk
- scope is limited to Telegram voice-note placeholder inputs and configured owner-chat matching
- no generic `sendMessage` retries were added (to avoid duplicate content risk)
- retry wrapper remains restricted to safe replay endpoints (`getUpdates`, `getFile`, `sendChatAction`, `answerCallbackQuery`, and Telegram file downloads)
- extension is optional and config-driven
## Test plan
- `pnpm exec vitest -c vitest.extensions.config.ts extensions/tg-network-guard/src/runtime.test.ts`
- verifies:
- transcribing status send
- transcript reply send with preserved `reply_to_message_id`
- status edit to `Transcribed.`
- metadata media-path fallback behavior
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds a new optional extension `tg-network-guard` that provides two capabilities: (1) retry-safe fetch wrapping for Telegram API endpoints (file downloads, `getUpdates`, `getFile`, `sendChatAction`, `answerCallbackQuery`) with exponential backoff, and (2) a voice-note transcription flow that shows "Transcribing..." status, runs Whisper CLI, posts the transcript as a reply, then edits status to "Transcribed."
The extension is well-scoped: retries are restricted to idempotent Telegram endpoints (no `sendMessage` retry to avoid duplicate content), the global fetch patch uses `Symbol.for` to prevent double-installation, and the transcription flow has deduplication, cooldowns, and chunked output for long transcripts.
- **Owner chat ID matching uses substring check** (`from.includes(ownerChatId)`) which could match unintended Telegram user IDs whose ID is a superstring of the configured owner. Should use boundary-aware matching.
- **Hardcoded personal Telegram ID** `1336356696` appears as the default in both `openclaw.plugin.json` and as a runtime fallback in `runtime.ts`. This exposes a personal identifier and should be removed in favor of requiring explicit configuration.
- Test coverage is focused and verifies the core happy path (inline media-path and metadata media-path scenarios), though edge cases like failed transcription and ack cooldowns are not covered.
<h3>Confidence Score: 3/5</h3>
- Generally safe but has a substring-matching logic bug in owner ID gating and a hardcoded personal ID that should be addressed before merge.
- The extension is well-structured and follows repo conventions. The retry logic is correctly scoped to safe endpoints. However, the substring-based owner ID check could match the wrong user under certain conditions, and the hardcoded Telegram ID is both a privacy leak and a configuration footgun for other deployers. These are addressable fixes but should be resolved.
- `extensions/tg-network-guard/src/runtime.ts` (owner ID matching logic and hardcoded fallback), `extensions/tg-network-guard/openclaw.plugin.json` (hardcoded default ID)
<sub>Last reviewed commit: ed2e22e</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
<!-- /greptile_comment -->
Most Similar PRs
#23067: feat(telegram): add disableAudioPreflight config for groups and topics
by yangnim21029 · 2026-02-22
77.2%
#14419: feat(extensions): add telegram-files Mini App
by audichuang · 2026-02-12
76.9%
#17120: fix: transcribe all Telegram voice messages, not just mention-gated...
by MisterGuy420 · 2026-02-15
76.5%
#23572: feat(voice): enable voice note conversation loop for Telegram and W...
by davidrudduck · 2026-02-22
76.3%
#7902: feat: Implement Telegram video note support with tests and docs
by thewulf7 · 2026-02-03
75.9%
#22260: feat(extensions/deltachat): add Delta.Chat channel extension
by alanz · 2026-02-20
75.9%
#13389: feat(telegram): support native voice notes with automatic OGG/Opus ...
by leavingme · 2026-02-10
75.8%
#21898: fix(telegram): auto-detect captionable messages for editMessageCaption
by ptrkstr · 2026-02-20
74.8%
#8086: feat(security): Add prompt injection guard rail
by bobbythelobster · 2026-02-03
74.8%
#17953: fix(telegram): prevent silent message loss and duplicate messages i...
by zuyan9 · 2026-02-16
74.7%