Skip to content

feat(webhook): support platform:chat_id format in deliver config - #49591

Open
kas-cor wants to merge 2 commits into
NousResearch:mainfrom
kas-cor:feat/webhook-deliver-platform-chat-id
Open

feat(webhook): support platform:chat_id format in deliver config#49591
kas-cor wants to merge 2 commits into
NousResearch:mainfrom
kas-cor:feat/webhook-deliver-platform-chat-id

Conversation

@kas-cor

@kas-cor kas-cor commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Allow webhook subscriptions to use telegram:-1003774178835 format in the deliver field to target a specific channel or chat, not just the home channel.

Problem

When configuring a webhook subscription with --deliver "telegram:-1003774178835", the webhook adapter treated the entire string as a platform name and failed with Unknown deliver type: telegram:-1003774178835. This forced users to either:

  • Deliver to the home channel only (no per-webhook targeting)
  • Use deliver_extra.chat_id (which also didn't work for agent-mode webhooks)

Changes

gateway/platforms/webhook.py

  1. send() method — Parse platform:chat_id format before platform lookup:

    • Split on : to extract platform name and optional chat_id
    • Pass target_chat_id to _deliver_cross_platform
  2. _deliver_cross_platform() method — Accept optional target_chat_id parameter:

    • Priority: target_chat_id > deliver_extra.chat_id > home channel
    • Backward compatible — all existing callers pass None

Usage

hermes webhook subscribe my-route \
  --deliver "telegram:-1003774178835" \
  --prompt "Alert: {raw}"

Testing

  • Existing webhook subscriptions with deliver: telegram continue to use home channel (no change)
  • New subscriptions with deliver: telegram:-1003774178835 deliver to the specified chat
  • deliver_extra.chat_id still works as fallback

Allow webhook subscriptions to use 'telegram:-1003774178835' format
in the deliver field to target a specific channel or chat.

- Parse platform:chat_id format in send() method
- Pass target_chat_id to _deliver_cross_platform
- Priority: target_chat_id > deliver_extra.chat_id > home channel
@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery platform/webhook Webhook / API server P3 Low — cosmetic, nice to have labels Jun 20, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for addressing a real webhook-delivery gap: current main still treats telegram:<chat_id> as an unknown deliver type in gateway/platforms/webhook.py:287-303.

Problems

  • The new parser only runs in send(). deliver_only routes bypass that method through _direct_deliver() (gateway/platforms/webhook.py:1120-1146) and still pass the raw value to _deliver_cross_platform(), where Platform(platform_name) rejects telegram:<chat_id> (gateway/platforms/webhook.py:1233-1238). This breaks parity with agent-mode webhook delivery.
  • The diff adds no regression tests. Existing direct-delivery coverage only exercises bare telegram with deliver_extra.chat_id (tests/gateway/test_webhook_deliver_only.py:443-454).

Suggested changes

  • Normalize the delivery target in a shared path used by both send() and _direct_deliver().
  • Add agent-mode and deliver_only tests for inline chat IDs, precedence over deliver_extra.chat_id, and bare-platform home-channel fallback.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 14, 2026
…ests

Address sweeper review (teknium1):
- Extract _parse_deliver_target() shared by send() and _direct_deliver()
- _direct_deliver() now parses platform:chat_id before Platform() lookup
- Add tests for deliver_only + agent-mode inline chat IDs
- Add tests for precedence: target_chat_id > deliver_extra > home channel
- Add unit tests for _parse_deliver_target()
@kas-cor

kas-cor commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Fixes applied — addressing sweeper review

Thanks @teknium1 for the review! Pushed a fix (29f7830) that addresses both points:

1. Normalize delivery target in a shared path

Extracted _parse_deliver_target() as a @staticmethod used by both send() and _direct_deliver(). The parser splits platform:chat_id into (platform_name, chat_id) before any Platform() lookup, so deliver_only routes with telegram:-1003774178835 no longer hit Platform("telegram:-1003774178835")ValueError.

@staticmethod
def _parse_deliver_target(deliver_type: str) -> tuple[str, Optional[str]]:
    if ":" not in deliver_type:
        return deliver_type, None
    parts = deliver_type.split(":", 2)
    platform_name = parts[0].lower()
    chat_id = parts[1] if len(parts) > 1 and parts[1] else None
    return platform_name, chat_id

Both code paths now call it:

  • send()_parse_deliver_target()_deliver_cross_platform(target_platform, ..., target_chat_id)
  • _direct_deliver()_parse_deliver_target()_deliver_cross_platform(target_platform, ..., target_chat_id)

2. Regression tests added

TestDirectDeliverInlineChatId (deliver_only mode):

  • telegram:-1003774178835 routes to the inline chat_id
  • ✅ Inline chat_id takes precedence over deliver_extra.chat_id
  • ✅ Bare telegram falls back to deliver_extra.chat_id
  • ✅ Bare telegram with no extra falls back to home channel

TestSendInlineChatId (agent mode):

  • ✅ Same 4 scenarios via send() with _delivery_info populated

TestParseDeliverTarget (unit):

  • ✅ Bare platform, inline chat_id, uppercase normalization, empty chat_id, discord

All 27 tests pass:

============================== 27 passed in 1.76s ==============================

@kas-cor

kas-cor commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Hi @teknium1 — the review feedback was addressed in 29f7830: extracted _parse_deliver_target() into a shared path used by both send() and _direct_deliver(), and added regression tests. Would appreciate another look when you have a moment! 🙏

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

Labels

comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have platform/webhook Webhook / API server sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants