@openclaw/crabline 0.1.3 → 0.1.5
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 +31 -31
- package/dist/src/cli/program.js +15 -14
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/index.d.ts +9 -11
- package/dist/src/index.js +5 -6
- package/dist/src/index.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.d.ts +1 -1
- package/dist/src/openclaw/bridges/telegram.d.ts +1 -1
- package/dist/src/openclaw/bridges/whatsapp.d.ts +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js +1 -2
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
- package/dist/src/openclaw/shared.d.ts +11 -11
- package/dist/src/openclaw/shared.js +2 -2
- package/dist/src/openclaw/shared.js.map +1 -1
- package/dist/src/openclaw.d.ts +7 -7
- package/dist/src/openclaw.js +9 -9
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/providers/catalog.d.ts +1 -1
- package/dist/src/providers/catalog.js +1 -1
- package/dist/src/providers/catalog.js.map +1 -1
- package/dist/src/{fake-servers → servers}/http.d.ts +2 -1
- package/dist/src/{fake-servers → servers}/http.js +2 -1
- package/dist/src/servers/http.js.map +1 -0
- package/dist/src/servers/index.d.ts +25 -0
- package/dist/src/servers/index.js +22 -0
- package/dist/src/servers/index.js.map +1 -0
- package/dist/src/{fake-servers → servers}/slack.d.ts +5 -5
- package/dist/src/{fake-servers → servers}/slack.js +2 -2
- package/dist/src/servers/slack.js.map +1 -0
- package/dist/src/{fake-servers → servers}/telegram.d.ts +5 -5
- package/dist/src/{fake-servers → servers}/telegram.js +3 -3
- package/dist/src/servers/telegram.js.map +1 -0
- package/dist/src/servers/whatsapp-baileys-websocket.d.ts +27 -0
- package/dist/src/servers/whatsapp-baileys-websocket.js +555 -0
- package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -0
- package/dist/src/servers/whatsapp-wire/binary-node.d.ts +9 -0
- package/dist/src/servers/whatsapp-wire/binary-node.js +427 -0
- package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -0
- package/dist/src/servers/whatsapp-wire/crypto.d.ts +27 -0
- package/dist/src/servers/whatsapp-wire/crypto.js +108 -0
- package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -0
- package/dist/src/servers/whatsapp-wire/handshake.d.ts +17 -0
- package/dist/src/servers/whatsapp-wire/handshake.js +154 -0
- package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -0
- package/dist/src/servers/whatsapp-wire/signal.d.ts +5 -0
- package/dist/src/servers/whatsapp-wire/signal.js +24 -0
- package/dist/src/servers/whatsapp-wire/signal.js.map +1 -0
- package/dist/src/servers/whatsapp.d.ts +39 -0
- package/dist/src/{fake-servers → servers}/whatsapp.js +18 -166
- package/dist/src/servers/whatsapp.js.map +1 -0
- package/docs/channel-setup.md +29 -27
- package/package.json +10 -10
- package/dist/src/fake-servers/http.js.map +0 -1
- package/dist/src/fake-servers/index.d.ts +0 -25
- package/dist/src/fake-servers/index.js +0 -26
- package/dist/src/fake-servers/index.js.map +0 -1
- package/dist/src/fake-servers/slack.js.map +0 -1
- package/dist/src/fake-servers/telegram.js.map +0 -1
- package/dist/src/fake-servers/whatsapp-socket-factory.d.ts +0 -34
- package/dist/src/fake-servers/whatsapp-socket-factory.js +0 -225
- package/dist/src/fake-servers/whatsapp-socket-factory.js.map +0 -1
- package/dist/src/fake-servers/whatsapp.d.ts +0 -96
- package/dist/src/fake-servers/whatsapp.js.map +0 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
export function decodeHandshakeMessage(data) {
|
|
3
|
+
const reader = new ProtoReader(data);
|
|
4
|
+
const message = {};
|
|
5
|
+
while (!reader.done()) {
|
|
6
|
+
const tag = reader.uint32();
|
|
7
|
+
const field = tag >>> 3;
|
|
8
|
+
if (field === 2) {
|
|
9
|
+
message.clientHello = decodeClientHello(reader.bytes());
|
|
10
|
+
}
|
|
11
|
+
else if (field === 4) {
|
|
12
|
+
message.clientFinish = decodeClientFinish(reader.bytes());
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
reader.skip(tag & 7);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return message;
|
|
19
|
+
}
|
|
20
|
+
export function encodeHandshakeMessage(message) {
|
|
21
|
+
const writer = new ProtoWriter();
|
|
22
|
+
if (message.serverHello) {
|
|
23
|
+
writer.bytesField(3, encodeServerHello(message.serverHello));
|
|
24
|
+
}
|
|
25
|
+
return writer.finish();
|
|
26
|
+
}
|
|
27
|
+
function decodeClientHello(data) {
|
|
28
|
+
const reader = new ProtoReader(data);
|
|
29
|
+
let ephemeral;
|
|
30
|
+
while (!reader.done()) {
|
|
31
|
+
const tag = reader.uint32();
|
|
32
|
+
if (tag >>> 3 === 1) {
|
|
33
|
+
ephemeral = reader.bytes();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
reader.skip(tag & 7);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return ephemeral === undefined ? {} : { ephemeral };
|
|
40
|
+
}
|
|
41
|
+
function decodeClientFinish(data) {
|
|
42
|
+
const reader = new ProtoReader(data);
|
|
43
|
+
let payload;
|
|
44
|
+
let staticKey;
|
|
45
|
+
while (!reader.done()) {
|
|
46
|
+
const tag = reader.uint32();
|
|
47
|
+
const field = tag >>> 3;
|
|
48
|
+
if (field === 1) {
|
|
49
|
+
staticKey = reader.bytes();
|
|
50
|
+
}
|
|
51
|
+
else if (field === 2) {
|
|
52
|
+
payload = reader.bytes();
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
reader.skip(tag & 7);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
...(payload === undefined ? {} : { payload }),
|
|
60
|
+
...(staticKey === undefined ? {} : { staticKey }),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function encodeServerHello(serverHello) {
|
|
64
|
+
const writer = new ProtoWriter();
|
|
65
|
+
writer.bytesField(1, serverHello.ephemeral);
|
|
66
|
+
writer.bytesField(2, serverHello.staticKey);
|
|
67
|
+
writer.bytesField(3, serverHello.payload);
|
|
68
|
+
return writer.finish();
|
|
69
|
+
}
|
|
70
|
+
class ProtoReader {
|
|
71
|
+
#offset = 0;
|
|
72
|
+
#buffer;
|
|
73
|
+
constructor(data) {
|
|
74
|
+
this.#buffer = Buffer.from(data);
|
|
75
|
+
}
|
|
76
|
+
done() {
|
|
77
|
+
return this.#offset >= this.#buffer.length;
|
|
78
|
+
}
|
|
79
|
+
bytes() {
|
|
80
|
+
const length = this.uint32();
|
|
81
|
+
this.#require(length);
|
|
82
|
+
const value = this.#buffer.subarray(this.#offset, this.#offset + length);
|
|
83
|
+
this.#offset += length;
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
skip(wireType) {
|
|
87
|
+
if (wireType === 0) {
|
|
88
|
+
this.uint32();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (wireType === 1) {
|
|
92
|
+
this.#require(8);
|
|
93
|
+
this.#offset += 8;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (wireType === 2) {
|
|
97
|
+
const length = this.uint32();
|
|
98
|
+
this.#require(length);
|
|
99
|
+
this.#offset += length;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (wireType === 5) {
|
|
103
|
+
this.#require(4);
|
|
104
|
+
this.#offset += 4;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
throw new Error(`Unsupported WhatsApp handshake wire type: ${wireType}.`);
|
|
108
|
+
}
|
|
109
|
+
uint32() {
|
|
110
|
+
let value = 0;
|
|
111
|
+
let shift = 0;
|
|
112
|
+
while (shift < 32) {
|
|
113
|
+
this.#require(1);
|
|
114
|
+
const byte = this.#buffer[this.#offset];
|
|
115
|
+
this.#offset += 1;
|
|
116
|
+
if (byte === undefined) {
|
|
117
|
+
throw new Error("Unexpected end of WhatsApp handshake protobuf.");
|
|
118
|
+
}
|
|
119
|
+
value |= (byte & 0x7f) << shift;
|
|
120
|
+
if ((byte & 0x80) === 0) {
|
|
121
|
+
return value >>> 0;
|
|
122
|
+
}
|
|
123
|
+
shift += 7;
|
|
124
|
+
}
|
|
125
|
+
throw new Error("Invalid WhatsApp handshake varint.");
|
|
126
|
+
}
|
|
127
|
+
#require(length) {
|
|
128
|
+
if (this.#offset + length > this.#buffer.length) {
|
|
129
|
+
throw new Error("Unexpected end of WhatsApp handshake protobuf.");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
class ProtoWriter {
|
|
134
|
+
#parts = [];
|
|
135
|
+
bytesField(field, value) {
|
|
136
|
+
this.uint32((field << 3) | 2);
|
|
137
|
+
this.uint32(value.byteLength);
|
|
138
|
+
this.#parts.push(Buffer.from(value));
|
|
139
|
+
}
|
|
140
|
+
finish() {
|
|
141
|
+
return Buffer.concat(this.#parts);
|
|
142
|
+
}
|
|
143
|
+
uint32(value) {
|
|
144
|
+
let remaining = value >>> 0;
|
|
145
|
+
const bytes = [];
|
|
146
|
+
while (remaining > 127) {
|
|
147
|
+
bytes.push((remaining & 0x7f) | 0x80);
|
|
148
|
+
remaining >>>= 7;
|
|
149
|
+
}
|
|
150
|
+
bytes.push(remaining);
|
|
151
|
+
this.#parts.push(Buffer.from(bytes));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=handshake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../../../src/servers/whatsapp-wire/handshake.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BinaryNode } from "./binary-node.js";
|
|
2
|
+
import { KEY_BUNDLE_TYPE, type KeyPair, type SignedKeyPair } from "./crypto.js";
|
|
3
|
+
export declare function xmppPreKey(pair: KeyPair, id: number): BinaryNode;
|
|
4
|
+
export declare function xmppSignedPreKey(key: SignedKeyPair): BinaryNode;
|
|
5
|
+
export { KEY_BUNDLE_TYPE };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { encodeBigEndian, KEY_BUNDLE_TYPE } from "./crypto.js";
|
|
2
|
+
export function xmppPreKey(pair, id) {
|
|
3
|
+
return {
|
|
4
|
+
attrs: {},
|
|
5
|
+
content: [
|
|
6
|
+
{ attrs: {}, content: encodeBigEndian(id, 3), tag: "id" },
|
|
7
|
+
{ attrs: {}, content: pair.public, tag: "value" },
|
|
8
|
+
],
|
|
9
|
+
tag: "key",
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function xmppSignedPreKey(key) {
|
|
13
|
+
return {
|
|
14
|
+
attrs: {},
|
|
15
|
+
content: [
|
|
16
|
+
{ attrs: {}, content: encodeBigEndian(key.keyId, 3), tag: "id" },
|
|
17
|
+
{ attrs: {}, content: key.keyPair.public, tag: "value" },
|
|
18
|
+
{ attrs: {}, content: key.signature, tag: "signature" },
|
|
19
|
+
],
|
|
20
|
+
tag: "skey",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export { KEY_BUNDLE_TYPE };
|
|
24
|
+
//# sourceMappingURL=signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../../../../src/servers/whatsapp-wire/signal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAoC,MAAM,aAAa,CAAC;AAEjG,MAAM,UAAU,UAAU,CAAC,IAAa,EAAE,EAAU;IAClD,OAAO;QACL,KAAK,EAAE,EAAE;QACT,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE;YACzD,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE;SAClD;QACD,GAAG,EAAE,KAAK;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAkB;IACjD,OAAO;QACL,KAAK,EAAE,EAAE;QACT,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE;YAChE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE;YACxD,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE;SACxD;QACD,GAAG,EAAE,MAAM;KACZ,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type WhatsAppBaileysInboundMessage } from "./whatsapp-baileys-websocket.js";
|
|
2
|
+
export type WhatsAppBaileysMessage = WhatsAppBaileysInboundMessage;
|
|
3
|
+
export type WhatsAppServerManifest = {
|
|
4
|
+
accessToken: string;
|
|
5
|
+
adminToken: string;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
endpoints: {
|
|
8
|
+
adminInboundUrl: string;
|
|
9
|
+
apiRoot: string;
|
|
10
|
+
baileysWebSocketUrl: string;
|
|
11
|
+
messagesUrl: string;
|
|
12
|
+
presenceUrl: string;
|
|
13
|
+
};
|
|
14
|
+
env: {
|
|
15
|
+
CRABLINE_WHATSAPP_ADMIN_TOKEN: string;
|
|
16
|
+
CRABLINE_WHATSAPP_ACCESS_TOKEN: string;
|
|
17
|
+
CRABLINE_WHATSAPP_API_ROOT: string;
|
|
18
|
+
CRABLINE_WHATSAPP_BAILEYS_WEB_SOCKET_URL: string;
|
|
19
|
+
CRABLINE_WHATSAPP_RECORDER_PATH: string;
|
|
20
|
+
CRABLINE_WHATSAPP_SELF_JID: string;
|
|
21
|
+
};
|
|
22
|
+
provider: "whatsapp";
|
|
23
|
+
recorderPath: string;
|
|
24
|
+
selfJid: string;
|
|
25
|
+
version: 1;
|
|
26
|
+
};
|
|
27
|
+
export type StartedWhatsAppServer = {
|
|
28
|
+
close(): Promise<void>;
|
|
29
|
+
manifest: WhatsAppServerManifest;
|
|
30
|
+
};
|
|
31
|
+
export type StartWhatsAppServerParams = {
|
|
32
|
+
accessToken?: string | undefined;
|
|
33
|
+
adminToken?: string | undefined;
|
|
34
|
+
host?: string | undefined;
|
|
35
|
+
port?: number | undefined;
|
|
36
|
+
recorderPath?: string | undefined;
|
|
37
|
+
selfJid?: string | undefined;
|
|
38
|
+
};
|
|
39
|
+
export declare function startWhatsAppServer(params?: StartWhatsAppServerParams): Promise<StartedWhatsAppServer>;
|
|
@@ -2,6 +2,7 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { adminAuthError, hasAdminToken, jsonResponse, parseRequestBody, queryRecord, readTrimmedString, startHttpJsonServer, } from "./http.js";
|
|
5
|
+
import { attachWhatsAppBaileysWebSocketServer, } from "./whatsapp-baileys-websocket.js";
|
|
5
6
|
const WHATSAPP_USER_JID_RE = /^\d{7,15}(?::\d+)?@s\.whatsapp\.net$/iu;
|
|
6
7
|
const WHATSAPP_LEGACY_USER_JID_RE = /^\d{7,15}@c\.us$/iu;
|
|
7
8
|
const WHATSAPP_GROUP_JID_RE = /^\d{5,}@g\.us$/iu;
|
|
@@ -65,42 +66,6 @@ function nextMessageId(state) {
|
|
|
65
66
|
function waIdFromJid(jid) {
|
|
66
67
|
return jid.split("@", 1)[0]?.split(":", 1)[0] ?? jid;
|
|
67
68
|
}
|
|
68
|
-
function trimTrailingSlashes(value) {
|
|
69
|
-
let end = value.length;
|
|
70
|
-
while (end > 0 && value.charCodeAt(end - 1) === 47) {
|
|
71
|
-
end -= 1;
|
|
72
|
-
}
|
|
73
|
-
return value.slice(0, end);
|
|
74
|
-
}
|
|
75
|
-
function trimLeadingSlashes(value) {
|
|
76
|
-
let start = 0;
|
|
77
|
-
while (start < value.length && value.charCodeAt(start) === 47) {
|
|
78
|
-
start += 1;
|
|
79
|
-
}
|
|
80
|
-
return value.slice(start);
|
|
81
|
-
}
|
|
82
|
-
function joinUrl(root, pathPart) {
|
|
83
|
-
return `${trimTrailingSlashes(root)}/${trimLeadingSlashes(pathPart)}`;
|
|
84
|
-
}
|
|
85
|
-
function normalizeApiRoot(value) {
|
|
86
|
-
return trimTrailingSlashes(value);
|
|
87
|
-
}
|
|
88
|
-
async function postJson(params) {
|
|
89
|
-
const response = await params.fetchImpl(params.url, {
|
|
90
|
-
body: JSON.stringify(params.body),
|
|
91
|
-
headers: {
|
|
92
|
-
authorization: `Bearer ${params.accessToken}`,
|
|
93
|
-
"content-type": "application/json",
|
|
94
|
-
},
|
|
95
|
-
method: "POST",
|
|
96
|
-
});
|
|
97
|
-
const rawBody = await response.text();
|
|
98
|
-
const parsed = rawBody ? JSON.parse(rawBody) : {};
|
|
99
|
-
if (!response.ok) {
|
|
100
|
-
throw new Error(`WhatsApp API request failed with HTTP ${response.status}.`);
|
|
101
|
-
}
|
|
102
|
-
return parsed;
|
|
103
|
-
}
|
|
104
69
|
function requireMessagingProduct(body) {
|
|
105
70
|
const messagingProduct = readTrimmedString(body.messaging_product);
|
|
106
71
|
if (messagingProduct && messagingProduct !== "whatsapp") {
|
|
@@ -142,122 +107,6 @@ function createWhatsAppMessage(params) {
|
|
|
142
107
|
pushName: params.pushName ?? (params.fromMe ? "Test Bot" : "Test User"),
|
|
143
108
|
};
|
|
144
109
|
}
|
|
145
|
-
function readBaileysTextContent(content) {
|
|
146
|
-
const text = readTrimmedString(content.text) ?? readTrimmedString(content.conversation);
|
|
147
|
-
if (!text) {
|
|
148
|
-
throw new Error("WhatsApp Baileys mock supports text sends only.");
|
|
149
|
-
}
|
|
150
|
-
return text;
|
|
151
|
-
}
|
|
152
|
-
function readResponseMessage(body, fallbackJid) {
|
|
153
|
-
const message = body.message;
|
|
154
|
-
if (message && typeof message === "object") {
|
|
155
|
-
return message;
|
|
156
|
-
}
|
|
157
|
-
const messageId = readTrimmedString(body.messages?.[0]?.id) ??
|
|
158
|
-
readTrimmedString(body.messageId) ??
|
|
159
|
-
"wamid.FAKEUNKNOWN";
|
|
160
|
-
return createWhatsAppMessage({
|
|
161
|
-
fromMe: true,
|
|
162
|
-
id: messageId,
|
|
163
|
-
remoteJid: fallbackJid,
|
|
164
|
-
text: "",
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
function createEventBus() {
|
|
168
|
-
const listeners = new Map();
|
|
169
|
-
return {
|
|
170
|
-
emit(event, payload) {
|
|
171
|
-
const handlers = listeners.get(event);
|
|
172
|
-
if (!handlers?.size) {
|
|
173
|
-
return false;
|
|
174
|
-
}
|
|
175
|
-
for (const handler of handlers) {
|
|
176
|
-
handler(payload);
|
|
177
|
-
}
|
|
178
|
-
return true;
|
|
179
|
-
},
|
|
180
|
-
off(event, handler) {
|
|
181
|
-
listeners.get(event)?.delete(handler);
|
|
182
|
-
},
|
|
183
|
-
on(event, handler) {
|
|
184
|
-
const handlers = listeners.get(event) ?? new Set();
|
|
185
|
-
handlers.add(handler);
|
|
186
|
-
listeners.set(event, handlers);
|
|
187
|
-
},
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
export class WhatsAppBaileysMockRegistry {
|
|
191
|
-
#busesByApiRoot = new Map();
|
|
192
|
-
clear(apiRoot) {
|
|
193
|
-
this.#busesByApiRoot.delete(normalizeApiRoot(apiRoot));
|
|
194
|
-
}
|
|
195
|
-
createSocket(config) {
|
|
196
|
-
const fetchImpl = config.fetch ?? fetch;
|
|
197
|
-
const selfJid = config.selfJid ?? "15550000000@s.whatsapp.net";
|
|
198
|
-
const ev = createEventBus();
|
|
199
|
-
this.register(config.apiRoot, ev);
|
|
200
|
-
return {
|
|
201
|
-
ev,
|
|
202
|
-
async sendMessage(jid, content) {
|
|
203
|
-
const text = readBaileysTextContent(content);
|
|
204
|
-
const body = await postJson({
|
|
205
|
-
accessToken: config.accessToken,
|
|
206
|
-
body: {
|
|
207
|
-
messaging_product: "whatsapp",
|
|
208
|
-
text: { body: text },
|
|
209
|
-
to: jid,
|
|
210
|
-
type: "text",
|
|
211
|
-
},
|
|
212
|
-
fetchImpl,
|
|
213
|
-
url: joinUrl(config.apiRoot, "messages"),
|
|
214
|
-
});
|
|
215
|
-
const message = readResponseMessage(body, jid);
|
|
216
|
-
ev.emit("messages.upsert", { messages: [message], type: "notify" });
|
|
217
|
-
return message;
|
|
218
|
-
},
|
|
219
|
-
async sendPresenceUpdate(presence, jid) {
|
|
220
|
-
await postJson({
|
|
221
|
-
accessToken: config.accessToken,
|
|
222
|
-
body: { ...(jid ? { jid } : {}), presence },
|
|
223
|
-
fetchImpl,
|
|
224
|
-
url: joinUrl(config.apiRoot, "presence"),
|
|
225
|
-
});
|
|
226
|
-
ev.emit("presence.update", { jid, presence });
|
|
227
|
-
},
|
|
228
|
-
user: {
|
|
229
|
-
id: selfJid,
|
|
230
|
-
name: "Test Bot",
|
|
231
|
-
},
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
emitInbound(apiRoot, message) {
|
|
235
|
-
const buses = this.#busesByApiRoot.get(normalizeApiRoot(apiRoot));
|
|
236
|
-
if (!buses?.size) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
const payload = { messages: [message], type: "notify" };
|
|
240
|
-
for (const ev of buses) {
|
|
241
|
-
ev.emit("messages.upsert", payload);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
register(apiRoot, ev) {
|
|
245
|
-
const key = normalizeApiRoot(apiRoot);
|
|
246
|
-
const buses = this.#busesByApiRoot.get(key) ?? new Set();
|
|
247
|
-
buses.add(ev);
|
|
248
|
-
this.#busesByApiRoot.set(key, buses);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
export const DEFAULT_WHATSAPP_BAILEYS_MOCK_REGISTRY = new WhatsAppBaileysMockRegistry();
|
|
252
|
-
export function createWhatsAppBaileysMockSocket(config) {
|
|
253
|
-
const registry = config.registry ?? DEFAULT_WHATSAPP_BAILEYS_MOCK_REGISTRY;
|
|
254
|
-
return registry.createSocket({
|
|
255
|
-
accessToken: config.accessToken,
|
|
256
|
-
apiRoot: config.apiRoot,
|
|
257
|
-
fetch: config.fetch,
|
|
258
|
-
selfJid: config.selfJid,
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
110
|
async function handleSendMessage(params) {
|
|
262
111
|
const productError = requireMessagingProduct(params.body);
|
|
263
112
|
if (productError) {
|
|
@@ -305,7 +154,7 @@ async function handleAdminInbound(params) {
|
|
|
305
154
|
const text = readTrimmedString(params.body.text);
|
|
306
155
|
if (!text) {
|
|
307
156
|
return {
|
|
308
|
-
response: graphParameterError("(#100) Missing required parameter: text", "An inbound WhatsApp
|
|
157
|
+
response: graphParameterError("(#100) Missing required parameter: text", "An inbound WhatsApp event requires text."),
|
|
309
158
|
};
|
|
310
159
|
}
|
|
311
160
|
const message = createWhatsAppMessage({
|
|
@@ -381,7 +230,7 @@ async function handleRequest(params) {
|
|
|
381
230
|
}
|
|
382
231
|
await appendEvent(params.state, event);
|
|
383
232
|
if (result.message) {
|
|
384
|
-
params.state.
|
|
233
|
+
params.state.deliverInboundMessage(result.message);
|
|
385
234
|
}
|
|
386
235
|
return result.response;
|
|
387
236
|
}
|
|
@@ -412,16 +261,16 @@ async function handleRequest(params) {
|
|
|
412
261
|
}
|
|
413
262
|
return new Response("not found", { status: 404 });
|
|
414
263
|
}
|
|
415
|
-
export async function
|
|
264
|
+
export async function startWhatsAppServer(params = {}) {
|
|
416
265
|
const state = {
|
|
417
266
|
accessToken: params.accessToken ?? "crabline-whatsapp-access-token",
|
|
418
267
|
adminToken: params.adminToken ?? randomBytes(24).toString("hex"),
|
|
419
268
|
apiRoot: "",
|
|
420
|
-
|
|
269
|
+
deliverInboundMessage: () => undefined,
|
|
421
270
|
displayPhoneNumber: "15550000000",
|
|
422
271
|
nextMessageId: 1,
|
|
423
272
|
phoneNumberId: "TEST_PHONE_NUMBER_ID",
|
|
424
|
-
recorderPath: params.recorderPath ?? path.resolve(".crabline", "
|
|
273
|
+
recorderPath: params.recorderPath ?? path.resolve(".crabline", "servers", "whatsapp.jsonl"),
|
|
425
274
|
selfJid: params.selfJid ?? "15550000000@s.whatsapp.net",
|
|
426
275
|
};
|
|
427
276
|
const host = params.host ?? "127.0.0.1";
|
|
@@ -433,20 +282,21 @@ export async function startWhatsAppFakeServer(params = {}) {
|
|
|
433
282
|
});
|
|
434
283
|
const baseUrl = httpServer.baseUrl;
|
|
435
284
|
const apiRoot = `${baseUrl}/crabline/whatsapp`;
|
|
285
|
+
const baileysWebSocketUrl = `${baseUrl.replace(/^http/u, "ws")}/crabline/whatsapp/ws/chat?access_token=${encodeURIComponent(state.accessToken)}`;
|
|
436
286
|
state.apiRoot = apiRoot;
|
|
287
|
+
const baileysWebSocketServer = attachWhatsAppBaileysWebSocketServer({
|
|
288
|
+
accessToken: state.accessToken,
|
|
289
|
+
appendEvent: (event) => appendEvent(state, event),
|
|
290
|
+
httpServer: httpServer.server,
|
|
291
|
+
path: "/crabline/whatsapp/ws/chat",
|
|
292
|
+
selfJid: state.selfJid,
|
|
293
|
+
});
|
|
294
|
+
state.deliverInboundMessage = (message) => baileysWebSocketServer.deliverInboundMessage(message);
|
|
437
295
|
return {
|
|
438
296
|
async close() {
|
|
439
|
-
|
|
297
|
+
await baileysWebSocketServer.close();
|
|
440
298
|
await httpServer.close();
|
|
441
299
|
},
|
|
442
|
-
createBaileysMockSocket(config = {}) {
|
|
443
|
-
return state.baileysRegistry.createSocket({
|
|
444
|
-
accessToken: state.accessToken,
|
|
445
|
-
apiRoot,
|
|
446
|
-
selfJid: state.selfJid,
|
|
447
|
-
...config,
|
|
448
|
-
});
|
|
449
|
-
},
|
|
450
300
|
manifest: {
|
|
451
301
|
accessToken: state.accessToken,
|
|
452
302
|
adminToken: state.adminToken,
|
|
@@ -454,6 +304,7 @@ export async function startWhatsAppFakeServer(params = {}) {
|
|
|
454
304
|
endpoints: {
|
|
455
305
|
adminInboundUrl: `${apiRoot}/inbound`,
|
|
456
306
|
apiRoot,
|
|
307
|
+
baileysWebSocketUrl,
|
|
457
308
|
messagesUrl: `${apiRoot}/messages`,
|
|
458
309
|
presenceUrl: `${apiRoot}/presence`,
|
|
459
310
|
},
|
|
@@ -461,6 +312,7 @@ export async function startWhatsAppFakeServer(params = {}) {
|
|
|
461
312
|
CRABLINE_WHATSAPP_ADMIN_TOKEN: state.adminToken,
|
|
462
313
|
CRABLINE_WHATSAPP_ACCESS_TOKEN: state.accessToken,
|
|
463
314
|
CRABLINE_WHATSAPP_API_ROOT: apiRoot,
|
|
315
|
+
CRABLINE_WHATSAPP_BAILEYS_WEB_SOCKET_URL: baileysWebSocketUrl,
|
|
464
316
|
CRABLINE_WHATSAPP_RECORDER_PATH: state.recorderPath,
|
|
465
317
|
CRABLINE_WHATSAPP_SELF_JID: state.selfJid,
|
|
466
318
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../../src/servers/whatsapp.ts"],"names":[],"mappings":"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"}
|
package/docs/channel-setup.md
CHANGED
|
@@ -4,7 +4,7 @@ Crabline is a local mock service for OpenClaw channel contracts. It has two
|
|
|
4
4
|
surfaces:
|
|
5
5
|
|
|
6
6
|
- fixture-level local mocks used directly by the Crabline CLI
|
|
7
|
-
-
|
|
7
|
+
- local provider servers that OpenClaw live adapters can target
|
|
8
8
|
|
|
9
9
|
Live channel testing belongs in OpenClaw's live channel adapters. Crabline
|
|
10
10
|
belongs in deterministic smoke CI and local QA where the test needs
|
|
@@ -70,11 +70,11 @@ Provider credential fields such as `botToken`, `accessToken`, `baseURL`, or
|
|
|
70
70
|
`serverUrl` are optional mock metadata. They are not required for local mock
|
|
71
71
|
execution.
|
|
72
72
|
|
|
73
|
-
##
|
|
73
|
+
## Local Provider Servers
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
Local provider servers sit below OpenClaw's normal channel adapters. QA starts the
|
|
76
76
|
server, writes the emitted runtime manifest into OpenClaw config/env, and then
|
|
77
|
-
OpenClaw talks to the local
|
|
77
|
+
OpenClaw talks to the local provider instead of the public provider.
|
|
78
78
|
|
|
79
79
|
Slack:
|
|
80
80
|
|
|
@@ -145,34 +145,36 @@ crabline --json serve whatsapp --ready-file .crabline/whatsapp-server.json
|
|
|
145
145
|
|
|
146
146
|
Manifest fields:
|
|
147
147
|
|
|
148
|
-
- `endpoints.apiRoot`: Crabline WhatsApp
|
|
149
|
-
- `
|
|
148
|
+
- `endpoints.apiRoot`: Crabline WhatsApp local provider API root
|
|
149
|
+
- `endpoints.baileysWebSocketUrl`: Baileys-compatible WebSocket URL for
|
|
150
|
+
`waWebSocketUrl`, including the local provider access token query parameter
|
|
151
|
+
- `accessToken`: bearer token for local provider requests
|
|
150
152
|
- `adminToken`: value for the `X-Crabline-Admin-Token` header on admin ingress
|
|
151
|
-
- `selfJid`:
|
|
152
|
-
- `env.CRABLINE_WHATSAPP_ACCESS_TOKEN`:
|
|
153
|
-
|
|
154
|
-
- `env.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
- `selfJid`: local authenticated WhatsApp user JID
|
|
154
|
+
- `env.CRABLINE_WHATSAPP_ACCESS_TOKEN`: same value as `accessToken`
|
|
155
|
+
- `env.CRABLINE_WHATSAPP_API_ROOT`: same value as `endpoints.apiRoot`
|
|
156
|
+
- `env.CRABLINE_WHATSAPP_BAILEYS_WEB_SOCKET_URL`: same value as
|
|
157
|
+
`endpoints.baileysWebSocketUrl`
|
|
158
|
+
- `env.CRABLINE_WHATSAPP_RECORDER_PATH`: recorder file for HTTP traffic and
|
|
159
|
+
Baileys WebSocket stanzas
|
|
160
|
+
- `env.CRABLINE_WHATSAPP_SELF_JID`: local authenticated WhatsApp user JID
|
|
159
161
|
- `endpoints.adminInboundUrl`: authenticated admin ingress for test user
|
|
160
|
-
messages
|
|
161
|
-
- `endpoints.messagesUrl`: text send endpoint
|
|
162
|
-
- `endpoints.presenceUrl`: presence endpoint
|
|
163
|
-
- `recorderPath`: JSONL provider traffic recorder
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
162
|
+
messages using the WhatsApp Business webhook payload shape
|
|
163
|
+
- `endpoints.messagesUrl`: text send endpoint for Graph-style callers
|
|
164
|
+
- `endpoints.presenceUrl`: presence endpoint for Graph-style callers
|
|
165
|
+
- `recorderPath`: JSONL provider traffic recorder for HTTP traffic and Baileys
|
|
166
|
+
WebSocket stanzas
|
|
167
|
+
|
|
168
|
+
Pass `endpoints.baileysWebSocketUrl` to Baileys as `waWebSocketUrl` when a
|
|
169
|
+
runtime needs to connect through the local provider. The local server completes
|
|
170
|
+
the Baileys Noise handshake, serves bootstrap/device/prekey queries, and records
|
|
171
|
+
encrypted outbound WebSocket stanzas. The WebSocket endpoint rejects clients
|
|
172
|
+
that do not present the access token embedded in the manifest URL. The admin
|
|
173
|
+
token is generated randomly unless `--admin-token <token>` is provided.
|
|
171
174
|
|
|
172
175
|
OpenClaw bridge callers should post injected user messages with the
|
|
173
176
|
`providerUrl`, `providerHeaders`, and `providerBody` returned by
|
|
174
|
-
`createOpenClawCrablineInbound()`.
|
|
175
|
-
server also exposes `createBaileysMockSocket()`.
|
|
177
|
+
`createOpenClawCrablineInbound()`.
|
|
176
178
|
The admin ingress accepts JSON like:
|
|
177
179
|
|
|
178
180
|
```json
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/crabline",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Standalone CLI for deterministic messaging provider E2E tests",
|
|
5
5
|
"homepage": "https://github.com/openclaw/crabline#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -27,10 +27,6 @@
|
|
|
27
27
|
".": {
|
|
28
28
|
"types": "./dist/src/index.d.ts",
|
|
29
29
|
"import": "./dist/src/index.js"
|
|
30
|
-
},
|
|
31
|
-
"./whatsapp-socket-factory": {
|
|
32
|
-
"types": "./dist/src/fake-servers/whatsapp-socket-factory.d.ts",
|
|
33
|
-
"import": "./dist/src/fake-servers/whatsapp-socket-factory.js"
|
|
34
30
|
}
|
|
35
31
|
},
|
|
36
32
|
"scripts": {
|
|
@@ -53,18 +49,22 @@
|
|
|
53
49
|
"check": "pnpm verify"
|
|
54
50
|
},
|
|
55
51
|
"dependencies": {
|
|
56
|
-
"commander": "^
|
|
52
|
+
"commander": "^15.0.0",
|
|
53
|
+
"curve25519-js": "^0.0.4",
|
|
57
54
|
"picocolors": "^1.1.1",
|
|
55
|
+
"ws": "^8.21.0",
|
|
58
56
|
"yaml": "^2.9.0",
|
|
59
57
|
"zod": "^4.4.3"
|
|
60
58
|
},
|
|
61
59
|
"devDependencies": {
|
|
62
|
-
"@types/node": "^
|
|
63
|
-
"@
|
|
60
|
+
"@types/node": "^26.0.1",
|
|
61
|
+
"@types/ws": "^8.18.1",
|
|
62
|
+
"@typescript/native-preview": "7.0.0-dev.20260629.1",
|
|
64
63
|
"@vitest/coverage-v8": "^4.1.8",
|
|
65
|
-
"
|
|
64
|
+
"baileys": "7.0.0-rc13",
|
|
65
|
+
"oxfmt": "^0.56.0",
|
|
66
66
|
"oxlint": "^1.69.0",
|
|
67
|
-
"oxlint-tsgolint": "^0.
|
|
67
|
+
"oxlint-tsgolint": "^0.23.0",
|
|
68
68
|
"tsx": "^4.22.4",
|
|
69
69
|
"typescript": "^6.0.3",
|
|
70
70
|
"vitest": "^4.1.8"
|