@emotion-machine/claw-messenger 0.1.9 → 0.1.11

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/dist/channel.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type ChannelPlugin } from "openclaw/plugin-sdk";
1
+ import type { ChannelPlugin } from "openclaw/plugin-sdk";
2
2
  import { type ClawMessengerConfig } from "./config.js";
3
3
  import { WsClient } from "./ws/client.js";
4
4
  interface ResolvedAccount {
package/dist/channel.js CHANGED
@@ -1,4 +1,4 @@
1
- import { buildChannelConfigSchema, DEFAULT_ACCOUNT_ID, formatPairingApproveHint, PAIRING_APPROVED_MESSAGE, } from "openclaw/plugin-sdk";
1
+ import * as pluginSdk from "openclaw/plugin-sdk";
2
2
  import { ClawMessengerConfigSchema } from "./config.js";
3
3
  import { getRuntime } from "./runtime.js";
4
4
  import { WsClient } from "./ws/client.js";
@@ -14,10 +14,35 @@ const EMOJI_TO_REACTION = {
14
14
  function emojiToReaction(emoji) {
15
15
  return EMOJI_TO_REACTION[emoji];
16
16
  }
17
- function resolveAccount(cfg, _accountId) {
17
+ // -- Account resolution --
18
+ const FALLBACK_ACCOUNT_ID = "default";
19
+ function hasAccountId(value) {
20
+ if (typeof value !== "string")
21
+ return false;
22
+ const trimmed = value.trim();
23
+ return Boolean(trimmed) && trimmed !== "undefined" && trimmed !== "null";
24
+ }
25
+ function normalizeAccountIdCompat(accountId) {
26
+ const fallback = hasAccountId(accountId) ? accountId.trim() : FALLBACK_ACCOUNT_ID;
27
+ const normalize = pluginSdk.normalizeAccountId;
28
+ if (typeof normalize === "function") {
29
+ try {
30
+ const normalized = normalize(fallback);
31
+ if (hasAccountId(normalized))
32
+ return normalized.trim();
33
+ }
34
+ catch {
35
+ // Older OpenClaw SDKs can expose helpers differently when plugins are globally installed.
36
+ }
37
+ }
38
+ return fallback;
39
+ }
40
+ const DEFAULT_ACCOUNT_ID = normalizeAccountIdCompat(pluginSdk.DEFAULT_ACCOUNT_ID);
41
+ const MESSAGE_TOOL_ACTIONS = ["send", "react"];
42
+ function resolveAccount(cfg, accountId) {
18
43
  const cloudConfig = (cfg.channels?.["claw-messenger"] ?? {});
19
44
  return {
20
- accountId: DEFAULT_ACCOUNT_ID,
45
+ accountId: normalizeAccountIdCompat(accountId ?? DEFAULT_ACCOUNT_ID),
21
46
  enabled: cloudConfig.enabled !== false,
22
47
  apiKey: cloudConfig.apiKey ?? "",
23
48
  serverUrl: cloudConfig.serverUrl ?? "wss://claw-messenger.onrender.com",
@@ -57,6 +82,21 @@ export async function createGroup(to, text) {
57
82
  const result = await sendToNewGroup(ws, to, text, account.preferredService);
58
83
  return { ok: true, ...result };
59
84
  }
85
+ function resolveConfig(input) {
86
+ if (input && "channels" in input)
87
+ return input;
88
+ return input?.cfg ?? getRuntime().config.loadConfig();
89
+ }
90
+ function describeClawMessageTool(input) {
91
+ const account = resolveAccount(resolveConfig(input));
92
+ const ws = wsClients.get(account.accountId);
93
+ const connected = Boolean(ws?.connected);
94
+ return {
95
+ actions: connected ? MESSAGE_TOOL_ACTIONS : [],
96
+ capabilities: [],
97
+ schema: null,
98
+ };
99
+ }
60
100
  // -- Channel Plugin --
61
101
  const meta = {
62
102
  label: "Claw Messenger",
@@ -80,7 +120,7 @@ export const clawMessengerPlugin = {
80
120
  const ws = wsClients.get(account.accountId);
81
121
  if (!ws)
82
122
  throw new Error("Not connected to claw-messenger");
83
- await sendText(ws, id, PAIRING_APPROVED_MESSAGE, account.preferredService);
123
+ await sendText(ws, id, pluginSdk.PAIRING_APPROVED_MESSAGE, account.preferredService);
84
124
  },
85
125
  },
86
126
  capabilities: {
@@ -92,7 +132,7 @@ export const clawMessengerPlugin = {
92
132
  blockStreaming: true,
93
133
  },
94
134
  reload: { configPrefixes: ["channels.claw-messenger"] },
95
- configSchema: buildChannelConfigSchema(ClawMessengerConfigSchema),
135
+ configSchema: pluginSdk.buildChannelConfigSchema(ClawMessengerConfigSchema),
96
136
  config: {
97
137
  listAccountIds: () => [DEFAULT_ACCOUNT_ID],
98
138
  resolveAccount: (cfg, accountId) => resolveAccount(cfg, accountId),
@@ -126,7 +166,7 @@ export const clawMessengerPlugin = {
126
166
  allowFrom: account.config.allowFrom ?? [],
127
167
  policyPath: "channels.claw-messenger.dmPolicy",
128
168
  allowFromPath: "channels.claw-messenger.",
129
- approveHint: formatPairingApproveHint("claw-messenger"),
169
+ approveHint: pluginSdk.formatPairingApproveHint("claw-messenger"),
130
170
  }),
131
171
  collectWarnings: ({ cfg }) => {
132
172
  const account = resolveAccount(cfg);
@@ -158,7 +198,8 @@ export const clawMessengerPlugin = {
158
198
  },
159
199
  // Legacy API (OpenClaw <2026.3.22): kept for backward compatibility
160
200
  actions: {
161
- listActions: () => ["send", "react"],
201
+ listActions: () => [...MESSAGE_TOOL_ACTIONS],
202
+ describeMessageTool: describeClawMessageTool,
162
203
  handleAction: async ({ action, params, cfg }) => {
163
204
  const account = resolveAccount(cfg);
164
205
  const ws = wsClients.get(account.accountId);
@@ -360,19 +401,25 @@ export const clawMessengerPlugin = {
360
401
  });
361
402
  ws.connect();
362
403
  wsClients.set(resolvedAccountId, ws);
363
- // Handle abort
364
- const stopHandler = () => {
365
- ctx.log?.info(`[${resolvedAccountId}] Stopping Claw Messenger provider`);
366
- ws.stop();
367
- wsClients.delete(resolvedAccountId);
368
- };
369
- ctx.abortSignal?.addEventListener("abort", stopHandler);
370
- return {
371
- stop: () => {
372
- stopHandler();
404
+ return new Promise((resolve) => {
405
+ let stopped = false;
406
+ const stopHandler = () => {
407
+ if (stopped)
408
+ return;
409
+ stopped = true;
410
+ ctx.log?.info(`[${resolvedAccountId}] Stopping Claw Messenger provider`);
411
+ ws.stop();
412
+ wsClients.delete(resolvedAccountId);
373
413
  ctx.abortSignal?.removeEventListener("abort", stopHandler);
374
- },
375
- };
414
+ resolve();
415
+ };
416
+ if (ctx.abortSignal?.aborted) {
417
+ stopHandler();
418
+ }
419
+ else {
420
+ ctx.abortSignal?.addEventListener("abort", stopHandler);
421
+ }
422
+ });
376
423
  },
377
424
  logoutAccount: async ({ cfg }) => {
378
425
  const account = resolveAccount(cfg);
@@ -388,16 +435,7 @@ export const clawMessengerPlugin = {
388
435
  // OpenClaw 2026.3.22+ message-action-discovery API.
389
436
  // Added as a runtime property because the ChannelPlugin type from older SDK
390
437
  // versions doesn't include it. Newer OpenClaw calls this; older versions ignore it.
391
- clawMessengerPlugin.describeMessageTool = (cfg) => {
392
- const account = resolveAccount(cfg);
393
- const ws = wsClients.get(account.accountId);
394
- const connected = Boolean(ws?.connected);
395
- return {
396
- actions: connected ? ["send", "react"] : [],
397
- capabilities: [],
398
- schema: null,
399
- };
400
- };
438
+ clawMessengerPlugin.describeMessageTool = describeClawMessageTool;
401
439
  // -- Inbound message handler --
402
440
  async function handleInboundMessage(data, accountId, account, ctx) {
403
441
  const from = data.from;
package/dist/index.js CHANGED
@@ -99,7 +99,7 @@ const plugin = {
99
99
  const ws = getWsClient(status.accountId);
100
100
  const diagnostics = ws?.getDiagnostics() ?? { errors: [], connectionLog: [] };
101
101
  const report = {
102
- plugin_version: "0.1.7",
102
+ plugin_version: "0.1.11",
103
103
  node_version: process.version,
104
104
  connected: status.connected,
105
105
  server_url: status.serverUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emotion-machine/claw-messenger",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "iMessage, RCS & SMS channel plugin for OpenClaw — no phone or Mac Mini required",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",