hermes-agent/gateway
cypres0099 8b52356849 fix(gateway/bluebubbles): fall back to data.chats[0].guid when chatGuid missing
BlueBubbles v1.9+ webhook payloads for new-message events do not always
include a top-level chatGuid field on the message data object. Instead,
the chat GUID is nested under data.chats[0].guid.

The adapter currently checks five top-level fallback locations (record and
payload, snake_case and camelCase, plus payload.guid) but never looks
inside the chats array. When none of those top-level fields contain the
GUID, the adapter falls through to using the sender's phone/email as the
session chat ID.

This causes two observable bugs when a user is a participant in both a DM
and a group chat with the bot:

1. DM and group sessions merge. Every message from that user ends up with
   the same session_chat_id (their own address), so the bot cannot
   distinguish which thread the message came from.

2. Outbound routing becomes ambiguous. _resolve_chat_guid() iterates all
   chats and returns the first one where the address appears as a
   participant; group chats typically sort ahead of DMs by activity, so
   replies and cron messages intended for the DM can land in a group.

This was observed in production: a user's morning brief cron delivered to
a group chat with his spouse instead of his DM thread.

The fix adds a single fallback that extracts chat_guid from
record["chats"][0]["guid"] when the top-level fields are empty. The chats
array is included in every new-message webhook payload in BB v1.9.9
(verified against a live server). It is backwards compatible: if a future
BB version starts including chatGuid at the top level, that still wins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 11:02:48 -07:00
..
builtin_hooks refactor: remove dead code — 1,784 lines across 77 files (#9180) 2026-04-13 16:32:04 -07:00
platforms fix(gateway/bluebubbles): fall back to data.chats[0].guid when chatGuid missing 2026-04-14 11:02:48 -07:00
__init__.py Enhance CLI with multi-platform messaging integration and configuration management 2026-02-02 19:01:51 -08:00
channel_directory.py fix(gateway): derive channel directory platforms from enum instead of hardcoded list (#7450) 2026-04-10 17:27:32 -07:00
config.py feat(gateway): add ignored_threads config for Telegram 2026-04-14 01:40:32 -07:00
delivery.py refactor: remove dead code — 1,784 lines across 77 files (#9180) 2026-04-13 16:32:04 -07:00
display_config.py fix(gateway): fix regression causing display.streaming to override root streaming key 2026-04-14 10:52:23 -07:00
hooks.py feat: built-in boot-md hook — run BOOT.md on gateway startup (#3733) 2026-03-29 10:19:54 -07:00
mirror.py chore: remove ~100 unused imports across 55 files (#3016) 2026-03-25 15:02:03 -07:00
pairing.py fix: multiple platform adaptors concurrency 2026-04-06 16:49:54 -07:00
restart.py fix(gateway): address restart review feedback 2026-04-10 21:18:34 -07:00
run.py feat: gateway proxy mode — forward messages to remote API server 2026-04-14 10:49:48 -07:00
session.py refactor: remove dead code — 1,784 lines across 77 files (#9180) 2026-04-13 16:32:04 -07:00
session_context.py fix(gateway): add HERMES_SESSION_KEY to session_context contextvars 2026-04-11 15:35:04 -07:00
status.py fix(gateway): handle stale lock files in acquire_scoped_lock 2026-04-13 04:59:25 -07:00
sticker_cache.py chore: remove ~100 unused imports across 55 files (#3016) 2026-03-25 15:02:03 -07:00
stream_consumer.py fix: prevent streaming cursor from appearing as standalone messages (#9538) 2026-04-14 01:52:42 -07:00