fix(bluebubbles): repair same-host webhook flow and iMessage sanitization - #9272
Open
trevorgordon981 wants to merge 1 commit into
Open
fix(bluebubbles): repair same-host webhook flow and iMessage sanitization#9272trevorgordon981 wants to merge 1 commit into
trevorgordon981 wants to merge 1 commit into
Conversation
trevorgordon981
force-pushed
the
fix/bluebubbles-same-host
branch
from
June 22, 2026 03:29
4bd4030 to
39faa12
Compare
teknium1
reviewed
Jul 12, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for preserving the remaining same-host URL fix and the outbound rendering cleanup. The webhook-event and password-registration parts described in the PR body are already on current main (064f8d74d, 326cbbe40), while the default-host mismatch remains: gateway/platforms/bluebubbles.py:283 binds self.webhook_host, but :315-316 rewrites default 127.0.0.1 to localhost.
Problems
gateway/platforms/bluebubbles.py:77-80adds iMessage sanitization, but the PR test diff only updates_webhook_urlassertions. There is no regression test for Block Elements, BMP/supplementary PUA removal, preserved ordinary emoji, or whitespace cleanup.
Suggested changes
- Add focused
format_message()or helper tests for those sanitization contracts. - Salvage only the still-needed URL normalization and sanitization portions; the webhook-event and password fixes are already implemented on
mainatgateway/platforms/bluebubbles.py:320-331and:374-377.
This is an automated hermes-sweeper review.
| # * Block Elements (U+2580..U+259F) — streaming-cursor artifacts like ▉ that | ||
| # the agent's stream renderer can leak into the final message. | ||
| # * Private Use Area (U+E000..U+F8FF) — Slack custom workspace emoji live | ||
| # here and get carried through when Slack history ends up in model context. |
Contributor
There was a problem hiding this comment.
Please add regression coverage for this helper via format_message(): Block Elements, BMP and supplementary PUA code points, preserved standard emoji, mixed text, and trailing whitespace. The current test changes cover only URL normalization.
Adds regression coverage for the iMessage tofu-character sanitization (Block Elements U+2580..U+259F, BMP PUA U+E000..U+F8FF, supplementary PUAs U+F0000..U+FFFFD / U+100000..U+10FFFD), confirming ordinary emoji are preserved and trailing whitespace is rstripped. Also updates the _webhook_url assertions for the new 127.0.0.1 loopback normalization (including the ::1 host) and wires _sanitize_for_imessage into format_message().
trevorgordon981
force-pushed
the
fix/bluebubbles-same-host
branch
from
August 7, 2026 05:56
39faa12 to
fd70bae
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
What's in this PR
All four fixes live in
gateway/platforms/bluebubbles.py:Drop invalid
"message"event from the webhook registration payload (fixes BlueBubbles adapter registers invalid "message" event; 400 Bad Request blocks all webhook registration #9263). BlueBubbles Server only acceptsnew-message/updated-message(among others) and 400s the entirePOST /api/v1/webhookif"message"is in the list — so on stock main, no events get subscribed at all.Embed the password in
_webhook_url(fixes BlueBubbles adapter webhook URL omits password; every dispatch 401s and no inbound messages reach the agent #9265). BlueBubblesWebhookService.dispatchEvent()has no auth-header configuration, so every dispatch was being rejected by_handle_webhook's password check with 401 Unauthorized.Use the
127.0.0.1literal in_webhook_urlinstead of rewriting loopback hosts to"localhost". On macOS with modern Node.js, BlueBubbles Server resolveslocalhost→::1(IPv6 first), but the adapter'saiohttp.web.TCPSitebinds IPv4-only, so every same-host dispatch fails withECONNREFUSED ::1:8645. Switching to the literal avoids the AAAA lookup entirely.Strip iMessage tofu characters in outbound sends. Apple Color Emoji has no glyphs for two ranges that routinely leak through the pipeline:
▉that the agent's stream renderer can leave in the final message.A new
_sanitize_for_imessage()helper is called fromsend()andformat_message()before the outbound REST call so the user sees clean text instead of boxes.#1 and #2 each independently prevent any inbound message from reaching the agent, and #3 prevents anything if you run BB Server and Hermes on the same Mac (which is the documented recommended setup). In combination, the native BlueBubbles adapter has not worked out of the box for same-host installs since it was added. #4 is a quality-of-life fix that becomes visible as soon as the first three are in place.
Test plan
"message"event removed,_register_webhookreturnsstatus=200against a real BlueBubbles Server 1.9.9 andGET /api/v1/webhookshows the new entry withevents: ["new-message", "updated-message"]._webhook_url, inbound iMessages from BlueBubbles dispatch to Hermes and hit_handle_webhookas 200 OK instead of 401; the agent actually runs and produces a reply.127.0.0.1,aiohttp.TCPSitebind and BB dispatch target are both unambiguously IPv4; same-host dispatch succeeds where it previously returnedECONNREFUSED ::1:8645in~/Library/Logs/bluebubbles-server/main.log._sanitize_for_imessageunit-sanity tested against"Hello ▉","Done ▉", strings with\uE001\uE002PUA chars, strings with legitimate🙂 ✅emoji (preserved), and mixed strings. Trailing-whitespace cleanup works as expected.Notes
gateway/run.pysubstitutes the literal"(No response generated)"into empty agent results and it ends up being delivered to users (and to cron home channels). Not fixed in this PR since it lives in different files and touches the cron scheduler's empty-skip path.🤖 Generated with Claude Code