fix(messaging): route WhatsApp group JIDs to the target, not the home DM
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.
This commit is contained in:
parent
c17469cb19
commit
ea49a79633
4 changed files with 219 additions and 3 deletions
|
|
@ -40,6 +40,14 @@ _NUMERIC_TOPIC_RE = _TELEGRAM_TOPIC_TARGET_RE
|
|||
# downstream adapters (signal, etc.) expect.
|
||||
_PHONE_PLATFORMS = frozenset({"photon", "signal", "sms", "whatsapp"})
|
||||
_E164_TARGET_RE = re.compile(r"^\s*\+(\d{7,15})\s*$")
|
||||
# WhatsApp JIDs: group chats (<digits>@g.us), individual users
|
||||
# (<phone>@s.whatsapp.net), linked identities (<id>@lid), and broadcast /
|
||||
# newsletter chats. These are explicit native targets the bridge accepts
|
||||
# verbatim — they must NOT fall through to home-channel resolution.
|
||||
_WHATSAPP_JID_RE = re.compile(
|
||||
r"^\s*[\w-]+@(?:g\.us|s\.whatsapp\.net|lid|broadcast|newsletter)\s*$",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
# Email addresses — a valid email like "user@domain.com" should be treated as
|
||||
# an explicit target for the email platform, not fall through to channel-name
|
||||
# resolution which has no way to resolve a raw address.
|
||||
|
|
@ -509,6 +517,12 @@ def _parse_target_ref(platform_name: str, target_ref: str):
|
|||
match = _EMAIL_TARGET_RE.fullmatch(target_ref)
|
||||
if match:
|
||||
return target_ref.strip(), None, True
|
||||
if platform_name == "whatsapp":
|
||||
# Native WhatsApp JIDs (group @g.us, user @s.whatsapp.net, @lid, etc.)
|
||||
# are explicit targets — pass through verbatim. E.164 '+' numbers fall
|
||||
# through to the _PHONE_PLATFORMS handler below.
|
||||
if _WHATSAPP_JID_RE.fullmatch(target_ref):
|
||||
return target_ref.strip(), None, True
|
||||
if platform_name in _PHONE_PLATFORMS:
|
||||
match = _E164_TARGET_RE.fullmatch(target_ref)
|
||||
if match:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue