@emotion-machine/claw-messenger 0.1.1 → 0.1.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 CHANGED
@@ -10,22 +10,18 @@ openclaw plugins install @emotion-machine/claw-messenger
10
10
 
11
11
  ## Configuration
12
12
 
13
- After installing, add to your OpenClaw config under `channels`:
13
+ After installing, add to your config under `channels`:
14
14
 
15
15
  ```json5
16
16
  {
17
17
  "channels": {
18
18
  "claw-messenger": {
19
- "accounts": {
20
- "default": {
21
- "enabled": true,
22
- "apiKey": "cm_live_XXXXXXXX_YYYYYYYYYYYYYY",
23
- "serverUrl": "wss://claw-messenger.onrender.com",
24
- "preferredService": "iMessage", // "iMessage" | "RCS" | "SMS"
25
- "dmPolicy": "pairing", // "open" | "pairing" | "allowlist"
26
- "allowFrom": ["+15551234567"] // only used with "allowlist" policy
27
- }
28
- }
19
+ "enabled": true,
20
+ "apiKey": "cm_live_XXXXXXXX_YYYYYYYYYYYYYY",
21
+ "serverUrl": "wss://claw-messenger.onrender.com",
22
+ "preferredService": "iMessage", // "iMessage" | "RCS" | "SMS"
23
+ "dmPolicy": "pairing", // "open" | "pairing" | "allowlist"
24
+ "allowFrom": ["+15551234567"] // only used with "allowlist" policy
29
25
  }
30
26
  }
31
27
  }
@@ -65,4 +61,4 @@ The plugin registers two tools your agent can call:
65
61
 
66
62
  ## License
67
63
 
68
- UNLICENSED
64
+ UNLICENSED
package/dist/channel.d.ts CHANGED
@@ -1,7 +1,3 @@
1
- /**
2
- * Claw Messenger channel plugin — adapted from channel-linq.
3
- * All Linq API interaction is replaced by WebSocket communication to claw-messenger.
4
- */
5
1
  import { type ChannelPlugin } from "openclaw/plugin-sdk";
6
2
  import { type ClawMessengerConfig } from "./config.js";
7
3
  interface ResolvedAccount {
@@ -18,5 +14,10 @@ export declare function getConnectionStatus(): {
18
14
  preferredService: string;
19
15
  accountId: string;
20
16
  };
17
+ export declare function createGroup(to: string[], text: string): Promise<{
18
+ ok: boolean;
19
+ messageId: string;
20
+ chatId: string;
21
+ }>;
21
22
  export declare const clawMessengerPlugin: ChannelPlugin<ResolvedAccount>;
22
23
  export {};
package/dist/channel.js CHANGED
@@ -1,7 +1,3 @@
1
- /**
2
- * Claw Messenger channel plugin — adapted from channel-linq.
3
- * All Linq API interaction is replaced by WebSocket communication to claw-messenger.
4
- */
5
1
  import { buildChannelConfigSchema, DEFAULT_ACCOUNT_ID, formatPairingApproveHint, normalizeE164, PAIRING_APPROVED_MESSAGE, } from "openclaw/plugin-sdk";
6
2
  import { ClawMessengerConfigSchema } from "./config.js";
7
3
  import { getRuntime } from "./runtime.js";
@@ -45,6 +41,19 @@ export function getConnectionStatus() {
45
41
  accountId: account.accountId,
46
42
  };
47
43
  }
44
+ export async function createGroup(to, text) {
45
+ const runtime = getRuntime();
46
+ const cfg = runtime.config.loadConfig();
47
+ const account = resolveAccount(cfg);
48
+ const ws = wsClients.get(account.accountId);
49
+ if (!ws)
50
+ throw new Error("Not connected to claw-messenger");
51
+ if (!Array.isArray(to) || to.length < 2) {
52
+ throw new Error("Group requires at least 2 recipients");
53
+ }
54
+ const result = await sendToNewGroup(ws, to, text, account.preferredService);
55
+ return { ok: true, ...result };
56
+ }
48
57
  // -- Channel Plugin --
49
58
  const meta = {
50
59
  label: "Claw Messenger",
@@ -52,7 +61,7 @@ const meta = {
52
61
  detailLabel: "Claw Messenger",
53
62
  docsPath: "/channels/claw-messenger",
54
63
  docsLabel: "claw-messenger",
55
- blurb: "iMessage, RCS & SMS without a Mac or Linq account — via shared claw-messenger proxy.",
64
+ blurb: "iMessage, RCS & SMS without a Mac or a phone number",
56
65
  systemImage: "message.fill",
57
66
  };
58
67
  export const clawMessengerPlugin = {
@@ -149,6 +158,7 @@ export const clawMessengerPlugin = {
149
158
  "Use reactions naturally — the way a real person would in iMessage.",
150
159
  ],
151
160
  },
161
+ // Legacy API (OpenClaw <2026.3.22): kept for backward compatibility
152
162
  actions: {
153
163
  listActions: () => ["send", "react"],
154
164
  handleAction: async ({ action, params, cfg }) => {
@@ -377,6 +387,19 @@ export const clawMessengerPlugin = {
377
387
  },
378
388
  },
379
389
  };
390
+ // OpenClaw 2026.3.22+ message-action-discovery API.
391
+ // Added as a runtime property because the ChannelPlugin type from older SDK
392
+ // versions doesn't include it. Newer OpenClaw calls this; older versions ignore it.
393
+ clawMessengerPlugin.describeMessageTool = (cfg) => {
394
+ const account = resolveAccount(cfg);
395
+ const ws = wsClients.get(account.accountId);
396
+ const connected = Boolean(ws?.connected);
397
+ return {
398
+ actions: connected ? ["send", "react"] : [],
399
+ capabilities: [],
400
+ schema: null,
401
+ };
402
+ };
380
403
  // -- Inbound message handler --
381
404
  async function handleInboundMessage(data, accountId, account, ctx) {
382
405
  const from = data.from;
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
2
2
  import { Type } from "@sinclair/typebox";
3
- import { clawMessengerPlugin, getConnectionStatus } from "./channel.js";
3
+ import { clawMessengerPlugin, getConnectionStatus, createGroup } from "./channel.js";
4
4
  import { setRuntime, getRuntime } from "./runtime.js";
5
5
  const VALID_SERVICES = ["iMessage", "RCS", "SMS"];
6
6
  const plugin = {
7
7
  id: "claw-messenger",
8
8
  name: "Claw Messenger",
9
- description: "iMessage, RCS & SMS without a Mac or Linq account — via shared claw-messenger proxy",
9
+ description: "iMessage, RCS & SMS without a Mac or a phone number",
10
10
  configSchema: emptyPluginConfigSchema(),
11
11
  register(api) {
12
12
  setRuntime(api.runtime);
@@ -56,6 +56,32 @@ const plugin = {
56
56
  };
57
57
  },
58
58
  });
59
+ api.registerTool({
60
+ name: "claw_messenger_create_group",
61
+ label: "Create iMessage/RCS/SMS Group",
62
+ description: "Create a new group chat and send the first message. Pass an array of E.164 phone numbers (at least 2) and the initial message text. Returns the chatId to use for future messages to this group.",
63
+ parameters: Type.Object({
64
+ to: Type.Array(Type.String(), {
65
+ description: "Array of E.164 phone numbers (e.g. [\"+12125551234\", \"+14155559876\"])",
66
+ minItems: 2,
67
+ }),
68
+ text: Type.String({ description: "The initial message to send to the group" }),
69
+ }),
70
+ async execute(_toolCallId, params) {
71
+ const { to, text } = params;
72
+ try {
73
+ const result = await createGroup(to, text);
74
+ return {
75
+ content: [{ type: "text", text: JSON.stringify(result) }],
76
+ };
77
+ }
78
+ catch (err) {
79
+ return {
80
+ content: [{ type: "text", text: JSON.stringify({ ok: false, error: err.message }) }],
81
+ };
82
+ }
83
+ },
84
+ });
59
85
  // -- Auto-Reply Commands --
60
86
  api.registerCommand({
61
87
  name: "cm-status",
@@ -1,7 +1,3 @@
1
- /**
2
- * Send messages via WebSocket to claw-messenger -> Linq -> iMessage.
3
- * Replaces direct Linq API calls from channel-linq/src/outbound/send.ts.
4
- */
5
1
  import type { WsClient } from "../ws/client.js";
6
2
  export interface SendResult {
7
3
  messageId: string;
@@ -1,7 +1,3 @@
1
- /**
2
- * Send messages via WebSocket to claw-messenger -> Linq -> iMessage.
3
- * Replaces direct Linq API calls from channel-linq/src/outbound/send.ts.
4
- */
5
1
  export async function sendText(ws, to, text, service) {
6
2
  return sendMessage(ws, to, [{ type: "text", value: text }], service);
7
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emotion-machine/claw-messenger",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
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",