@openclaw/whatsapp 2026.7.1 → 2026.7.2-beta.1
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/{access-control-DYE5dXna.js → access-control-DazDX3RB.js} +4 -4
- package/dist/{account-config-6PTOSfaI.js → account-config-LiT9wWH9.js} +4 -8
- package/dist/{accounts-4YgwroRU.js → accounts-CKOFMPf-.js} +2 -3
- package/dist/{action-runtime-DPahAqxV.js → action-runtime-Bf-12TIH.js} +3 -3
- package/dist/action-runtime-api.js +1 -1
- package/dist/action-runtime.runtime.js +1 -1
- package/dist/{active-listener-B4SDebQ6.js → active-listener-5kHap439.js} +2 -2
- package/dist/{agent-tools-login-BX7eHgDm.js → agent-tools-login-DfyToBpG.js} +1 -4
- package/dist/api.js +17 -18
- package/dist/{approval-handler.runtime-DNWS4aYQ.js → approval-handler.runtime-CBiGQuZ5.js} +19 -13
- package/dist/approval-reactions-BGQoz25s.js +373 -0
- package/dist/{approval-resolver-DF-lu8k5.js → approval-resolver-DoeBBt22.js} +2 -1
- package/dist/{auth-store-Db-wfApd.js → auth-store-BQi9pZqQ.js} +31 -19
- package/dist/call-tool-api.js +6 -14
- package/dist/{channel-BWp7h1uY.js → channel-D_1cK7-w.js} +72 -33
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-react-action-CKJHL_Wf.js → channel-react-action-PoRWfP9x.js} +7 -7
- package/dist/{channel.runtime-CAssfx9p.js → channel.runtime-BPrKzcYd.js} +5 -5
- package/dist/{channel.setup-CURc5rEt.js → channel.setup-eX64WZDx.js} +3 -4
- package/dist/config-schema-BZ8h1hWA.js +40 -0
- package/dist/{connection-controller-DkbrFSIn.js → connection-controller-C1rwfWb4.js} +52 -12
- package/dist/connection-controller-runtime-context-CbTsqmPT.js +14 -0
- package/dist/contract-api.js +2 -2
- package/dist/{directory-config-Dijefxc3.js → directory-config-CLBQrjtC.js} +3 -3
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +89 -4
- package/dist/{group-session-key-BhC1RQOE.js → group-session-key-CLTZeH_F.js} +31 -3
- package/dist/{identity-Dqft3mFA.js → identity-D7L8LCuH.js} +2 -2
- package/dist/light-runtime-api.js +4 -4
- package/dist/{login-C48y0jlx.js → login-DGIoToX8.js} +48 -8
- package/dist/{login-qr-BjId7dll.js → login-qr-X-CZHOk9.js} +6 -7
- package/dist/login-qr-runtime.js +1 -1
- package/dist/{monitor-DD8bXohk.js → monitor-BKtA0lzq.js} +102 -100
- package/dist/normalize-C-Z16y7Q.js +2 -0
- package/dist/{normalize-target-bVWjgftN.js → normalize-target-DSZnHkKF.js} +14 -10
- package/dist/{resolve-outbound-target-CcdugbDf.js → resolve-outbound-target-BR97fAbB.js} +1 -1
- package/dist/runtime-api.js +10 -10
- package/dist/{send-C5CpFcBG.js → send-D9Ydnn4o.js} +25 -320
- package/dist/{send-api-DLlXl8CH.js → send-api-W33lI2nR.js} +28 -88
- package/dist/{session-errors-BAj9D2La.js → session-errors-JuazczrA.js} +2 -1
- package/dist/{session-DriaHt7V.js → session-mxWFn0eS.js} +181 -19
- package/dist/session.runtime-Nsqaehbd.js +16 -0
- package/dist/{setup-core-DH-DFPLY.js → setup-core-BXDFGqky.js} +18 -33
- package/dist/{setup-finalize-c8dl34sO.js → setup-finalize-DzOHXnPj.js} +41 -11
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-DlWb0Z09.js → setup-surface-5EUmMLHS.js} +3 -3
- package/dist/{targets-runtime-C-GiVn6Y.js → targets-runtime-Bsh0HR9y.js} +13 -6
- package/dist/targets.js +1 -1
- package/dist/text-runtime-BTGkMN0o.js +4 -0
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +72 -48
- package/package.json +4 -4
- package/dist/config-schema-mBX2nmn1.js +0 -47
- package/dist/connection-controller-registry-TSX_udJp.js +0 -22
- package/dist/normalize-Bxwqo-bW.js +0 -2
- package/dist/session.runtime-CyooSQvj.js +0 -12
- package/dist/socket-timing-DhbVFjah.js +0 -77
- package/dist/text-runtime-DdX6-mC_.js +0 -4
|
@@ -1,14 +1,86 @@
|
|
|
1
1
|
import { o as resolveWebCredsBackupPath, s as resolveWebCredsPath, t as assertWebCredsPathRegularFileOrMissing } from "./creds-files-B1kSWtBg.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { i as makeWASocket, n as fetchLatestBaileysVersion, o as useMultiFileAuthState, r as makeCacheableSignalKeyStore } from "./session.runtime-CyooSQvj.js";
|
|
2
|
+
import { E as writeWebCredsRawAtomically, S as enqueueCredsSave, T as writeCredsJsonAtomically, b as restoreCredsFromBackupIfNeeded, u as readCredsJsonRaw, w as waitForCredsSaveQueueWithTimeout, y as resolveDefaultWebAuthDir } from "./auth-store-BQi9pZqQ.js";
|
|
3
|
+
import { n as getStatusCode } from "./session-errors-JuazczrA.js";
|
|
4
|
+
import { a as makeWASocket, i as makeCacheableSignalKeyStore, n as createBaileysSignalRepository, r as fetchLatestBaileysVersion, s as useMultiFileAuthState } from "./session.runtime-Nsqaehbd.js";
|
|
6
5
|
import { VERSION, formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
|
|
7
6
|
import { danger, getChildLogger, success, toPinoLikeLogger } from "openclaw/plugin-sdk/runtime-env";
|
|
8
7
|
import { renderQrTerminal } from "openclaw/plugin-sdk/media-runtime";
|
|
9
8
|
import { ensureDir, resolveUserPath } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
9
|
+
import { parseStrictPositiveInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
import { createHttp1EnvHttpProxyAgent, createHttp1ProxyAgent, createNodeProxyAgent } from "openclaw/plugin-sdk/fetch-runtime";
|
|
12
|
+
//#region extensions/whatsapp/src/socket-timing.ts
|
|
13
|
+
const socketSendMessageQueueTails = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
const DEFAULT_WHATSAPP_SOCKET_TIMING = {
|
|
15
|
+
keepAliveIntervalMs: 25e3,
|
|
16
|
+
connectTimeoutMs: 6e4,
|
|
17
|
+
defaultQueryTimeoutMs: 6e4
|
|
18
|
+
};
|
|
19
|
+
var WhatsAppSocketOperationTimeoutError = class extends Error {
|
|
20
|
+
constructor(operation, timeoutMs) {
|
|
21
|
+
super(`WhatsApp socket ${operation} timed out after ${timeoutMs}ms; delivery state is unknown`);
|
|
22
|
+
this.operation = operation;
|
|
23
|
+
this.timeoutMs = timeoutMs;
|
|
24
|
+
this.deliveryState = "unknown";
|
|
25
|
+
this.name = "WhatsAppSocketOperationTimeoutError";
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
function resolveWhatsAppSocketTiming(cfg, overrides) {
|
|
29
|
+
const configured = cfg.web?.whatsapp;
|
|
30
|
+
return {
|
|
31
|
+
keepAliveIntervalMs: parseStrictPositiveInteger(overrides?.keepAliveIntervalMs) ?? parseStrictPositiveInteger(configured?.keepAliveIntervalMs) ?? DEFAULT_WHATSAPP_SOCKET_TIMING.keepAliveIntervalMs,
|
|
32
|
+
connectTimeoutMs: parseStrictPositiveInteger(overrides?.connectTimeoutMs) ?? parseStrictPositiveInteger(configured?.connectTimeoutMs) ?? DEFAULT_WHATSAPP_SOCKET_TIMING.connectTimeoutMs,
|
|
33
|
+
defaultQueryTimeoutMs: parseStrictPositiveInteger(overrides?.defaultQueryTimeoutMs) ?? parseStrictPositiveInteger(configured?.defaultQueryTimeoutMs) ?? DEFAULT_WHATSAPP_SOCKET_TIMING.defaultQueryTimeoutMs
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function isWhatsAppSocketOperationTimeoutError(error) {
|
|
37
|
+
return error instanceof WhatsAppSocketOperationTimeoutError;
|
|
38
|
+
}
|
|
39
|
+
function resolveWhatsAppSocketOperationTimeoutMs(timeoutMs) {
|
|
40
|
+
return resolveTimerTimeoutMs(timeoutMs, DEFAULT_WHATSAPP_SOCKET_TIMING.defaultQueryTimeoutMs);
|
|
41
|
+
}
|
|
42
|
+
async function runSerializedSocketSendMessage(sock, run) {
|
|
43
|
+
const result = (socketSendMessageQueueTails.get(sock) ?? Promise.resolve()).then(run);
|
|
44
|
+
const tail = result.then(() => void 0, () => void 0);
|
|
45
|
+
socketSendMessageQueueTails.set(sock, tail);
|
|
46
|
+
tail.then(() => {
|
|
47
|
+
if (socketSendMessageQueueTails.get(sock) === tail) socketSendMessageQueueTails.delete(sock);
|
|
48
|
+
});
|
|
49
|
+
return await result;
|
|
50
|
+
}
|
|
51
|
+
async function withWhatsAppSocketOperationTimeout(operation, promise, timeoutMs, onTimeout) {
|
|
52
|
+
const resolvedTimeoutMs = resolveWhatsAppSocketOperationTimeoutMs(timeoutMs);
|
|
53
|
+
let timeout = null;
|
|
54
|
+
try {
|
|
55
|
+
return await Promise.race([promise, new Promise((_, reject) => {
|
|
56
|
+
timeout = setTimeout(() => {
|
|
57
|
+
onTimeout?.();
|
|
58
|
+
reject(new WhatsAppSocketOperationTimeoutError(operation, resolvedTimeoutMs));
|
|
59
|
+
}, resolvedTimeoutMs);
|
|
60
|
+
timeout.unref?.();
|
|
61
|
+
})]);
|
|
62
|
+
} finally {
|
|
63
|
+
if (timeout) clearTimeout(timeout);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function createWhatsAppSocketOperationTimeoutAdapter(sock, timeoutMs, hooks) {
|
|
67
|
+
const operationTimeoutMs = resolveWhatsAppSocketOperationTimeoutMs(timeoutMs);
|
|
68
|
+
return {
|
|
69
|
+
sendMessage: (jid, content, options) => {
|
|
70
|
+
return runSerializedSocketSendMessage(sock, () => {
|
|
71
|
+
const send = options ? sock.sendMessage(jid, content, options) : sock.sendMessage(jid, content);
|
|
72
|
+
return withWhatsAppSocketOperationTimeout("sendMessage", send, operationTimeoutMs, hooks?.onSendMessageTimeout ? () => hooks.onSendMessageTimeout?.({
|
|
73
|
+
jid,
|
|
74
|
+
promise: send
|
|
75
|
+
}) : void 0);
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
sendPresenceUpdate: (presence, jid) => {
|
|
79
|
+
return withWhatsAppSocketOperationTimeout("sendPresenceUpdate", jid === void 0 ? sock.sendPresenceUpdate(presence) : sock.sendPresenceUpdate(presence, jid), operationTimeoutMs);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
12
84
|
//#region extensions/whatsapp/src/session.ts
|
|
13
85
|
const LOGGED_OUT_STATUS = 401;
|
|
14
86
|
const WHATSAPP_WEBSOCKET_PROXY_TARGET = "https://mmg.whatsapp.net/";
|
|
@@ -17,29 +89,60 @@ const OPENCLAW_WHATSAPP_WEB_SOCKET_URL_ENV = "OPENCLAW_WHATSAPP_WEB_SOCKET_URL";
|
|
|
17
89
|
async function rejectUnsafeWebCredsPath(authDir) {
|
|
18
90
|
await assertWebCredsPathRegularFileOrMissing(resolveWebCredsPath(authDir));
|
|
19
91
|
}
|
|
20
|
-
function enqueueSaveCreds(authDir, saveCreds, logger) {
|
|
21
|
-
enqueueCredsSave(authDir, () => safeSaveCreds(
|
|
92
|
+
function enqueueSaveCreds(authDir, saveCreds, logger, options) {
|
|
93
|
+
enqueueCredsSave(authDir, () => safeSaveCreds({
|
|
94
|
+
authDir,
|
|
95
|
+
saveCreds,
|
|
96
|
+
logger,
|
|
97
|
+
beforeCredentialPersistence: options?.beforeCredentialPersistence
|
|
98
|
+
}), (err) => {
|
|
22
99
|
logger.warn({ error: String(err) }, "WhatsApp creds save queue error");
|
|
100
|
+
options?.onError?.(err);
|
|
23
101
|
});
|
|
24
102
|
}
|
|
25
|
-
async function safeSaveCreds(
|
|
103
|
+
async function safeSaveCreds(params) {
|
|
104
|
+
let backup;
|
|
26
105
|
try {
|
|
27
|
-
const credsPath = resolveWebCredsPath(authDir);
|
|
28
|
-
const backupPath = resolveWebCredsBackupPath(authDir);
|
|
106
|
+
const credsPath = resolveWebCredsPath(params.authDir);
|
|
107
|
+
const backupPath = resolveWebCredsBackupPath(params.authDir);
|
|
29
108
|
const raw = readCredsJsonRaw(credsPath);
|
|
30
109
|
if (raw) try {
|
|
31
110
|
JSON.parse(raw);
|
|
32
|
-
|
|
33
|
-
filePath: backupPath,
|
|
111
|
+
backup = {
|
|
34
112
|
content: raw,
|
|
113
|
+
filePath: backupPath
|
|
114
|
+
};
|
|
115
|
+
} catch {}
|
|
116
|
+
} catch {}
|
|
117
|
+
if (backup) {
|
|
118
|
+
await params.beforeCredentialPersistence?.();
|
|
119
|
+
try {
|
|
120
|
+
await writeWebCredsRawAtomically({
|
|
121
|
+
filePath: backup.filePath,
|
|
122
|
+
content: backup.content,
|
|
35
123
|
tempPrefix: ".creds.backup"
|
|
36
124
|
});
|
|
37
125
|
} catch {}
|
|
38
|
-
}
|
|
126
|
+
}
|
|
127
|
+
await params.beforeCredentialPersistence?.();
|
|
39
128
|
try {
|
|
40
|
-
await Promise.resolve(saveCreds());
|
|
129
|
+
await Promise.resolve(params.saveCreds());
|
|
41
130
|
} catch (err) {
|
|
42
|
-
logger.warn({ error: String(err) }, "failed saving WhatsApp creds");
|
|
131
|
+
params.logger.warn({ error: String(err) }, "failed saving WhatsApp creds");
|
|
132
|
+
if (params.beforeCredentialPersistence) throw err;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function abortSocketAfterCredentialPersistenceFailure(sock, error) {
|
|
136
|
+
const failure = error instanceof Error ? error : /* @__PURE__ */ new Error("WhatsApp credential persistence rejected");
|
|
137
|
+
const closeWebSocket = () => {
|
|
138
|
+
try {
|
|
139
|
+
sock.ws?.close?.();
|
|
140
|
+
} catch {}
|
|
141
|
+
};
|
|
142
|
+
try {
|
|
143
|
+
sock.end(failure).catch(closeWebSocket);
|
|
144
|
+
} catch {
|
|
145
|
+
closeWebSocket();
|
|
43
146
|
}
|
|
44
147
|
}
|
|
45
148
|
async function printTerminalQr(qr) {
|
|
@@ -70,12 +173,13 @@ async function createWaSocket(printQr, verbose, opts = {}) {
|
|
|
70
173
|
const logger = toPinoLikeLogger(getChildLogger({ module: "baileys" }, { level: verbose ? "info" : "silent" }), verbose ? "info" : "silent");
|
|
71
174
|
const authDir = resolveUserPath(opts.authDir ?? resolveDefaultWebAuthDir());
|
|
72
175
|
await rejectUnsafeWebCredsPath(authDir);
|
|
176
|
+
await opts.beforeCredentialPersistence?.();
|
|
73
177
|
await ensureDir(authDir);
|
|
74
178
|
const sessionLogger = getChildLogger({ module: "web-session" });
|
|
75
179
|
if (await waitForCredsSaveQueueWithTimeout(authDir) === "timed_out") sessionLogger.warn({ authDir }, CREDS_FLUSH_TIMEOUT_MESSAGE);
|
|
76
180
|
else {
|
|
77
181
|
await rejectUnsafeWebCredsPath(authDir);
|
|
78
|
-
await restoreCredsFromBackupIfNeeded(authDir);
|
|
182
|
+
await restoreCredsFromBackupIfNeeded(authDir, { beforeCredentialPersistence: opts.beforeCredentialPersistence });
|
|
79
183
|
}
|
|
80
184
|
await rejectUnsafeWebCredsPath(authDir);
|
|
81
185
|
const { state } = await useMultiFileAuthState(authDir);
|
|
@@ -91,10 +195,62 @@ async function createWaSocket(printQr, verbose, opts = {}) {
|
|
|
91
195
|
connectTimeoutMs: opts.connectTimeoutMs ?? DEFAULT_WHATSAPP_SOCKET_TIMING.connectTimeoutMs,
|
|
92
196
|
defaultQueryTimeoutMs: opts.defaultQueryTimeoutMs ?? DEFAULT_WHATSAPP_SOCKET_TIMING.defaultQueryTimeoutMs
|
|
93
197
|
};
|
|
198
|
+
const socketRef = {};
|
|
199
|
+
let pendingSocketAbort;
|
|
200
|
+
const reportCredentialPersistenceError = (error) => {
|
|
201
|
+
if (socketRef.current) abortSocketAfterCredentialPersistenceFailure(socketRef.current, error);
|
|
202
|
+
else pendingSocketAbort = { error };
|
|
203
|
+
opts.onCredentialPersistenceError?.(error);
|
|
204
|
+
};
|
|
205
|
+
const cachedSignalKeys = makeCacheableSignalKeyStore(opts.beforeCredentialPersistence ? {
|
|
206
|
+
...state.keys,
|
|
207
|
+
async set(data) {
|
|
208
|
+
await opts.beforeCredentialPersistence?.();
|
|
209
|
+
await state.keys.set(data);
|
|
210
|
+
}
|
|
211
|
+
} : state.keys, logger);
|
|
212
|
+
const signalKeys = opts.beforeCredentialPersistence ? {
|
|
213
|
+
...cachedSignalKeys,
|
|
214
|
+
get(type, ids) {
|
|
215
|
+
const task = Promise.resolve(cachedSignalKeys.get(type, ids));
|
|
216
|
+
opts.onCredentialPersistenceTask?.(task);
|
|
217
|
+
return task;
|
|
218
|
+
},
|
|
219
|
+
set(data) {
|
|
220
|
+
const task = (async () => {
|
|
221
|
+
try {
|
|
222
|
+
await cachedSignalKeys.set(data);
|
|
223
|
+
} catch (error) {
|
|
224
|
+
reportCredentialPersistenceError(error);
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
})();
|
|
228
|
+
opts.onCredentialPersistenceTask?.(task);
|
|
229
|
+
return task;
|
|
230
|
+
}
|
|
231
|
+
} : cachedSignalKeys;
|
|
232
|
+
const makeSignalRepository = opts.onCredentialPersistenceTask ? (...args) => {
|
|
233
|
+
const repository = createBaileysSignalRepository(...args);
|
|
234
|
+
const storeLidPnMappings = repository.lidMapping.storeLIDPNMappings.bind(repository.lidMapping);
|
|
235
|
+
repository.lidMapping.storeLIDPNMappings = (...storeArgs) => {
|
|
236
|
+
const task = storeLidPnMappings(...storeArgs);
|
|
237
|
+
opts.onCredentialPersistenceTask?.(task);
|
|
238
|
+
task.then(void 0, reportCredentialPersistenceError);
|
|
239
|
+
return task;
|
|
240
|
+
};
|
|
241
|
+
const migrateSession = repository.migrateSession.bind(repository);
|
|
242
|
+
repository.migrateSession = (...migrateArgs) => {
|
|
243
|
+
const task = migrateSession(...migrateArgs);
|
|
244
|
+
opts.onCredentialPersistenceTask?.(task);
|
|
245
|
+
task.then(void 0, reportCredentialPersistenceError);
|
|
246
|
+
return task;
|
|
247
|
+
};
|
|
248
|
+
return repository;
|
|
249
|
+
} : void 0;
|
|
94
250
|
const sock = makeWASocket({
|
|
95
251
|
auth: {
|
|
96
252
|
creds: state.creds,
|
|
97
|
-
keys:
|
|
253
|
+
keys: signalKeys
|
|
98
254
|
},
|
|
99
255
|
version,
|
|
100
256
|
logger,
|
|
@@ -109,11 +265,17 @@ async function createWaSocket(printQr, verbose, opts = {}) {
|
|
|
109
265
|
...socketTiming,
|
|
110
266
|
agent,
|
|
111
267
|
fetchAgent,
|
|
268
|
+
...makeSignalRepository ? { makeSignalRepository } : {},
|
|
112
269
|
...waWebSocketUrl ? { waWebSocketUrl } : {},
|
|
113
270
|
...opts.getMessage ? { getMessage: opts.getMessage } : {},
|
|
114
271
|
...opts.cachedGroupMetadata ? { cachedGroupMetadata: opts.cachedGroupMetadata } : {}
|
|
115
272
|
});
|
|
116
|
-
|
|
273
|
+
socketRef.current = sock;
|
|
274
|
+
if (pendingSocketAbort) abortSocketAfterCredentialPersistenceFailure(sock, pendingSocketAbort.error);
|
|
275
|
+
sock.ev.on("creds.update", () => enqueueSaveCreds(authDir, saveCreds, sessionLogger, {
|
|
276
|
+
beforeCredentialPersistence: opts.beforeCredentialPersistence,
|
|
277
|
+
onError: reportCredentialPersistenceError
|
|
278
|
+
}));
|
|
117
279
|
sock.ev.on("connection.update", (update) => {
|
|
118
280
|
(async () => {
|
|
119
281
|
try {
|
|
@@ -208,7 +370,7 @@ async function waitForWaConnection(sock, options = { timeout: "none" }) {
|
|
|
208
370
|
}
|
|
209
371
|
if (update.connection === "close") {
|
|
210
372
|
cleanup();
|
|
211
|
-
reject(toLintErrorObject(update.lastDisconnect ?? /* @__PURE__ */ new Error("Connection closed"), "Non-Error rejection"));
|
|
373
|
+
reject(toLintErrorObject(update.lastDisconnect?.error ?? update.lastDisconnect ?? /* @__PURE__ */ new Error("Connection closed"), "Non-Error rejection"));
|
|
212
374
|
}
|
|
213
375
|
};
|
|
214
376
|
sock.ev.on("connection.update", handler);
|
|
@@ -238,4 +400,4 @@ function createConnectionTimeoutError(timeoutMs) {
|
|
|
238
400
|
return error;
|
|
239
401
|
}
|
|
240
402
|
//#endregion
|
|
241
|
-
export {
|
|
403
|
+
export { createWhatsAppSocketOperationTimeoutAdapter as a, resolveWhatsAppSocketTiming as c, DEFAULT_WHATSAPP_SOCKET_TIMING as i, withWhatsAppSocketOperationTimeout as l, newConnectionId as n, isWhatsAppSocketOperationTimeoutError as o, waitForWaConnection as r, resolveWhatsAppSocketOperationTimeoutMs as s, createWaSocket as t, renderQrTerminal as u };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
+
import { BufferJSON, DEFAULT_CONNECTION_CONFIG, fetchLatestBaileysVersion, makeCacheableSignalKeyStore, makeWASocket, useMultiFileAuthState } from "baileys";
|
|
3
|
+
//#region extensions/whatsapp/src/session.runtime.ts
|
|
4
|
+
var session_runtime_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
BufferJSON: () => BufferJSON,
|
|
6
|
+
createBaileysSignalRepository: () => createBaileysSignalRepository,
|
|
7
|
+
fetchLatestBaileysVersion: () => fetchLatestBaileysVersion,
|
|
8
|
+
makeCacheableSignalKeyStore: () => makeCacheableSignalKeyStore,
|
|
9
|
+
makeWASocket: () => makeWASocket,
|
|
10
|
+
useMultiFileAuthState: () => useMultiFileAuthState
|
|
11
|
+
});
|
|
12
|
+
function createBaileysSignalRepository(...args) {
|
|
13
|
+
return DEFAULT_CONNECTION_CONFIG.makeSignalRepository(...args);
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { makeWASocket as a, makeCacheableSignalKeyStore as i, createBaileysSignalRepository as n, session_runtime_exports as o, fetchLatestBaileysVersion as r, useMultiFileAuthState as s, BufferJSON as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as resolveDefaultWhatsAppAccountId, t as listAccountIds } from "./account-ids-CB5SOWjc.js";
|
|
2
|
-
import { a as resolveWhatsAppAccount, n as hasAnyWhatsAppAuth } from "./accounts-
|
|
3
|
-
import { a as normalizeWhatsAppAllowFromEntries } from "./normalize-target-
|
|
4
|
-
import { t as WhatsAppChannelConfigSchema } from "./config-schema-
|
|
2
|
+
import { a as resolveWhatsAppAccount, n as hasAnyWhatsAppAuth } from "./accounts-CKOFMPf-.js";
|
|
3
|
+
import { a as normalizeWhatsAppAllowFromEntries } from "./normalize-target-DSZnHkKF.js";
|
|
4
|
+
import { t as WhatsAppChannelConfigSchema } from "./config-schema-BZ8h1hWA.js";
|
|
5
5
|
import { n as whatsappDoctor } from "./doctor-By3SB4lm.js";
|
|
6
6
|
import { t as resolveWhatsAppConfigPath } from "./group-config-path-BGyzT9Lg.js";
|
|
7
7
|
import { t as resolveLegacyGroupSessionKey } from "./group-session-contract-DDnZSsJ1.js";
|
|
@@ -11,7 +11,7 @@ import { normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-
|
|
|
11
11
|
import { normalizeE164 } from "openclaw/plugin-sdk/account-resolution";
|
|
12
12
|
import { createChannelPluginBase } from "openclaw/plugin-sdk/core";
|
|
13
13
|
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
14
|
-
import { collectOpenGroupPolicyRouteAllowlistWarnings, createAllowlistProviderGroupPolicyWarningCollector,
|
|
14
|
+
import { buildChannelGroupsScopeTree, collectOpenGroupPolicyRouteAllowlistWarnings, createAllowlistProviderGroupPolicyWarningCollector, resolveScopeRequireMention, resolveScopeToolsPolicy } from "openclaw/plugin-sdk/channel-policy";
|
|
15
15
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
16
16
|
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
17
17
|
import { createDelegatedSetupWizardProxy } from "openclaw/plugin-sdk/setup-runtime";
|
|
@@ -22,37 +22,22 @@ function formatWhatsAppConfigAllowFromEntries(allowFrom) {
|
|
|
22
22
|
return normalizeWhatsAppAllowFromEntries(allowFrom);
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|
|
25
|
-
//#region extensions/whatsapp/src/group-intro.ts
|
|
26
|
-
const WHATSAPP_GROUP_INTRO_HINT = "WhatsApp IDs: SenderId is the participant JID (group participant id).";
|
|
27
|
-
function resolveWhatsAppGroupIntroHint() {
|
|
28
|
-
return WHATSAPP_GROUP_INTRO_HINT;
|
|
29
|
-
}
|
|
30
|
-
function resolveWhatsAppMentionStripRegexes(ctx) {
|
|
31
|
-
const selfE164 = (ctx.To ?? "").replace(/^whatsapp:/i, "");
|
|
32
|
-
if (!selfE164) return [];
|
|
33
|
-
const escaped = selfE164.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
34
|
-
return [new RegExp(escaped, "g"), new RegExp(`@${escaped}`, "g")];
|
|
35
|
-
}
|
|
36
|
-
//#endregion
|
|
37
25
|
//#region extensions/whatsapp/src/group-policy.ts
|
|
26
|
+
function resolveScopePath(params) {
|
|
27
|
+
return params.groupId ? [params.groupId] : [];
|
|
28
|
+
}
|
|
38
29
|
function resolveWhatsAppGroupRequireMention(params) {
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
groupId: params.groupId,
|
|
43
|
-
accountId: params.accountId
|
|
30
|
+
return resolveScopeRequireMention({
|
|
31
|
+
tree: buildChannelGroupsScopeTree(params.cfg, "whatsapp", params.accountId),
|
|
32
|
+
path: resolveScopePath(params)
|
|
44
33
|
});
|
|
45
34
|
}
|
|
46
35
|
function resolveWhatsAppGroupToolPolicy(params) {
|
|
47
|
-
return
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
senderId: params.senderId,
|
|
53
|
-
senderName: params.senderName,
|
|
54
|
-
senderUsername: params.senderUsername,
|
|
55
|
-
senderE164: params.senderE164
|
|
36
|
+
return resolveScopeToolsPolicy({
|
|
37
|
+
...params,
|
|
38
|
+
tree: buildChannelGroupsScopeTree(params.cfg, "whatsapp", params.accountId),
|
|
39
|
+
path: resolveScopePath(params),
|
|
40
|
+
messageProvider: "whatsapp"
|
|
56
41
|
});
|
|
57
42
|
}
|
|
58
43
|
//#endregion
|
|
@@ -99,10 +84,10 @@ async function applyWhatsAppSecurityConfigFixes(params) {
|
|
|
99
84
|
//#region extensions/whatsapp/src/shared.ts
|
|
100
85
|
const WHATSAPP_CHANNEL = "whatsapp";
|
|
101
86
|
async function loadWhatsAppChannelRuntime() {
|
|
102
|
-
return await import("./channel.runtime-
|
|
87
|
+
return await import("./channel.runtime-BPrKzcYd.js");
|
|
103
88
|
}
|
|
104
89
|
async function loadWhatsAppSetupSurface() {
|
|
105
|
-
return await import("./setup-surface-
|
|
90
|
+
return await import("./setup-surface-5EUmMLHS.js");
|
|
106
91
|
}
|
|
107
92
|
const whatsappSetupWizardProxy = createWhatsAppSetupWizardProxy(async () => (await loadWhatsAppSetupSurface()).whatsappSetupWizard);
|
|
108
93
|
const whatsappConfigAdapter = createScopedChannelConfigAdapter({
|
|
@@ -333,4 +318,4 @@ const whatsappSetupAdapter = {
|
|
|
333
318
|
}
|
|
334
319
|
};
|
|
335
320
|
//#endregion
|
|
336
|
-
export { resolveWhatsAppGroupRequireMention as a,
|
|
321
|
+
export { resolveWhatsAppGroupRequireMention as a, whatsappSetupWizardProxy as i, createWhatsAppPluginBase as n, resolveWhatsAppGroupToolPolicy as o, loadWhatsAppChannelRuntime as r, formatWhatsAppConfigAllowFromEntries as s, whatsappSetupAdapter as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as resolveDefaultWhatsAppAccountId } from "./account-ids-CB5SOWjc.js";
|
|
2
2
|
import { r as hasWebCredsSync } from "./creds-files-B1kSWtBg.js";
|
|
3
|
-
import { a as resolveWhatsAppAccount, o as resolveWhatsAppAuthDir } from "./accounts-
|
|
4
|
-
import { a as normalizeWhatsAppAllowFromEntries, o as normalizeWhatsAppAllowFromEntry } from "./normalize-target-
|
|
5
|
-
import { t as whatsappSetupAdapter } from "./setup-core-
|
|
3
|
+
import { a as resolveWhatsAppAccount, o as resolveWhatsAppAuthDir } from "./accounts-CKOFMPf-.js";
|
|
4
|
+
import { a as normalizeWhatsAppAllowFromEntries, o as normalizeWhatsAppAllowFromEntry } from "./normalize-target-DSZnHkKF.js";
|
|
5
|
+
import { t as whatsappSetupAdapter } from "./setup-core-BXDFGqky.js";
|
|
6
6
|
import { DEFAULT_ACCOUNT_ID, createSetupTranslator, splitSetupEntries } from "openclaw/plugin-sdk/setup";
|
|
7
7
|
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
|
8
8
|
//#region extensions/whatsapp/src/setup-finalize.ts
|
|
@@ -271,6 +271,15 @@ async function finalizeWhatsAppSetup(params) {
|
|
|
271
271
|
cfg: next,
|
|
272
272
|
accountId
|
|
273
273
|
});
|
|
274
|
+
if (params.options?.deferDeviceLinkToClient) {
|
|
275
|
+
next = await promptWhatsAppDmAccess({
|
|
276
|
+
cfg: next,
|
|
277
|
+
accountId,
|
|
278
|
+
forceAllowFrom: params.forceAllowFrom,
|
|
279
|
+
prompter: params.prompter
|
|
280
|
+
});
|
|
281
|
+
return { cfg: next };
|
|
282
|
+
}
|
|
274
283
|
if (!linked) await params.prompter.note([
|
|
275
284
|
t("wizard.whatsapp.scanQr"),
|
|
276
285
|
t("wizard.whatsapp.credentialsStored", { authDir }),
|
|
@@ -279,14 +288,35 @@ async function finalizeWhatsAppSetup(params) {
|
|
|
279
288
|
if (await params.prompter.confirm({
|
|
280
289
|
message: linked ? t("wizard.whatsapp.relinkPrompt") : t("wizard.whatsapp.linkNowPrompt"),
|
|
281
290
|
initialValue: !linked
|
|
282
|
-
}))
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
291
|
+
})) {
|
|
292
|
+
const reportLoginFailure = async (error) => {
|
|
293
|
+
params.runtime.error(`WhatsApp login failed: ${String(error)}`);
|
|
294
|
+
await params.prompter.note(t("wizard.channels.docs", { link: formatDocsLink("/whatsapp", "whatsapp") }), t("wizard.whatsapp.helpTitle"));
|
|
295
|
+
};
|
|
296
|
+
let loginWeb;
|
|
297
|
+
try {
|
|
298
|
+
({loginWeb} = await import("./login-DGIoToX8.js").then((n) => n.n));
|
|
299
|
+
} catch (error) {
|
|
300
|
+
await reportLoginFailure(error);
|
|
301
|
+
}
|
|
302
|
+
if (loginWeb) {
|
|
303
|
+
let persistenceGuardFailure;
|
|
304
|
+
const beforeCredentialPersistence = params.options?.beforePersistentEffect ? async () => {
|
|
305
|
+
try {
|
|
306
|
+
await params.options?.beforePersistentEffect?.();
|
|
307
|
+
} catch (error) {
|
|
308
|
+
persistenceGuardFailure = { error };
|
|
309
|
+
throw error;
|
|
310
|
+
}
|
|
311
|
+
} : void 0;
|
|
312
|
+
try {
|
|
313
|
+
await loginWeb(false, void 0, params.runtime, accountId, { beforeCredentialPersistence });
|
|
314
|
+
} catch (error) {
|
|
315
|
+
if (persistenceGuardFailure) throw persistenceGuardFailure.error;
|
|
316
|
+
await reportLoginFailure(error);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
} else if (!linked) await params.prompter.note(t("wizard.whatsapp.linkLater", { command: formatCliCommand("openclaw channels login") }), "WhatsApp");
|
|
290
320
|
next = await promptWhatsAppDmAccess({
|
|
291
321
|
cfg: next,
|
|
292
322
|
accountId,
|
package/dist/setup-plugin-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as whatsappSetupPlugin } from "./channel.setup-
|
|
1
|
+
import { t as whatsappSetupPlugin } from "./channel.setup-eX64WZDx.js";
|
|
2
2
|
export { whatsappSetupPlugin };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as listAccountIds } from "./account-ids-CB5SOWjc.js";
|
|
2
|
-
import { o as resolveWhatsAppAuthDir } from "./accounts-
|
|
3
|
-
import { a as formatWhatsAppWebAuthStatusState, h as readWebAuthState } from "./auth-store-
|
|
2
|
+
import { o as resolveWhatsAppAuthDir } from "./accounts-CKOFMPf-.js";
|
|
3
|
+
import { a as formatWhatsAppWebAuthStatusState, h as readWebAuthState } from "./auth-store-BQi9pZqQ.js";
|
|
4
4
|
import { DEFAULT_ACCOUNT_ID, createSetupTranslator, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
|
|
5
5
|
//#region extensions/whatsapp/src/setup-surface.ts
|
|
6
6
|
const t = createSetupTranslator();
|
|
@@ -36,7 +36,7 @@ const whatsappSetupWizard = {
|
|
|
36
36
|
},
|
|
37
37
|
resolveShouldPromptAccountIds: ({ shouldPromptAccountIds }) => shouldPromptAccountIds,
|
|
38
38
|
credentials: [],
|
|
39
|
-
finalize: async (params) => await (await import("./setup-finalize-
|
|
39
|
+
finalize: async (params) => await (await import("./setup-finalize-DzOHXnPj.js")).finalizeWhatsAppSetup(params),
|
|
40
40
|
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false),
|
|
41
41
|
onAccountRecorded: (accountId, options) => {
|
|
42
42
|
options?.onAccountId?.(channel, accountId);
|
|
@@ -71,22 +71,27 @@ async function resolveEquivalentWhatsAppDirectChatJids(jid, opts) {
|
|
|
71
71
|
const pnMatch = normalized.match(DIRECT_PN_JID_RE);
|
|
72
72
|
if (pnMatch) {
|
|
73
73
|
addEquivalentDirectChatCandidate(candidates, await tryLookupMappedJid(() => opts?.lidLookup?.getLIDForPN?.(normalized)));
|
|
74
|
+
const phoneDigits = pnMatch[1];
|
|
75
|
+
const pnDomain = pnMatch[2];
|
|
76
|
+
if (!phoneDigits || !pnDomain) return candidates;
|
|
74
77
|
const mappedLocalLid = readLidForwardMapping({
|
|
75
|
-
phoneDigits
|
|
78
|
+
phoneDigits,
|
|
76
79
|
opts
|
|
77
80
|
});
|
|
78
|
-
const localLidDomain =
|
|
81
|
+
const localLidDomain = pnDomain.toLowerCase() === "hosted" ? "hosted.lid" : "lid";
|
|
79
82
|
addUniqueString(candidates, mappedLocalLid ? `${mappedLocalLid}@${localLidDomain}` : null);
|
|
80
83
|
return candidates;
|
|
81
84
|
}
|
|
82
85
|
const lidMatch = normalized.match(DIRECT_LID_JID_RE);
|
|
83
86
|
if (lidMatch) {
|
|
84
87
|
addEquivalentDirectChatCandidate(candidates, await tryLookupMappedJid(() => opts?.lidLookup?.getPNForLID?.(normalized)));
|
|
88
|
+
const lidDomain = lidMatch[2];
|
|
89
|
+
if (!lidMatch[1] || !lidDomain) return candidates;
|
|
85
90
|
const e164 = jidToE164(normalized, {
|
|
86
91
|
...opts,
|
|
87
92
|
logMissing: false
|
|
88
93
|
});
|
|
89
|
-
addUniqueString(candidates, e164 &&
|
|
94
|
+
addUniqueString(candidates, e164 && lidDomain.toLowerCase() === "hosted.lid" ? `${e164.replace(/\D/g, "")}@hosted` : e164 ? toWhatsappJid(e164) : null);
|
|
90
95
|
}
|
|
91
96
|
return candidates;
|
|
92
97
|
}
|
|
@@ -132,12 +137,14 @@ function readLidForwardMapping(params) {
|
|
|
132
137
|
return null;
|
|
133
138
|
}
|
|
134
139
|
function jidToE164(jid, opts) {
|
|
135
|
-
const
|
|
136
|
-
if (
|
|
140
|
+
const phoneDigits = jid.match(/^(\d+)(?::\d+)?@(s\.whatsapp\.net|hosted)$/)?.[1];
|
|
141
|
+
if (phoneDigits) return `+${phoneDigits}`;
|
|
137
142
|
const lidMatch = jid.match(/^(\d+)(?::\d+)?@(lid|hosted\.lid)$/);
|
|
138
143
|
if (!lidMatch) return null;
|
|
144
|
+
const lid = lidMatch[1];
|
|
145
|
+
if (!lid) return null;
|
|
139
146
|
const phone = readLidReverseMapping({
|
|
140
|
-
lid
|
|
147
|
+
lid,
|
|
141
148
|
opts
|
|
142
149
|
});
|
|
143
150
|
if (phone) return phone;
|
package/dist/targets.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { c as normalizeWhatsAppTarget, r as isWhatsAppUserTarget, t as isWhatsAppGroupJid } from "./normalize-target-
|
|
1
|
+
import { c as normalizeWhatsAppTarget, r as isWhatsAppUserTarget, t as isWhatsAppGroupJid } from "./normalize-target-DSZnHkKF.js";
|
|
2
2
|
export { isWhatsAppGroupJid, isWhatsAppUserTarget, normalizeWhatsAppTarget };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import "./targets-runtime-Bsh0HR9y.js";
|
|
2
|
+
import { convertMarkdownTables, sanitizeAssistantVisibleText, sanitizeAssistantVisibleTextWithProfile, stripToolCallXmlTags } from "openclaw/plugin-sdk/text-chunking";
|
|
3
|
+
import { normalizeE164, resolveUserPath as resolveUserPath$1 } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
4
|
+
export { sanitizeAssistantVisibleTextWithProfile as a, sanitizeAssistantVisibleText as i, normalizeE164 as n, stripToolCallXmlTags as o, resolveUserPath$1 as r, convertMarkdownTables as t };
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/whatsapp",
|
|
3
|
-
"version": "2026.7.1",
|
|
3
|
+
"version": "2026.7.2-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/whatsapp",
|
|
9
|
-
"version": "2026.7.1",
|
|
9
|
+
"version": "2026.7.2-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"audio-decode": "2.2.3",
|
|
12
12
|
"baileys": "7.0.0-rc13",
|
|
13
13
|
"typebox": "1.3.3"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"openclaw": ">=2026.7.1"
|
|
16
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
17
17
|
},
|
|
18
18
|
"peerDependenciesMeta": {
|
|
19
19
|
"openclaw": {
|