Skip to content

feat(telegram): send and receive JPEG/PNG images - #29

Open
hegelstad wants to merge 2 commits into
dcosson:mainfrom
hegelstad:feat/telegram-images
Open

hegelstad wants to merge 2 commits into
dcosson:mainfrom
hegelstad:feat/telegram-images

Conversation

@hegelstad

@hegelstad hegelstad commented Sep 8, 2026

Copy link
Copy Markdown
image

Summary

Add image support to the existing Telegram bridge, without a separate service or harness-specific prompt protocol.

  • Receive Telegram photos and JPEG/PNG documents. Save validated image bytes in a private $H2_DIR/attachments/<bridge-name>/ directory, then deliver the caption and local image path through the existing agent-message route.
  • Add h2 send <bridge> --image ./image.png [caption], including --closes support. Image uploads use an optional bridge.ImageSender capability; text-only bridges are unchanged.
  • Preserve caption prefixes and reply-to-agent routing. Image captions are not executed as slash commands.
  • Use a distinct send-image socket operation so an older bridge rejects the request instead of silently discarding the image.

Safety and scope

  • Configured-chat authorization before downloading, bounded metadata/downloads, JPEG/PNG decoding and dimension checks, private files with generated names, no remote filenames used locally.
  • Image HTTP requests have deadlines, reject redirects, and omit token-bearing URLs/remote response bodies from errors. Error notifications respect cancellation.
  • Upload only explicitly selected regular local files; do not interpret paths or URLs in message text as upload instructions.
  • Inbound images are local file references, not native multimodal prompt injection. Agents need an image-viewing tool and access to the attachment directory.
  • One image per send; photo albums arrive as separate Telegram updates. No GIF/sticker/video support, automatic retention cleanup, or automatic upload retry in this change. Those limitations are documented.
  • No production daemon restart or live bot credentials were used for validation.

Verification

  • make check — pass (gofmt, go vet, staticcheck).
  • make test — pass.
  • make test-external — pass with inherited H2_* session variables removed and temporary h2 roots. An initial run inherited H2_POD=ops, which filtered pod-list fixtures; rerunning in the isolated environment passed.
  • go test -race ./internal/bridge/telegram ./internal/bridgeservice -count=1 — pass.
  • make build — pass.

New tests cover multipart upload, captionless sends and --closes, routing, file validation, chat authorization, size/path/redirect errors, error redaction, and socket capability handling. A synthetic-image integration test goes through Bot API polling → local attachment → agent socket → bridge socket → Bot API upload. The HTTP API and agent are test doubles; the Telegram implementation and bridge service are real.

The broader CLI race build was stopped while instrumenting the large treesitter Bash grammar to avoid exhausting the development host's memory; the CLI is covered by the normal full and external suites, while the transport packages passed race testing.

Usage and retention/privacy details: docs/telegram-images.md.

@hegelstad

Copy link
Copy Markdown
Author

Any interest for image sending and receiving support? I have found it very useful to send screenshots back to the concierge to show how something looks or how I want it to look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant