Skip to content

fix(messaging): route WhatsApp group JIDs to the target, not the home DM - #46622

Closed
kmccammon wants to merge 1 commit into
NousResearch:mainfrom
kmccammon:fix/whatsapp-jid-targeting
Closed

fix(messaging): route WhatsApp group JIDs to the target, not the home DM#46622
kmccammon wants to merge 1 commit into
NousResearch:mainfrom
kmccammon:fix/whatsapp-jid-targeting

Conversation

@kmccammon

Copy link
Copy Markdown
Contributor

Symptom

send_message(target="whatsapp:<group-jid>") silently delivers to the configured home DM instead of the requested group. The tool reports success with a Sent to whatsapp home channel note, so it looks like it worked — the message just lands in the wrong chat. Reproduced on a real gateway: a group message round-trips inbound fine (the gateway auto-replies in-context), but every outbound send addressed to the group JID falls back to the DM.

Root cause

Two independent gaps, both tool-side (the Node bridge's /send endpoint already accepts any chatId):

1. _parse_target_ref has no WhatsApp branch (tools/send_message_tool.py).
WhatsApp is in _PHONE_PLATFORMS, but the only pattern that matches there is +-prefixed E.164. A group JID 120363…@g.us, user JID …@s.whatsapp.net, linked-identity …@lid, or broadcast/newsletter JID matches no branch and hits the final return None, None, False. The caller reads that as "not an explicit target" and substitutes the home channel.

Fix: add a whatsapp branch recognizing native JIDs as explicit. The existing +-E.164 path is untouched.

2. WhatsApp groups have no friendly name (gateway/channel_directory.py).
The directory is regenerated from session data on a timer, so a group surfaces only as its raw 18-digit JID, and any hand-edit to channel_directory.json is clobbered on the next rebuild. There's no way to give a group a stable name.

Fix: add a user-maintained alias overlay at ~/.hermes/channel_aliases.json, re-applied on every build (persisted) and every load (immediate, survives between rebuilds). Format:

{ "whatsapp": { "120363408391911677@g.us": "general" } }

Aliases rename matching entries in place and inject a placeholder for an aliased id not yet discovered — so a freshly-created group is addressable by name before its first message.

Tests

  • TestParseTargetRefWhatsAppJID (7 cases): group/user/lid/broadcast/newsletter JIDs are explicit; E.164 still works; JID suffixes are not explicit on other platforms; bare friendly names fall through to directory resolution.
  • TestChannelAliases (7 cases): rename-on-load, resolve-by-name (case-insensitive), inject-undiscovered-group, no-file no-op, corrupt-file ignored, persist-through-rebuild, malformed-map safety.
  • Added an autouse fixture isolating CHANNEL_ALIASES_PATH in the directory test module so a real ~/.hermes/channel_aliases.json can't leak into existing tests.

All 110 tests in the touched areas pass locally (tests/gateway/test_channel_directory.py, tests/tools/test_send_message_target_parse.py, tests/gateway/test_weixin.py). The main test_send_message_tool.py module importorskips python-telegram-bot (not installed in this env); the new parser assertions were verified directly against the patched function.

Cache / invariant safety

No change to the system prompt, message alternation, or per-conversation caching. Pure target-resolution + directory-overlay logic. Alias config lives in a JSON file under ~/.hermes/, not in .env and not a new HERMES_* env var.

send_message(target="whatsapp:<group-jid>") silently delivered to the
configured home DM instead of the requested group. Two gaps:

1. _parse_target_ref had no WhatsApp branch. Group JIDs (<id>@g.us),
   user JIDs (<id>@s.whatsapp.net), linked-identity JIDs (<id>@lid), and
   broadcast/newsletter JIDs matched no pattern and fell through to
   `return None, None, False`, so the caller treated them as
   unresolvable and used the home channel. The bridge's /send endpoint
   accepts any chatId, so only the tool-side target parsing was at fault.
   Add a whatsapp branch that recognizes native JIDs as explicit targets.
   The pre-existing '+'-prefixed E.164 path is preserved.

2. WhatsApp groups have no human-friendly name — the channel directory
   is regenerated from session data on a timer, so a group shows up as
   its raw 18-digit JID and any hand-edit to channel_directory.json is
   clobbered on the next rebuild. Add a user-maintained alias overlay
   (~/.hermes/channel_aliases.json) re-applied on every build AND every
   load, giving durable friendly names and letting a freshly-created
   group be pre-named before its first message.

Tests: TestParseTargetRefWhatsAppJID (7 cases) for the parser;
TestChannelAliases (7 cases) for the overlay, plus an autouse fixture
isolating CHANNEL_ALIASES_PATH so a real alias file can't leak into the
existing directory tests.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery comp/tools Tool registry, model_tools, toolsets platform/whatsapp WhatsApp Business adapter labels Jun 15, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #41407 (bug), #20718 / #41415 / #18646 (open cluster) all fix the same _parse_target_ref WhatsApp-JID gap that routes group sends to the home channel. This PR adds that same core fix PLUS a user-maintained alias overlay (~/.hermes/channel_aliases.json in channel_directory.py) that the cluster lacks — so it's a superset/competing approach, not a strict duplicate. Maintainer should pick one core fix.

@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #46635: #46635

Your commit was cherry-picked onto current main with authorship preserved in git history as commit ea49a79. I added a small follow-up for the no-optional-Telegram parser/routing regression, alias snapshot coverage, malformed alias hardening, and release attribution mapping.

Thanks for the fix — the raw WhatsApp group JID path now routes to the requested target instead of the configured home DM.

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 comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists platform/whatsapp WhatsApp Business adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants