openclaw - ✅(Solved) Fix Telegram managed hooks do not expose inbound media refs for DM photo/document messages [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#66827Fetched 2026-04-15 06:24:15
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
0
Author
Timeline (top)
commented ×1cross-referenced ×1

On OpenClaw v2026.4.14, managed Telegram hooks are firing for inbound DM media, but the hook payloads available to repo-level hook/plugin code do not expose usable media refs or attachments early enough to intercept heavy visual turns.

In practice:

  • message:received fires
  • message:preprocessed fires later
  • but our hook code sees no usable Telegram photo/document refs in either stage
  • so a visual preprocessing pipeline cannot claim the turn before the normal agent loop starts

This makes it impossible to implement an out-of-band OCR / visual extraction flow for Telegram media from repo-level managed hooks alone.

Root Cause

This blocks a common pattern:

  • intercept heavy image/PDF turns before the main LLM run
  • do OCR / extraction out of band
  • replay compact text into the agent instead of poisoning the sticky chat session with raw media

We confirmed our downstream queue/extraction/replay code works when manually fed a manifest. The missing piece is getting Telegram media refs from the documented managed-hook surfaces.

Fix Action

Fixed

PR fix notes

PR #66910: fix(hooks): expose inbound media on early receive hooks

Description (problem / solution / changelog)

Summary

  • Problem: Telegram inbound media reached the finalized inbound context, but message:received hooks dropped the media fields before managed hooks could inspect them.
  • Why it matters: repo-level hook code could not claim or preprocess inbound Telegram media early, even though the downloaded media paths already existed.
  • What changed: message:received now carries inbound media fields, and enriched internal message hook contexts now preserve media arrays alongside the first media item.
  • What did NOT change (scope boundary): this does not add raw Telegram-native ids like file_id or media_group_id; it only exposes the finalized inbound media data already available in the runtime.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #66827
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: the hook mapper dropped mediaPath/mediaType entirely for message:received, and it dropped mediaPaths/mediaTypes for enriched internal hook contexts.
  • Missing detection / guardrail: the nearest mapper regression test covered inbound-claim media metadata, but not the early receive/preprocessed hook surfaces.
  • Contributing context (if known): Telegram resolves inbound media into finalized context before the hook bridge runs, so the missing data was a mapper-contract bug rather than a Telegram download-timing bug.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/hooks/message-hook-mappers.test.ts
  • Scenario the test should lock in: canonical inbound media arrays survive into plugin/internal message:received payloads and internal message:preprocessed payloads.
  • Why this is the smallest reliable guardrail: the regression happens in the shared hook mapper contract after inbound context is finalized, so a focused mapper test directly exercises the bug surface without depending on Telegram runtime setup.
  • Existing test that already covers this (if any): extensions/telegram/src/bot.media.downloads-media-file-path-no-file-download.e2e.test.ts proves Telegram inbound media paths are created before the mapper stage.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

Telegram/media-aware managed hooks can now read finalized inbound media paths earlier:

  • internal message:received hooks now include mediaPath, mediaType, mediaPaths, and mediaTypes
  • internal enriched hooks like message:preprocessed now preserve mediaPaths and mediaTypes
  • plugin message_received hooks now include the same media fields in event.metadata

Diagram (if applicable)

Before:
[telegram inbound media] -> [finalized context has MediaPath/MediaPaths] -> [message:received mapper drops media] -> [hook cannot claim media early]

After:
[telegram inbound media] -> [finalized context has MediaPath/MediaPaths] -> [message:received/preprocessed mapper preserves media] -> [hook can inspect media early]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS 15.3.0
  • Runtime/container: local Node/pnpm workspace
  • Model/provider: N/A
  • Integration/channel (if any): Telegram managed hook surface
  • Relevant config (redacted): N/A

Steps

  1. Build a canonical inbound context with multiple media paths/types.
  2. Map it into plugin/internal message:received payloads and internal message:preprocessed payloads.
  3. Verify the resulting hook payloads still expose the finalized media fields.

Expected

  • Early message hook payloads preserve the inbound media metadata already present on the finalized context.

Actual

  • Before this change, message:received dropped media entirely and enriched internal hooks dropped media arrays.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios:
    • pnpm test src/hooks/message-hook-mappers.test.ts src/hooks/message-hooks.test.ts
    • pnpm test extensions/telegram/src/bot.media.downloads-media-file-path-no-file-download.e2e.test.ts -t "keeps Telegram inbound media paths with triple-dash ids"
    • pnpm check
    • pnpm build
  • Edge cases checked:
    • multi-attachment inbound media arrays remain aligned with the first media item
    • existing hook fixtures still pass without requiring new fields
  • What you did not verify:
    • live Telegram manual end-to-end verification against a real bot account

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: hook consumers may start depending on the newly surfaced media fields before raw Telegram-native ids are available.
    • Mitigation: the PR keeps scope explicit and only surfaces finalized runtime media data that already exists today.

AI Assistance

Prepared with coding assistance and manually verified with the checks listed above.

Made with Cursor

Changed files

  • src/hooks/internal-hooks.ts (modified, +12/-0)
  • src/hooks/message-hook-mappers.test.ts (modified, +102/-2)
  • src/hooks/message-hook-mappers.ts (modified, +59/-12)
  • src/plugins/hook-message.types.ts (modified, +4/-0)

Code Example

[visual-ingress] received no-attachments session=agent:main:telegram:default:direct:... channel=telegram checked=context.metadata.message,context.metadata.update.message,context.metadata.update.edited_message,context.message,... errors=none
[visual-ingress] preprocessed-fallback no-attachments session=agent:main:telegram:default:direct:... channel=telegram checked=context.metadata.message,context.metadata.update.message,context.metadata.update.edited_message,context.message,... errors=none
RAW_BUFFERClick to expand / collapse

Summary

On OpenClaw v2026.4.14, managed Telegram hooks are firing for inbound DM media, but the hook payloads available to repo-level hook/plugin code do not expose usable media refs or attachments early enough to intercept heavy visual turns.

In practice:

  • message:received fires
  • message:preprocessed fires later
  • but our hook code sees no usable Telegram photo/document refs in either stage
  • so a visual preprocessing pipeline cannot claim the turn before the normal agent loop starts

This makes it impossible to implement an out-of-band OCR / visual extraction flow for Telegram media from repo-level managed hooks alone.

Expected

For an inbound Telegram DM photo/document message, a managed hook should be able to read enough media metadata in message:received (or, if intended, in message:preprocessed) to identify and persist the media for external processing.

At minimum, one of those surfaces should expose something like:

  • Telegram file_id / document ref / photo ref
  • provider message id
  • media-group / album id when present
  • basic mime / filename / caption metadata

Actual

The managed hooks do fire, but our logging shows no usable attachments / refs in the event shapes we can access from repo code.

Example logs from a real Telegram DM image test:

[visual-ingress] received no-attachments session=agent:main:telegram:default:direct:... channel=telegram checked=context.metadata.message,context.metadata.update.message,context.metadata.update.edited_message,context.message,... errors=none
[visual-ingress] preprocessed-fallback no-attachments session=agent:main:telegram:default:direct:... channel=telegram checked=context.metadata.message,context.metadata.update.message,context.metadata.update.edited_message,context.message,... errors=none

Because no claim can be created, the normal raw-media agent path starts instead.

In the same run we then see the main session process the images directly (image resize spam, active-memory, repeated terminated runs), which is exactly what we were trying to avoid.

Minimal repro

  1. Run OpenClaw v2026.4.14 with Telegram configured.
  2. Add a managed hook for:
    • message:received
    • message:preprocessed
  3. In the hook, log the keys/metadata available for inbound Telegram media and try to discover:
    • context.metadata.message.photo
    • context.metadata.message.document
    • context.metadata.update.message.photo
    • context.metadata.update.message.document
  4. Send a Telegram DM photo to the bot.
  5. Observe that the hook fires, but no usable media refs/attachments are available on the surfaces exposed to the hook.

Why this matters

This blocks a common pattern:

  • intercept heavy image/PDF turns before the main LLM run
  • do OCR / extraction out of band
  • replay compact text into the agent instead of poisoning the sticky chat session with raw media

We confirmed our downstream queue/extraction/replay code works when manually fed a manifest. The missing piece is getting Telegram media refs from the documented managed-hook surfaces.

Environment

  • OpenClaw: v2026.4.14
  • Channel: Telegram DM
  • Reproducible with real inbound image messages

Question

Is this:

  • a bug in the Telegram managed-hook payload surface,
  • an intentional limitation,
  • or are we expected to read Telegram media refs from a different documented field/path in message:received / message:preprocessed?

extent analysis

TL;DR

The issue can be resolved by investigating the Telegram managed-hook payload surface for missing media refs and potentially using an alternative approach to access the required metadata.

Guidance

  • Review the OpenClaw documentation for message:received and message:preprocessed hooks to ensure that the expected media metadata is supposed to be exposed.
  • Inspect the context.metadata object in the hook code to see if the media refs are available under a different key or path.
  • Consider logging the entire context object to identify any potential issues with the payload surface.
  • If the media refs are not available, explore alternative approaches, such as using a different hook or modifying the downstream queue/extraction/replay code to handle the missing metadata.

Example

No code snippet is provided as the issue is related to the payload surface and not a specific code implementation.

Notes

The issue seems to be specific to the OpenClaw v2026.4.14 version and the Telegram channel. It is unclear if this is a bug or an intentional limitation, and further investigation is required to determine the root cause.

Recommendation

Apply a workaround by exploring alternative approaches to access the required metadata, as it is unclear if an upgrade to a fixed version is available. This approach allows for a potential solution to be implemented while the root cause is being investigated.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Telegram managed hooks do not expose inbound media refs for DM photo/document messages [1 pull requests, 1 comments, 2 participants]