@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 +45 -0
- package/package.json +1 -1
- package/src/monitor.ts +9 -0
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
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
|