@openclaw/bluebubbles 2026.2.2 → 2026.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # BlueBubbles extension (developer reference)
2
+
3
+ This directory contains the **BlueBubbles external channel plugin** for OpenClaw.
4
+
5
+ If you’re looking for **how to use BlueBubbles as an agent/tool user**, see:
6
+
7
+ - `skills/bluebubbles/SKILL.md`
8
+
9
+ ## Layout
10
+
11
+ - Extension package: `extensions/bluebubbles/` (entry: `index.ts`).
12
+ - Channel implementation: `extensions/bluebubbles/src/channel.ts`.
13
+ - Webhook handling: `extensions/bluebubbles/src/monitor.ts` (register via `api.registerHttpHandler`).
14
+ - REST helpers: `extensions/bluebubbles/src/send.ts` + `extensions/bluebubbles/src/probe.ts`.
15
+ - Runtime bridge: `extensions/bluebubbles/src/runtime.ts` (set via `api.runtime`).
16
+ - Catalog entry for onboarding: `src/channels/plugins/catalog.ts`.
17
+
18
+ ## Internal helpers (use these, not raw API calls)
19
+
20
+ - `probeBlueBubbles` in `extensions/bluebubbles/src/probe.ts` for health checks.
21
+ - `sendMessageBlueBubbles` in `extensions/bluebubbles/src/send.ts` for text delivery.
22
+ - `resolveChatGuidForTarget` in `extensions/bluebubbles/src/send.ts` for chat lookup.
23
+ - `sendBlueBubblesReaction` in `extensions/bluebubbles/src/reactions.ts` for tapbacks.
24
+ - `sendBlueBubblesTyping` + `markBlueBubblesChatRead` in `extensions/bluebubbles/src/chat.ts`.
25
+ - `downloadBlueBubblesAttachment` in `extensions/bluebubbles/src/attachments.ts` for inbound media.
26
+ - `buildBlueBubblesApiUrl` + `blueBubblesFetchWithTimeout` in `extensions/bluebubbles/src/types.ts` for shared REST plumbing.
27
+
28
+ ## Webhooks
29
+
30
+ - BlueBubbles posts JSON to the gateway HTTP server.
31
+ - Normalize sender/chat IDs defensively (payloads vary by version).
32
+ - Skip messages marked as from self.
33
+ - Route into core reply pipeline via the plugin runtime (`api.runtime`) and `openclaw/plugin-sdk` helpers.
34
+ - For attachments/stickers, use `<media:...>` placeholders when text is empty and attach media paths via `MediaUrl(s)` in the inbound context.
35
+
36
+ ## Config (core)
37
+
38
+ - `channels.bluebubbles.serverUrl` (base URL), `channels.bluebubbles.password`, `channels.bluebubbles.webhookPath`.
39
+ - Action gating: `channels.bluebubbles.actions.reactions` (default true).
40
+
41
+ ## Message tool notes
42
+
43
+ - **Reactions:** the `react` action requires a `target` (phone number or chat identifier) in addition to `messageId`.
44
+ Example:
45
+ `action=react target=+15551234567 messageId=ABC123 emoji=❤️`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/bluebubbles",
3
- "version": "2026.2.2",
3
+ "version": "2026.2.3",
4
4
  "description": "OpenClaw BlueBubbles channel plugin",
5
5
  "type": "module",
6
6
  "devDependencies": {
package/src/monitor.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { IncomingMessage, ServerResponse } from "node:http";
2
2
  import type { OpenClawConfig } from "openclaw/plugin-sdk";
3
3
  import {
4
+ createReplyPrefixOptions,
4
5
  logAckFailure,
5
6
  logInboundDrop,
6
7
  logTypingFailure,
@@ -2173,10 +2174,17 @@ async function processMessage(
2173
2174
  }, typingRestartDelayMs);
2174
2175
  };
2175
2176
  try {
2177
+ const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
2178
+ cfg: config,
2179
+ agentId: route.agentId,
2180
+ channel: "bluebubbles",
2181
+ accountId: account.accountId,
2182
+ });
2176
2183
  await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
2177
2184
  ctx: ctxPayload,
2178
2185
  cfg: config,
2179
2186
  dispatcherOptions: {
2187
+ ...prefixOptions,
2180
2188
  deliver: async (payload, info) => {
2181
2189
  const rawReplyToId =
2182
2190
  typeof payload.replyToId === "string" ? payload.replyToId.trim() : "";
@@ -2288,6 +2296,7 @@ async function processMessage(
2288
2296
  },
2289
2297
  },
2290
2298
  replyOptions: {
2299
+ onModelSelected,
2291
2300
  disableBlockStreaming:
2292
2301
  typeof account.config.blockStreaming === "boolean"
2293
2302
  ? !account.config.blockStreaming