← Back to PRs

#23705: BlueBubbles: enrich webhook group participants from chat metadata

by marc726 open 2026-02-22 16:20 View on GitHub →
channel: bluebubbles size: M
## Summary Describe the problem and fix in 2–5 bullets: - Problem: BlueBubbles webhook payloads for some group messages arrive with missing/partial participants, and monitor.ts previously normalized that payload directly without enrichment. - Why it matters: OpenClaw could miss group members, producing incorrect GroupMembers context and weaker first-contact behavior. - What changed: Added participant enrichment in monitor.ts to fetch chat metadata before enqueueing, using a new `resolveChatRecordForTarget` helper in send.ts, and then normalizing participant records via exported `normalizeParticipantList`. - What did NOT change (scope boundary): No allowlist policy changes, no outbound send behavior changes, no auth model changes, and no non-BlueBubbles channel behavior changes. #### Root causes: Webhook path queued raw message without participant enrichment https://github.com/openclaw/openclaw/blob/9363c320d8ffe29290906752fab92621da02c3f7/extensions/bluebubbles/src/monitor.ts#L451-L457 Normalizer falls back to empty participants when webhook/chat payload lacks participant arrays https://github.com/openclaw/openclaw/blob/9363c320d8ffe29290906752fab92621da02c3f7/extensions/bluebubbles/src/monitor-normalize.ts#L274-L280 ## Change Type (select all) - [x] Bug fix - [x] Refactor ## Scope (select all touched areas) - [x] Integrations ## User-visible / Behavior Changes Incoming BlueBubbles group webhooks with incomplete participant payloads are now enriched from BlueBubbles chat metadata, so GroupMembers/group context includes full roster more reliably. ## Security Impact (required) - New permissions/capabilities? No - Secrets/tokens handling changed? No - New/changed network calls? Yes - Command/tool execution surface changed? No - Data access scope changed? Yes - If any `Yes`, explain risk + mitigation: - Adds a bounded follow-up BlueBubbles chat query for group messages with sparse participant data (5s timeout only when needed). - Uses existing account baseUrl + password already configured for BlueBubbles. - Failure is fail-open to prior behavior (logs verbose failure and continues with webhook payload). ## Repro + Verification ### Environment OS: Windows 11, BlueBubbles integration target on macOS Runtime/container: Node 22 + pnpm Model/provider: N/A Integration/channel (if any): BlueBubbles Relevant config (redacted): BlueBubbles account with baseUrl + password, group policy open ### Steps 1. Receive BlueBubbles webhook for a group message where participants is missing/partial. 2. Process webhook through BlueBubbles monitor handler. 3. Inspect normalized context (GroupSubject, GroupMembers) dispatched to runtime. ### Expected - Group context should include enriched participants from chat metadata when webhook participants are incomplete. ### Actual - Before fix: often only sender appeared. - After fix: full participant roster is included when metadata lookup succeeds. ## Evidence Attach at least one: - [x] Screenshot/recording <img width="1177" height="931" alt="BB_Gc" src="https://github.com/user-attachments/assets/3b0adcc7-b922-4dc8-b038-bc9efe21ee03" /> ## Human Verification (required) What you personally verified (not just CI), and how: - Verified scenarios: - New monitor regression test passes and asserts GroupMembers includes enriched roster (Alice, Bob, Emily) when webhook lacks participants. Existing BlueBubbles send/monitor tests still pass. - Edge cases checked: - Enrichment is skipped for non-group messages. - Enrichment is skipped when existing participants are already sufficient. - Enrichment failure path returns original message (no hard failure). ## Compatibility / Migration - Backward compatible? Yes - Config/env changes? No - Migration needed? No - If yes, exact upgrade steps: N/A ## Failure Recovery (if this breaks) - How to disable/revert this change quickly: Revert commit/remove the enrichment call in monitor.ts. - Files/config to restore: Commit files (monitor.ts, send.ts, monitor-normalize.ts, monitor.test.ts) - Known bad symptoms reviewers should watch for: - Increased webhook handling latency in group messages. - Verbose logs showing repeated participant enrichment failures. - Group members still missing when BlueBubbles chat query cannot resolve target. ## Risks and Mitigations List only real risks for this PR. Add/remove entries as needed. If none, write `None`. - Risk: Extra API lookup per affected group webhook could add latency or transient failure points. - Mitigation: Strict gating (group-only + sparse participants), 5s timeout, and graceful fallback to original payload. - Risk: Chat target resolution mismatch across GUID/identifier variants. - Mitigation: Added matching fallback logic (chat_guid, identifier extraction, identifier fields) and regression coverage. <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR enriches BlueBubbles webhook group messages with complete participant rosters by fetching chat metadata when the webhook payload has missing/incomplete participants. **Key changes:** - Added `enrichWebhookMessageParticipants` in `monitor.ts:164-220` that queries chat metadata for group messages with sparse participant data - Refactored `resolveChatGuidForTarget` in `send.ts:319-333` to use new `resolveChatRecordForTarget` helper that returns full chat records instead of just GUIDs - Exported `normalizeParticipantList` from `monitor-normalize.ts:342` for reuse in enrichment logic - Added comprehensive test coverage in `monitor.test.ts:1586-1643` verifying enrichment works correctly **Implementation quality:** - Bounded enrichment with proper gating (group-only, sparse participants check, 5s timeout) - Graceful fail-open behavior on errors (logs and continues with original payload) - Multiple fallback matching strategies for chat lookup (GUID, identifier extraction, chat ID) - Type-safe implementation using existing BlueBubbles types <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - The implementation is well-bounded with proper error handling, comprehensive test coverage, and backward-compatible changes. The enrichment is strictly gated (group-only + sparse participants), has a 5s timeout, and fails gracefully to preserve existing behavior. The refactoring maintains all existing functionality while adding the new enrichment path. - No files require special attention <sub>Last reviewed commit: d7994b6</sub> <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> <!-- /greptile_comment -->

Most Similar PRs