@openclaw/whatsapp 2026.9.1 → 2026.9.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/dist/api.js +3 -3
- package/dist/{approval-handler.runtime-C2cpkbpY.js → approval-handler.runtime-DGJEaoqh.js} +1 -1
- package/dist/{approval-reactions-DrZe-NmN.js → approval-reactions-DSFH6Mtx.js} +20 -53
- package/dist/{channel-DebjeuFC.js → channel-BeBrHPVa.js} +3 -7
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-B90_wffD.js → channel.runtime-qi6Zbi9p.js} +2 -2
- package/dist/{channel.setup-D1-jE0aE.js → channel.setup-DhuZ51Kg.js} +1 -1
- package/dist/{monitor-DyPdOPRx.js → monitor-DNGfO3k0.js} +77 -49
- package/dist/runtime-api.js +1 -1
- package/dist/{setup-finalize-C5QtbrWV.js → setup-finalize-Bp-4QnVw.js} +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-WsAzq337.js → setup-surface-B5UnuLT_.js} +1 -1
- package/dist/{shared-BzKxoeKY.js → shared-D6cUWXiq.js} +7 -3
- package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
- package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
- package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
- package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
- package/node_modules/typebox/build/system/memory/create.mjs +3 -4
- package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
- package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
- package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
- package/node_modules/typebox/build/system/memory/update.mjs +3 -2
- package/node_modules/typebox/package.json +1 -1
- package/openclaw.plugin.json +5 -2
- package/package.json +5 -5
package/dist/api.js
CHANGED
|
@@ -4,10 +4,10 @@ import { a as normalizeWhatsAppAllowFromEntries, c as normalizeWhatsAppTarget, i
|
|
|
4
4
|
import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-1GqbT1uX.js";
|
|
5
5
|
import { c as toWhatsappJid, i as markdownToWhatsApp, l as toWhatsappJidWithLid, n as isSelfChatMode, r as jidToE164, s as resolveJidToE164, t as assertWebChannel } from "./targets-runtime-RBjx3pg_.js";
|
|
6
6
|
import { n as resolveUserPath, t as normalizeE164 } from "./text-runtime-DyfmcATV.js";
|
|
7
|
-
import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS, t as whatsappPlugin } from "./channel-
|
|
8
|
-
import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy } from "./shared-
|
|
7
|
+
import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS, t as whatsappPlugin } from "./channel-BeBrHPVa.js";
|
|
8
|
+
import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy } from "./shared-D6cUWXiq.js";
|
|
9
9
|
import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
|
|
10
|
-
import { t as whatsappSetupPlugin } from "./channel.setup-
|
|
10
|
+
import { t as whatsappSetupPlugin } from "./channel.setup-DhuZ51Kg.js";
|
|
11
11
|
import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-C7m81BNe.js";
|
|
12
12
|
import { a as waitForWaConnection, o as DEFAULT_WHATSAPP_SOCKET_TIMING, r as createWaSocket, s as createWhatsAppSocketOperationTimeoutAdapter } from "./socket-close-B3X9uerq.js";
|
|
13
13
|
import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.js";
|
|
@@ -4,7 +4,7 @@ import { s as normalizeWhatsAppMessagingTarget } from "./normalize-target-CugRyO
|
|
|
4
4
|
import { i as sendTypingWhatsApp, t as sendMessageWhatsApp } from "./send-BDDGPxav.js";
|
|
5
5
|
import { i as getWhatsAppRuntime } from "./runtime-BLlToOi6.js";
|
|
6
6
|
import "./normalize-C7Hkc_vE.js";
|
|
7
|
-
import { i as unregisterWhatsAppApprovalReactionTarget, r as registerWhatsAppApprovalReactionTarget } from "./approval-reactions-
|
|
7
|
+
import { i as unregisterWhatsAppApprovalReactionTarget, r as registerWhatsAppApprovalReactionTarget } from "./approval-reactions-DSFH6Mtx.js";
|
|
8
8
|
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
|
9
9
|
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
10
10
|
import { buildApprovalReactionPendingContent } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
@@ -2,9 +2,8 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
|
2
2
|
import { a as resolveWhatsAppAccount } from "./accounts-CiKHiuEe.js";
|
|
3
3
|
import { n as getOptionalWhatsAppRuntime } from "./runtime-BLlToOi6.js";
|
|
4
4
|
import { c as getWhatsAppApprovalApprovers, l as whatsappApprovalAuth } from "./group-session-key-BmVDSPr1.js";
|
|
5
|
-
import { isApprovalNotFoundError } from "openclaw/plugin-sdk/error-runtime";
|
|
6
5
|
import { createLazyRuntimeSurface } from "openclaw/plugin-sdk/lazy-runtime";
|
|
7
|
-
import { approvalReactionDecisionSetsMatch, buildApprovalReactionDeliveredBindingMarker, createApprovalReactionTargetStore, listApprovalReactionBindings, readApprovalReactionDecisionList, readApprovalReactionDeliveredBinding, readApprovalReactionPresentationBinding, resolveTypedApprovalReactionTarget } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
6
|
+
import { approvalReactionDecisionSetsMatch, buildApprovalReactionDeliveredBindingMarker, createApprovalReactionTargetStore, listApprovalReactionBindings, readApprovalReactionDecisionList, readApprovalReactionDeliveredBinding, readApprovalReactionPresentationBinding, readApprovalReactionTargetRecord, resolveTypedApprovalReactionTarget, settleApprovalReaction } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
8
7
|
import { createPluginStateErrorReporter } from "openclaw/plugin-sdk/plugin-state-runtime";
|
|
9
8
|
//#region extensions/whatsapp/src/approval-reactions.ts
|
|
10
9
|
var approval_reactions_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -28,7 +27,7 @@ const whatsappApprovalReactionTargets = createApprovalReactionTargetStore({
|
|
|
28
27
|
defaultTtlMs: DEFAULT_REACTION_TARGET_TTL_MS,
|
|
29
28
|
openStore: (storeParams) => getOptionalWhatsAppRuntime()?.state.openKeyedStore(storeParams),
|
|
30
29
|
logPersistentError: reportPersistentApprovalReactionError,
|
|
31
|
-
readPersistedTarget
|
|
30
|
+
readPersistedTarget: readApprovalReactionTargetRecord
|
|
32
31
|
});
|
|
33
32
|
function buildReactionTargetKey(params) {
|
|
34
33
|
const accountId = params.accountId.trim();
|
|
@@ -52,17 +51,6 @@ function reportApprovalBindingCorrelationMismatch(binding) {
|
|
|
52
51
|
});
|
|
53
52
|
} catch {}
|
|
54
53
|
}
|
|
55
|
-
function readPersistedTarget(target) {
|
|
56
|
-
const value = target;
|
|
57
|
-
if (!value || typeof value.approvalId !== "string" || value.approvalKind !== "exec" && value.approvalKind !== "plugin") return null;
|
|
58
|
-
const allowedDecisions = readApprovalReactionDecisionList(value.allowedDecisions);
|
|
59
|
-
if (!allowedDecisions) return null;
|
|
60
|
-
return {
|
|
61
|
-
approvalId: value.approvalId,
|
|
62
|
-
approvalKind: value.approvalKind,
|
|
63
|
-
allowedDecisions
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
54
|
const APPROVAL_ID_LINE_RE = /^\s*ID:\s*(\S(?:.*\S)?)\s*$/i;
|
|
67
55
|
const APPROVAL_KIND_LINE_RE = /^\s*(?:\S+\s+)?(Exec|Plugin) approval required\s*$/i;
|
|
68
56
|
function visibleApprovalBindingMatches(text, binding) {
|
|
@@ -264,26 +252,8 @@ async function maybeResolveWhatsAppApprovalReaction(params) {
|
|
|
264
252
|
params.logVerboseMessage?.(`whatsapp: approval reaction ignored for ${target.approvalId}; missing actor identity`);
|
|
265
253
|
return true;
|
|
266
254
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
accountId: params.accountId
|
|
270
|
-
}).length === 0) {
|
|
271
|
-
params.logVerboseMessage?.(`whatsapp: approval reaction denied id=${target.approvalId}; reactions require explicit approvers`);
|
|
272
|
-
return true;
|
|
273
|
-
}
|
|
274
|
-
if (!whatsappApprovalAuth.authorizeActorAction({
|
|
275
|
-
cfg: params.cfg,
|
|
276
|
-
accountId: params.accountId,
|
|
277
|
-
senderId: actorId,
|
|
278
|
-
action: "approve",
|
|
279
|
-
approvalKind: target.approvalKind
|
|
280
|
-
}).authorized) {
|
|
281
|
-
params.logVerboseMessage?.(`whatsapp: approval reaction denied id=${target.approvalId} sender=${actorId}`);
|
|
282
|
-
return true;
|
|
283
|
-
}
|
|
284
|
-
const resolveApprovalOverGateway = await loadResolveApprovalOverGateway();
|
|
285
|
-
try {
|
|
286
|
-
const result = await resolveApprovalOverGateway({
|
|
255
|
+
await settleApprovalReaction({
|
|
256
|
+
request: {
|
|
287
257
|
cfg: params.cfg,
|
|
288
258
|
approvalId: target.approvalId,
|
|
289
259
|
approvalKind: target.approvalKind,
|
|
@@ -292,28 +262,25 @@ async function maybeResolveWhatsAppApprovalReaction(params) {
|
|
|
292
262
|
accountId: params.accountId,
|
|
293
263
|
senderId: actorId,
|
|
294
264
|
gatewayUrl: params.gatewayUrl
|
|
295
|
-
}
|
|
296
|
-
|
|
265
|
+
},
|
|
266
|
+
approvers: getWhatsAppApprovalApprovers({
|
|
267
|
+
cfg: params.cfg,
|
|
268
|
+
accountId: params.accountId
|
|
269
|
+
}),
|
|
270
|
+
authorizeActorAction: (input) => whatsappApprovalAuth.authorizeActorAction(input),
|
|
271
|
+
loadResolver: loadResolveApprovalOverGateway,
|
|
272
|
+
clearTarget: () => unregisterWhatsAppApprovalReactionTarget({
|
|
297
273
|
accountId: params.accountId,
|
|
298
274
|
remoteJid: target.remoteJid,
|
|
299
275
|
messageId: event.messageId
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
remoteJid: target.remoteJid,
|
|
309
|
-
messageId: event.messageId
|
|
310
|
-
});
|
|
311
|
-
params.logVerboseMessage?.(`whatsapp: approval reaction ignored for expired approval id=${target.approvalId} sender=${actorId}`);
|
|
312
|
-
return true;
|
|
313
|
-
}
|
|
314
|
-
params.logVerboseMessage?.(`whatsapp: approval reaction failed id=${target.approvalId} sender=${actorId}: ${String(error)}`);
|
|
315
|
-
return true;
|
|
316
|
-
}
|
|
276
|
+
}),
|
|
277
|
+
onResolved: (result) => {
|
|
278
|
+
const canonicalDecision = "decision" in result.approval ? ` decision=${result.approval.decision}` : "";
|
|
279
|
+
params.logVerboseMessage?.(result.applied ? `whatsapp: approval reaction applied id=${target.approvalId} sender=${actorId} status=${result.approval.status}${canonicalDecision}` : `whatsapp: approval reaction already resolved id=${target.approvalId} sender=${actorId} status=${result.approval.status}${canonicalDecision}`);
|
|
280
|
+
},
|
|
281
|
+
logVerboseMessage: params.logVerboseMessage
|
|
282
|
+
});
|
|
283
|
+
return true;
|
|
317
284
|
}
|
|
318
285
|
function clearWhatsAppApprovalReactionTargetsForTest() {
|
|
319
286
|
whatsappApprovalReactionTargets.clearForTest();
|
|
@@ -8,7 +8,7 @@ import "./normalize-C7Hkc_vE.js";
|
|
|
8
8
|
import { c as toWhatsappJid } from "./targets-runtime-RBjx3pg_.js";
|
|
9
9
|
import "./text-runtime-DyfmcATV.js";
|
|
10
10
|
import { c as getWhatsAppApprovalApprovers, l as whatsappApprovalAuth, s as lookupInboundMessageMetaForTarget, t as resolveWhatsAppGroupSessionKey } from "./group-session-key-BmVDSPr1.js";
|
|
11
|
-
import { a as resolveWhatsAppGroupRequireMention, c as loadWhatsAppChannelRuntime, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, s as formatWhatsAppConfigAllowFromEntries, t as createWhatsAppPluginBase } from "./shared-
|
|
11
|
+
import { a as resolveWhatsAppGroupRequireMention, c as loadWhatsAppChannelRuntime, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, s as formatWhatsAppConfigAllowFromEntries, t as createWhatsAppPluginBase } from "./shared-D6cUWXiq.js";
|
|
12
12
|
import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
|
|
13
13
|
import { f as readWebAuthExistsForDecision, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-ZWaclAbd.js";
|
|
14
14
|
import { createActionGate as createActionGate$1 } from "openclaw/plugin-sdk/channel-actions";
|
|
@@ -82,7 +82,7 @@ const whatsappApproval = createApproverRestrictedNativeApprovalCapabilityFromFor
|
|
|
82
82
|
approvalKind,
|
|
83
83
|
request
|
|
84
84
|
}),
|
|
85
|
-
load: async () => (await import("./approval-handler.runtime-
|
|
85
|
+
load: async () => (await import("./approval-handler.runtime-DGJEaoqh.js")).whatsappApprovalNativeRuntime
|
|
86
86
|
})
|
|
87
87
|
});
|
|
88
88
|
function buildWhatsAppPendingPayload(params, approvalKind) {
|
|
@@ -229,10 +229,6 @@ function createWhatsAppOutboundBase({ sendMessageWhatsApp, sendPollWhatsApp, sho
|
|
|
229
229
|
return {
|
|
230
230
|
...outbound,
|
|
231
231
|
sendPayload: async (ctx) => {
|
|
232
|
-
if (ctx.payload.isError === true) return {
|
|
233
|
-
channel: "whatsapp",
|
|
234
|
-
messageId: ""
|
|
235
|
-
};
|
|
236
232
|
const payload = normalizeWhatsAppOutboundPayload(ctx.payload, { normalizeText });
|
|
237
233
|
if (!payload.text && !(payload.mediaUrl || payload.mediaUrls?.length)) {
|
|
238
234
|
if (ctx.payload.interactive || ctx.payload.presentation || ctx.payload.channelData) throw new Error("WhatsApp sendPayload does not support structured-only payloads without text or media.");
|
|
@@ -254,7 +250,7 @@ function createWhatsAppOutboundBase({ sendMessageWhatsApp, sendPollWhatsApp, sho
|
|
|
254
250
|
}
|
|
255
251
|
//#endregion
|
|
256
252
|
//#region extensions/whatsapp/src/channel-outbound.ts
|
|
257
|
-
const loadWhatsAppApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-
|
|
253
|
+
const loadWhatsAppApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-DSFH6Mtx.js").then((n) => n.t));
|
|
258
254
|
const loadWhatsAppQuestionReactionsModule = createLazyRuntimeModule(() => import("./question-reactions-bbe0Qnjn.js").then((n) => n.n));
|
|
259
255
|
function normalizeWhatsAppChannelPayloadText(text) {
|
|
260
256
|
return normalizeWhatsAppPayloadTextPreservingIndentation(text);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as whatsappPlugin } from "./channel-
|
|
1
|
+
import { t as whatsappPlugin } from "./channel-BeBrHPVa.js";
|
|
2
2
|
export { whatsappPlugin };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { startWebLoginWithQr as startWebLoginWithQr$1, waitForWebLogin as waitForWebLogin$1 } from "./login-qr-runtime.js";
|
|
2
2
|
import { c as logoutWeb$1, d as readWebAuthExistsBestEffort$1, f as readWebAuthExistsForDecision$1, g as readWebSelfId$1, h as readWebAuthState$1, m as readWebAuthSnapshotBestEffort$1, o as getWebAuthAgeMs$1, p as readWebAuthSnapshot$1, s as logWebSelfId$1, x as webAuthExists$1 } from "./auth-store-ZWaclAbd.js";
|
|
3
3
|
import { t as getActiveWebListener$1 } from "./active-listener-BEjWsCNM.js";
|
|
4
|
-
import { t as monitorWebChannel$1 } from "./monitor-
|
|
4
|
+
import { t as monitorWebChannel$1 } from "./monitor-DNGfO3k0.js";
|
|
5
5
|
import { t as loginWeb$1 } from "./login-6j2iP9nR.js";
|
|
6
|
-
import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-
|
|
6
|
+
import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-B5UnuLT_.js";
|
|
7
7
|
//#region extensions/whatsapp/src/channel.runtime.ts
|
|
8
8
|
function getActiveWebListener(...args) {
|
|
9
9
|
return getActiveWebListener$1(...args);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, t as createWhatsAppPluginBase } from "./shared-
|
|
1
|
+
import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, t as createWhatsAppPluginBase } from "./shared-D6cUWXiq.js";
|
|
2
2
|
//#region extensions/whatsapp/src/channel.setup.ts
|
|
3
3
|
const whatsappSetupPlugin = { ...createWhatsAppPluginBase({
|
|
4
4
|
groups: {
|
|
@@ -13,7 +13,7 @@ import { t as BufferJSON } from "./session.runtime-Nsqaehbd.js";
|
|
|
13
13
|
import { _ as resolveInboundMediaMimetype, a as addWhatsAppImagePreviewFields, c as extractContextInfo, d as extractMediaKind, f as extractMentionedJids, g as projectWhatsAppInboundMessage, h as hasInboundUserContent, i as resolveWhatsAppOutboundMentions, l as extractExternalAdReplyContext, n as addWhatsAppOutboundMentionsToContent, o as describeReplyContext, p as extractText, r as mayContainWhatsAppOutboundMention, s as extractContactContext, t as createWebSendApi, u as extractLocationData } from "./send-api-C_Zn4Ij-.js";
|
|
14
14
|
import { t as resolveWhatsAppRuntimeGroupPolicy } from "./runtime-group-policy-DeSRFXEV.js";
|
|
15
15
|
import { c as computeBackoff, d as resolveReconnectPolicy, f as sleepWithAbort, l as newConnectionId, n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController, s as DEFAULT_RECONNECT_POLICY, u as resolveHeartbeatSeconds } from "./connection-controller-DNp6U1NN.js";
|
|
16
|
-
import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-
|
|
16
|
+
import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-DSFH6Mtx.js";
|
|
17
17
|
import { t as maybeResolveWhatsAppQuestionReaction } from "./question-reactions-bbe0Qnjn.js";
|
|
18
18
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
19
19
|
import { createAckReactionHandle, createStatusReactionController, logAckFailure, removeAckReactionHandleAfterReply, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
@@ -40,12 +40,12 @@ import { createHash } from "node:crypto";
|
|
|
40
40
|
import { resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
41
41
|
import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
|
|
42
42
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
|
|
43
|
-
import { createInboundDebouncer, resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound-debounce";
|
|
44
43
|
import { drainPendingDeliveries } from "openclaw/plugin-sdk/delivery-queue-runtime";
|
|
45
44
|
import { DEFAULT_GROUP_HISTORY_LIMIT, buildHistoryContextFromEntries, buildInboundHistoryFromEntries, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
46
45
|
import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
|
|
47
46
|
import { fanInChannelIngressLifecycles, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
48
47
|
import { getSessionEntry, patchSessionEntry, resolveGroupSessionKey, resolveStorePath, resolveStorePath as resolveStorePath$1, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
|
|
48
|
+
import { createInboundDebouncer, resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound-debounce";
|
|
49
49
|
import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
|
|
50
50
|
import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
|
51
51
|
import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
|
|
@@ -529,10 +529,10 @@ function createWhatsAppGroupMetadataCacheOwner(params) {
|
|
|
529
529
|
const listen = (event, listener) => {
|
|
530
530
|
detachListeners.push(params.listen(event, listener));
|
|
531
531
|
};
|
|
532
|
-
listen("groups.upsert", (
|
|
532
|
+
listen("groups.upsert", (groups) => {
|
|
533
533
|
for (const group of groups) if (group.id) rememberFullUpdate(group.id, group);
|
|
534
|
-
})
|
|
535
|
-
listen("groups.update", (
|
|
534
|
+
});
|
|
535
|
+
listen("groups.update", (updates) => {
|
|
536
536
|
for (const update of updates) {
|
|
537
537
|
if (!update.id) continue;
|
|
538
538
|
if (typeof update.subject === "string" && Array.isArray(update.participants)) {
|
|
@@ -541,10 +541,10 @@ function createWhatsAppGroupMetadataCacheOwner(params) {
|
|
|
541
541
|
}
|
|
542
542
|
forgetFullMetadata(update.id);
|
|
543
543
|
}
|
|
544
|
-
})
|
|
545
|
-
listen("group-participants.update", (
|
|
544
|
+
});
|
|
545
|
+
listen("group-participants.update", (update) => {
|
|
546
546
|
forgetFullMetadata(update.id);
|
|
547
|
-
})
|
|
547
|
+
});
|
|
548
548
|
(async () => {
|
|
549
549
|
try {
|
|
550
550
|
const groups = await params.sock.groupFetchAllParticipating();
|
|
@@ -578,13 +578,7 @@ function createWhatsAppGroupMetadataCacheOwner(params) {
|
|
|
578
578
|
//#region extensions/whatsapp/src/inbound/lifecycle.ts
|
|
579
579
|
function attachEmitterListener(emitter, event, listener) {
|
|
580
580
|
emitter.on(event, listener);
|
|
581
|
-
return () =>
|
|
582
|
-
if (typeof emitter.off === "function") {
|
|
583
|
-
emitter.off(event, listener);
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
if (typeof emitter.removeListener === "function") emitter.removeListener(event, listener);
|
|
587
|
-
};
|
|
581
|
+
return () => emitter.off(event, listener);
|
|
588
582
|
}
|
|
589
583
|
function closeInboundMonitorSocket(sock) {
|
|
590
584
|
if (typeof sock.end === "function") {
|
|
@@ -606,7 +600,6 @@ function resolveWhatsAppIngressLifecycle(message) {
|
|
|
606
600
|
//#endregion
|
|
607
601
|
//#region extensions/whatsapp/src/inbound/message-debounce.ts
|
|
608
602
|
function createWhatsAppInboundMessageDebouncer(options) {
|
|
609
|
-
const debounceMs = Math.max(0, Math.trunc(options.debounceMs ?? 0));
|
|
610
603
|
const pendingKeys = /* @__PURE__ */ new Map();
|
|
611
604
|
const activeFlushes = /* @__PURE__ */ new Set();
|
|
612
605
|
const workWaiters = /* @__PURE__ */ new Set();
|
|
@@ -636,7 +629,8 @@ function createWhatsAppInboundMessageDebouncer(options) {
|
|
|
636
629
|
return timestampDiff !== 0 ? timestampDiff : (a.receiveOrder ?? 0) - (b.receiveOrder ?? 0);
|
|
637
630
|
});
|
|
638
631
|
const debouncer = createInboundDebouncer({
|
|
639
|
-
debounceMs,
|
|
632
|
+
debounceMs: options.resolveDebounceMs(),
|
|
633
|
+
resolveDebounceMs: (entry) => entry.debounceMs,
|
|
640
634
|
buildKey: (msg) => msg.debounceKey ?? buildKey(msg),
|
|
641
635
|
shouldDebounce,
|
|
642
636
|
onFlush: (entries, createFlush) => {
|
|
@@ -702,11 +696,15 @@ function createWhatsAppInboundMessageDebouncer(options) {
|
|
|
702
696
|
},
|
|
703
697
|
onError: options.onError
|
|
704
698
|
});
|
|
705
|
-
const enqueue = async (
|
|
699
|
+
const enqueue = async (input) => {
|
|
700
|
+
const message = {
|
|
701
|
+
...input,
|
|
702
|
+
debounceMs: options.resolveDebounceMs()
|
|
703
|
+
};
|
|
706
704
|
const key = buildKey(message);
|
|
707
705
|
if (key) {
|
|
708
706
|
message.debounceKey = key;
|
|
709
|
-
if (debounceMs > 0 && shouldDebounce(message)) {
|
|
707
|
+
if (message.debounceMs > 0 && shouldDebounce(message)) {
|
|
710
708
|
message.debounceKeyTracked = true;
|
|
711
709
|
trackKey(key);
|
|
712
710
|
options.onPendingWorkChanged();
|
|
@@ -1184,7 +1182,11 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1184
1182
|
await maybeMarkInboundAsRead(target);
|
|
1185
1183
|
};
|
|
1186
1184
|
const messageDebouncer = createWhatsAppInboundMessageDebouncer({
|
|
1187
|
-
|
|
1185
|
+
resolveDebounceMs: () => resolveInboundDebounceMs({
|
|
1186
|
+
cfg: options.loadConfig?.() ?? options.cfg,
|
|
1187
|
+
channel: "whatsapp",
|
|
1188
|
+
overrideMs: options.debounceMs
|
|
1189
|
+
}),
|
|
1188
1190
|
onMessage: options.onMessage,
|
|
1189
1191
|
shouldDebounce: options.shouldDebounce,
|
|
1190
1192
|
markRead: maybeMarkInboundAsRead,
|
|
@@ -1340,6 +1342,16 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1340
1342
|
const preparation = durableId ? preparedInboundByDurableId.get(durableId) : void 0;
|
|
1341
1343
|
if (durableId) preparedInboundByDurableId.delete(durableId);
|
|
1342
1344
|
if (context.skipRecentOutboundEcho === true) return "completed";
|
|
1345
|
+
if (await maybeResolveWhatsAppApprovalReaction({
|
|
1346
|
+
cfg: options.loadConfig?.() ?? options.cfg,
|
|
1347
|
+
accountId: options.accountId,
|
|
1348
|
+
msg,
|
|
1349
|
+
selfJid: self.jid,
|
|
1350
|
+
selfLid: self.lid,
|
|
1351
|
+
resolveInboundJid,
|
|
1352
|
+
resolveReactionTargetJids,
|
|
1353
|
+
logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
|
|
1354
|
+
})) return "completed";
|
|
1343
1355
|
const prepared = await preparation;
|
|
1344
1356
|
if (prepared === null) return "completed";
|
|
1345
1357
|
const inbound = prepared ?? await normalizeInboundMessage(msg);
|
|
@@ -1392,16 +1404,22 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1392
1404
|
for (const msg of upsert.messages ?? []) {
|
|
1393
1405
|
rememberBaileysMessage(msg.key?.remoteJid, msg.key?.id, msg.message);
|
|
1394
1406
|
const receiveOrder = nextReceiveOrder++;
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1407
|
+
let approvalReactionResolved = false;
|
|
1408
|
+
try {
|
|
1409
|
+
approvalReactionResolved = await maybeResolveWhatsAppApprovalReaction({
|
|
1410
|
+
cfg: options.loadConfig?.() ?? options.cfg,
|
|
1411
|
+
accountId: options.accountId,
|
|
1412
|
+
msg,
|
|
1413
|
+
selfJid: self.jid,
|
|
1414
|
+
selfLid: self.lid,
|
|
1415
|
+
resolveInboundJid,
|
|
1416
|
+
resolveReactionTargetJids,
|
|
1417
|
+
logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
|
|
1418
|
+
});
|
|
1419
|
+
} catch (error) {
|
|
1420
|
+
inboundLogger.warn({ error: formatError(error) }, "whatsapp approval reaction resolution failed; admitting reaction for durable replay");
|
|
1421
|
+
}
|
|
1422
|
+
if (approvalReactionResolved) continue;
|
|
1405
1423
|
const receivedAt = Date.now();
|
|
1406
1424
|
const skipStaleAppend = shouldSkipStaleAppend(msg, upsert.type);
|
|
1407
1425
|
const skipRecentOutboundEcho = shouldSkipRecentOutboundEcho(msg);
|
|
@@ -2415,7 +2433,11 @@ async function applyGroupGating(params) {
|
|
|
2415
2433
|
const conversationGroupPolicy = inboundPolicy.resolveConversationGroupPolicy(conversationId);
|
|
2416
2434
|
if (conversationGroupPolicy.allowlistEnabled && !conversationGroupPolicy.allowed) {
|
|
2417
2435
|
const accountId = inboundPolicy.account.accountId;
|
|
2418
|
-
if (shouldWarnForGroupDrop(
|
|
2436
|
+
if (shouldWarnForGroupDrop(JSON.stringify([
|
|
2437
|
+
accountId,
|
|
2438
|
+
conversationId,
|
|
2439
|
+
"group registry"
|
|
2440
|
+
]))) {
|
|
2419
2441
|
const groupsPath = resolveWhatsAppGroupsConfigPath({
|
|
2420
2442
|
cfg: params.cfg,
|
|
2421
2443
|
accountId
|
|
@@ -2504,6 +2526,22 @@ async function applyGroupGating(params) {
|
|
|
2504
2526
|
needsMentionText: true
|
|
2505
2527
|
};
|
|
2506
2528
|
}
|
|
2529
|
+
const accountId = inboundPolicy.account.accountId;
|
|
2530
|
+
if (shouldWarnForGroupDrop(JSON.stringify([
|
|
2531
|
+
accountId,
|
|
2532
|
+
conversationId,
|
|
2533
|
+
"no mention"
|
|
2534
|
+
]))) {
|
|
2535
|
+
const groupsPath = resolveWhatsAppGroupsConfigPath({
|
|
2536
|
+
cfg: params.cfg,
|
|
2537
|
+
accountId
|
|
2538
|
+
});
|
|
2539
|
+
params.replyLogger.warn({
|
|
2540
|
+
conversationId,
|
|
2541
|
+
accountId,
|
|
2542
|
+
groupsPath
|
|
2543
|
+
}, `WhatsApp group ${conversationId}: skipping messages without a mention. Mention patterns can be derived from the agent identity name. Use /activation always for this session, or set ${groupsPath}[${JSON.stringify(conversationId)}].requireMention=false for the default. Preserve existing groups entries; when adding the first groups map, include "*": {} to keep other chats admitted.`);
|
|
2544
|
+
}
|
|
2507
2545
|
const pendingHistoryBody = params.mentionText === void 0 ? void 0 : formatAudioTranscriptForAgent(params.mentionText);
|
|
2508
2546
|
return skipGroupMessageAndStoreHistory(params, `Group message stored for context (no mention detected) in ${conversationId}: ${mentionMsg.payload.body}`, pendingHistoryBody);
|
|
2509
2547
|
}
|
|
@@ -2552,21 +2590,15 @@ function resolvePeerId(msg) {
|
|
|
2552
2590
|
}
|
|
2553
2591
|
//#endregion
|
|
2554
2592
|
//#region extensions/whatsapp/src/system-prompt.ts
|
|
2593
|
+
function resolveWhatsAppSystemPrompt(prompts, targetId) {
|
|
2594
|
+
if (!targetId) return;
|
|
2595
|
+
return (prompts?.[targetId]?.systemPrompt ?? prompts?.["*"]?.systemPrompt)?.trim() || void 0;
|
|
2596
|
+
}
|
|
2555
2597
|
function resolveWhatsAppGroupSystemPrompt(params) {
|
|
2556
|
-
|
|
2557
|
-
const groups = params.accountConfig?.groups;
|
|
2558
|
-
const specific = groups?.[params.groupId];
|
|
2559
|
-
if (specific != null && specific.systemPrompt != null) return specific.systemPrompt.trim() || void 0;
|
|
2560
|
-
const wildcard = groups?.["*"]?.systemPrompt;
|
|
2561
|
-
return wildcard != null ? wildcard.trim() || void 0 : void 0;
|
|
2598
|
+
return resolveWhatsAppSystemPrompt(params.accountConfig?.groups, params.groupId);
|
|
2562
2599
|
}
|
|
2563
2600
|
function resolveWhatsAppDirectSystemPrompt(params) {
|
|
2564
|
-
|
|
2565
|
-
const direct = params.accountConfig?.direct;
|
|
2566
|
-
const specific = direct?.[params.peerId];
|
|
2567
|
-
if (specific != null && specific.systemPrompt != null) return specific.systemPrompt.trim() || void 0;
|
|
2568
|
-
const wildcard = direct?.["*"]?.systemPrompt;
|
|
2569
|
-
return wildcard != null ? wildcard.trim() || void 0 : void 0;
|
|
2601
|
+
return resolveWhatsAppSystemPrompt(params.accountConfig?.direct, params.peerId);
|
|
2570
2602
|
}
|
|
2571
2603
|
//#endregion
|
|
2572
2604
|
//#region extensions/whatsapp/src/outbound-retry.ts
|
|
@@ -3071,7 +3103,7 @@ function resolveWhatsAppDurableReplyToId(params) {
|
|
|
3071
3103
|
}
|
|
3072
3104
|
function resolveWhatsAppDeliverablePayload(payload, info) {
|
|
3073
3105
|
if (payload.isReasoning === true || payload.isCompactionNotice === true) return null;
|
|
3074
|
-
if (payload.isError === true) return null;
|
|
3106
|
+
if (payload.isError === true && info.kind !== "final") return null;
|
|
3075
3107
|
if (info.kind === "tool") {
|
|
3076
3108
|
if (!resolveSendableOutboundReplyParts(payload).hasMedia) return null;
|
|
3077
3109
|
return {
|
|
@@ -4348,10 +4380,6 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
|
|
|
4348
4380
|
while (true) {
|
|
4349
4381
|
if (stopRequested()) break;
|
|
4350
4382
|
const connectionId = newConnectionId();
|
|
4351
|
-
const inboundDebounceMs = resolveInboundDebounceMs({
|
|
4352
|
-
cfg,
|
|
4353
|
-
channel: "whatsapp"
|
|
4354
|
-
});
|
|
4355
4383
|
const shouldDebounce = (msg) => shouldDebounceTextInbound({
|
|
4356
4384
|
text: msg.payload.commandBody ?? msg.payload.body,
|
|
4357
4385
|
cfg,
|
|
@@ -4396,7 +4424,7 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
|
|
|
4396
4424
|
selfChatMode: account.selfChatMode,
|
|
4397
4425
|
sendReadReceipts: account.sendReadReceipts,
|
|
4398
4426
|
socketTiming,
|
|
4399
|
-
debounceMs:
|
|
4427
|
+
debounceMs: tuning.debounceMs,
|
|
4400
4428
|
appendReplyWindow: connectionLocal.openedAfterRecentInbound ? {
|
|
4401
4429
|
afterMs: connectionLocal.startedAt - reconnectCatchUpWindowMs,
|
|
4402
4430
|
untilMs: connectionLocal.startedAt + reconnectCatchUpWindowMs,
|
package/dist/runtime-api.js
CHANGED
|
@@ -10,7 +10,7 @@ import { n as resolveWebAccountId, t as getActiveWebListener } from "./active-li
|
|
|
10
10
|
import { a as waitForWaConnection, i as newConnectionId, r as createWaSocket } from "./socket-close-B3X9uerq.js";
|
|
11
11
|
import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.js";
|
|
12
12
|
import { p as extractText, s as extractContactContext, u as extractLocationData } from "./send-api-C_Zn4Ij-.js";
|
|
13
|
-
import { a as loadWebMediaRaw, c as monitorWebInbox, i as loadWebMedia, l as resetWebInboundDedupe, n as LocalMediaAccessError, o as optimizeImageToJpeg, r as getDefaultLocalRoots, s as optimizeImageToPng, t as monitorWebChannel } from "./monitor-
|
|
13
|
+
import { a as loadWebMediaRaw, c as monitorWebInbox, i as loadWebMedia, l as resetWebInboundDedupe, n as LocalMediaAccessError, o as optimizeImageToJpeg, r as getDefaultLocalRoots, s as optimizeImageToPng, t as monitorWebChannel } from "./monitor-DNGfO3k0.js";
|
|
14
14
|
import { t as loginWeb } from "./login-6j2iP9nR.js";
|
|
15
15
|
import { HEARTBEAT_PROMPT, HEARTBEAT_TOKEN, SILENT_REPLY_TOKEN, stripHeartbeatToken } from "openclaw/plugin-sdk/reply-runtime";
|
|
16
16
|
export { DEFAULT_WEB_MEDIA_BYTES, HEARTBEAT_PROMPT, HEARTBEAT_TOKEN, LocalMediaAccessError, SILENT_REPLY_TOKEN, WA_WEB_AUTH_DIR, WHATSAPP_AUTH_UNSTABLE_CODE, WhatsAppAuthUnstableError, createWaSocket, createWhatsAppLoginTool, extractContactContext, extractLocationData, extractText, formatError, formatWhatsAppWebAuthStatusState, getActiveWebListener, getDefaultLocalRoots, getStatusCode, getWebAuthAgeMs, handleWhatsAppAction, hasWebCredsSync, loadWebMedia, loadWebMediaRaw, logWebSelfId, loginWeb, logoutWeb, monitorWebChannel, monitorWebInbox, newConnectionId, optimizeImageToJpeg, optimizeImageToPng, pickWebChannel, readCredsJsonRaw, readWebAuthExistsBestEffort, readWebAuthExistsForDecision, readWebAuthSnapshot, readWebAuthSnapshotBestEffort, readWebAuthState, readWebSelfId, readWebSelfIdentity, readWebSelfIdentityForDecision, resetWebInboundDedupe, resolveDefaultWebAuthDir, resolveWebAccountId, resolveWebCredsBackupPath, resolveWebCredsPath, restoreCredsFromBackupIfNeeded, sendMessageWhatsApp, sendPollWhatsApp, sendReactionWhatsApp, sendTypingWhatsApp, setWhatsAppRuntime, startWebLoginWithQr, stripHeartbeatToken, waitForCredsSaveQueue, waitForCredsSaveQueueWithTimeout, waitForWaConnection, waitForWebLogin, webAuthExists, whatsAppActionRuntime, writeCredsJsonAtomically };
|
|
@@ -2,7 +2,7 @@ import { a as resolveWhatsAppAccount, o as resolveWhatsAppAuthDir } from "./acco
|
|
|
2
2
|
import { r as resolveDefaultWhatsAppAccountId } from "./account-ids-CB5SOWjc.js";
|
|
3
3
|
import { r as hasWebCredsSync } from "./creds-files-Drg3usj1.js";
|
|
4
4
|
import { a as normalizeWhatsAppAllowFromEntries, o as normalizeWhatsAppAllowFromEntry } from "./normalize-target-CugRyONv.js";
|
|
5
|
-
import { r as whatsappSetupAdapter } from "./shared-
|
|
5
|
+
import { r as whatsappSetupAdapter } from "./shared-D6cUWXiq.js";
|
|
6
6
|
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
|
7
7
|
import { DEFAULT_ACCOUNT_ID, createSetupTranslator, splitSetupEntries } from "openclaw/plugin-sdk/setup";
|
|
8
8
|
//#region extensions/whatsapp/src/setup-finalize.ts
|
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-DhuZ51Kg.js";
|
|
2
2
|
export { whatsappSetupPlugin };
|
|
@@ -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-Bp-4QnVw.js")).finalizeWhatsAppSetup(params),
|
|
40
40
|
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false),
|
|
41
41
|
onAccountRecorded: (accountId, options) => {
|
|
42
42
|
options?.onAccountId?.(channel, accountId);
|
|
@@ -27,7 +27,7 @@ async function readWhatsAppAccountLinkState(authDir) {
|
|
|
27
27
|
}
|
|
28
28
|
const loadWhatsAppChannelRuntime = createLazyRuntimeModule(async () => {
|
|
29
29
|
await loadWhatsAppAuthStore();
|
|
30
|
-
return await import("./channel.runtime-
|
|
30
|
+
return await import("./channel.runtime-qi6Zbi9p.js");
|
|
31
31
|
});
|
|
32
32
|
//#endregion
|
|
33
33
|
//#region extensions/whatsapp/src/config-accessors.ts
|
|
@@ -116,7 +116,7 @@ async function applyWhatsAppSecurityConfigFixes(params) {
|
|
|
116
116
|
//#region extensions/whatsapp/src/shared.ts
|
|
117
117
|
const WHATSAPP_CHANNEL = "whatsapp";
|
|
118
118
|
async function loadWhatsAppSetupSurface() {
|
|
119
|
-
return await import("./setup-surface-
|
|
119
|
+
return await import("./setup-surface-B5UnuLT_.js");
|
|
120
120
|
}
|
|
121
121
|
const whatsappSetupWizardProxy = createWhatsAppSetupWizardProxy(async () => (await loadWhatsAppSetupSurface()).whatsappSetupWizard);
|
|
122
122
|
const whatsappConfigAdapter = createScopedChannelConfigAdapter({
|
|
@@ -252,7 +252,11 @@ function createWhatsAppPluginBase(params) {
|
|
|
252
252
|
"channels.whatsapp.accounts",
|
|
253
253
|
"channels.whatsapp.selfChatMode"
|
|
254
254
|
],
|
|
255
|
-
noopPrefixes: [
|
|
255
|
+
noopPrefixes: [
|
|
256
|
+
"channels.whatsapp",
|
|
257
|
+
"messages.inbound",
|
|
258
|
+
"messages.ackReactionScope"
|
|
259
|
+
]
|
|
256
260
|
},
|
|
257
261
|
gatewayMethodDescriptors: [{ name: "web.login.start" }, { name: "web.login.wait" }],
|
|
258
262
|
configSchema: WhatsAppChannelConfigSchema,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns true if the value is a json pointer
|
|
3
|
-
* @specification
|
|
4
|
-
* @source ajv-formats
|
|
3
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc6901
|
|
4
|
+
* @source https://github.com/ajv-validator/ajv-formats
|
|
5
5
|
*/
|
|
6
6
|
export declare function IsJsonPointer(value: string): boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const JsonPointer = /^(?:\/(?:[^~/]|~0|~1)*)*$/;
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is a json pointer
|
|
4
|
-
* @specification
|
|
5
|
-
* @source ajv-formats
|
|
4
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc6901
|
|
5
|
+
* @source https://github.com/ajv-validator/ajv-formats
|
|
6
6
|
*/
|
|
7
7
|
export function IsJsonPointer(value) {
|
|
8
8
|
return JsonPointer.test(value);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns true if the value is a json pointer uri fragment
|
|
3
|
-
* @specification
|
|
4
|
-
* @source ajv-formats
|
|
3
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc6901
|
|
4
|
+
* @source https://github.com/ajv-validator/ajv-formats
|
|
5
5
|
*/
|
|
6
6
|
export declare function IsJsonPointerUriFragment(value: string): boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const JsonPointerUriFragment = /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i;
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is a json pointer uri fragment
|
|
4
|
-
* @specification
|
|
5
|
-
* @source ajv-formats
|
|
4
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc6901
|
|
5
|
+
* @source https://github.com/ajv-validator/ajv-formats
|
|
6
6
|
*/
|
|
7
7
|
export function IsJsonPointerUriFragment(value) {
|
|
8
8
|
return JsonPointerUriFragment.test(value);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns true if the value is a relative json pointer
|
|
3
|
-
* @specification
|
|
4
|
-
* @source ajv-formats
|
|
3
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc6901
|
|
4
|
+
* @source https://github.com/ajv-validator/ajv-formats
|
|
5
5
|
*/
|
|
6
6
|
export declare function IsRelativeJsonPointer(value: string): boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const RelativeJsonPointer = /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is a relative json pointer
|
|
4
|
-
* @specification
|
|
5
|
-
* @source ajv-formats
|
|
4
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc6901
|
|
5
|
+
* @source https://github.com/ajv-validator/ajv-formats
|
|
6
6
|
*/
|
|
7
7
|
export function IsRelativeJsonPointer(value) {
|
|
8
8
|
return RelativeJsonPointer.test(value);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// deno-lint-ignore-file ban-types no-explicit-any
|
|
2
2
|
// deno-fmt-ignore-file
|
|
3
3
|
import { Metrics } from './metrics.mjs';
|
|
4
|
+
import { Freeze } from './freeze.mjs';
|
|
4
5
|
/**
|
|
5
6
|
* Performs an Object assign using the Left and Right object types. We track this operation as it
|
|
6
7
|
* creates a new GC handle per assignment.
|
|
7
8
|
*/
|
|
8
9
|
export function Assign(left, right) {
|
|
9
10
|
Metrics.assign += 1;
|
|
10
|
-
return { ...left, ...right };
|
|
11
|
+
return Freeze({ ...left, ...right });
|
|
11
12
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-explicit-any
|
|
2
|
-
// deno-fmt-ignore-file
|
|
3
2
|
import { Settings } from '../settings/index.mjs';
|
|
4
3
|
import { Metrics } from './metrics.mjs';
|
|
4
|
+
import { Freeze } from './freeze.mjs';
|
|
5
5
|
function MergeHidden(left, right) {
|
|
6
6
|
for (const key of Object.keys(right)) {
|
|
7
7
|
Object.defineProperty(left, key, {
|
|
@@ -23,8 +23,7 @@ function Merge(left, right) {
|
|
|
23
23
|
*/
|
|
24
24
|
export function Create(hidden, enumerable, options = {}) {
|
|
25
25
|
Metrics.create += 1;
|
|
26
|
-
const settings = Settings.Get();
|
|
27
26
|
const withOptions = Merge(enumerable, options);
|
|
28
|
-
const withHidden =
|
|
29
|
-
return
|
|
27
|
+
const withHidden = Settings.Get().enumerableKind ? Merge(withOptions, hidden) : MergeHidden(withOptions, hidden);
|
|
28
|
+
return Freeze(withHidden);
|
|
30
29
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-explicit-any
|
|
2
|
-
// deno-fmt-ignore-file
|
|
3
2
|
import { Guard } from '../../guard/index.mjs';
|
|
4
3
|
import { Metrics } from './metrics.mjs';
|
|
4
|
+
import { Freeze } from './freeze.mjs';
|
|
5
5
|
import { Clone } from './clone.mjs';
|
|
6
6
|
/** Discards multiple property keys from the given object value */
|
|
7
7
|
export function Discard(value, propertyKeys) {
|
|
@@ -14,5 +14,5 @@ export function Discard(value, propertyKeys) {
|
|
|
14
14
|
descriptor.value = Clone(descriptor.value);
|
|
15
15
|
Object.defineProperty(result, key, descriptor);
|
|
16
16
|
}
|
|
17
|
-
return result;
|
|
17
|
+
return Freeze(result);
|
|
18
18
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// deno-lint-ignore-file no-explicit-any
|
|
2
|
+
import { Settings } from '../settings/index.mjs';
|
|
3
|
+
/** Conditionally freezes the value if `immutableTypes` is true, otherwise no action. */
|
|
4
|
+
export function Freeze(value) {
|
|
5
|
+
return Settings.Get().immutableTypes ? Object.freeze(value) : value;
|
|
6
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
// deno-
|
|
1
|
+
// deno-lint-ignore-file no-explicit-any
|
|
2
2
|
import { Settings } from '../settings/index.mjs';
|
|
3
3
|
import { Metrics } from './metrics.mjs';
|
|
4
|
+
import { Freeze } from './freeze.mjs';
|
|
4
5
|
import { Clone } from './clone.mjs';
|
|
5
6
|
/**
|
|
6
7
|
* Updates a value with new properties while preserving property enumerability. Use this function to modify
|
|
@@ -28,5 +29,5 @@ export function Update(current, hidden, enumerable) {
|
|
|
28
29
|
value: enumerable[key]
|
|
29
30
|
});
|
|
30
31
|
}
|
|
31
|
-
return result;
|
|
32
|
+
return Freeze(result);
|
|
32
33
|
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
"id": "whatsapp",
|
|
3
3
|
"doctorContract": {
|
|
4
4
|
"configRepair": true,
|
|
5
|
-
"stateMigrations":
|
|
5
|
+
"stateMigrations": [
|
|
6
|
+
{
|
|
7
|
+
"id": "whatsapp-legacy-state"
|
|
8
|
+
}
|
|
9
|
+
]
|
|
6
10
|
},
|
|
7
11
|
"name": "WhatsApp",
|
|
8
12
|
"description": "OpenClaw WhatsApp channel plugin for WhatsApp Web chats.",
|
|
9
|
-
"icon": "https://cdn.simpleicons.org/whatsapp",
|
|
10
13
|
"skills": [
|
|
11
14
|
"./skills"
|
|
12
15
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/whatsapp",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.3",
|
|
4
4
|
"description": "OpenClaw WhatsApp channel plugin for WhatsApp Web chats.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"audio-decode": "2.2.3",
|
|
12
12
|
"baileys": "7.0.0-rc14",
|
|
13
|
-
"typebox": "1.3.
|
|
13
|
+
"typebox": "1.3.18"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"openclaw": ">=2026.9.
|
|
16
|
+
"openclaw": ">=2026.9.3"
|
|
17
17
|
},
|
|
18
18
|
"peerDependenciesMeta": {
|
|
19
19
|
"openclaw": {
|
|
@@ -65,11 +65,11 @@
|
|
|
65
65
|
"minHostVersion": ">=2026.4.25"
|
|
66
66
|
},
|
|
67
67
|
"compat": {
|
|
68
|
-
"pluginApi": ">=2026.9.
|
|
68
|
+
"pluginApi": ">=2026.9.3"
|
|
69
69
|
},
|
|
70
70
|
"build": {
|
|
71
71
|
"bundledDist": false,
|
|
72
|
-
"openclawVersion": "2026.9.
|
|
72
|
+
"openclawVersion": "2026.9.3"
|
|
73
73
|
},
|
|
74
74
|
"release": {
|
|
75
75
|
"publishToClawHub": true,
|