@openclaw/whatsapp 2026.5.26-beta.1 → 2026.5.26
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/{action-runtime-PNEpb1qb.js → action-runtime-DcAQibC1.js} +1 -1
- package/dist/action-runtime-api.js +1 -1
- package/dist/action-runtime.runtime.js +1 -1
- package/dist/api.js +4 -4
- package/dist/{approval-handler.runtime-GXmnPxiL.js → approval-handler.runtime-D0hxugEn.js} +9 -40
- package/dist/{channel-DkT2UI4n.js → channel-BfG9HEZG.js} +23 -117
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-react-action-61jg4cjy.js → channel-react-action-VgsrmO3-.js} +2 -2
- package/dist/{channel.runtime-BAdyJSMT.js → channel.runtime-0kQxYUcI.js} +2 -2
- package/dist/{channel.setup-DFASG1fi.js → channel.setup-1zhfYJ9v.js} +1 -1
- package/dist/{monitor-CdeM6e28.js → monitor-Cxk7UHkH.js} +23 -13
- package/dist/{outbound-adapter-76p0VEXd.js → outbound-adapter-BiLBIo1h.js} +1 -1
- package/dist/outbound-payload-test-api.js +1 -1
- package/dist/runtime-api.js +3 -3
- package/dist/{send-CAQrir3g.js → send-BuORvrFd.js} +43 -145
- package/dist/{setup-core-B_fDLMkf.js → setup-core-mK3yptun.js} +2 -2
- package/dist/{setup-finalize-CwUDT0HD.js → setup-finalize-CkiVDt0B.js} +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-C4R54NEZ.js → setup-surface-sCDFlWd2.js} +1 -1
- package/dist/test-api.js +1 -1
- package/npm-shrinkwrap.json +3 -3
- package/package.json +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as resolveWhatsAppAccount } from "./accounts-B3diVrr6.js";
|
|
2
2
|
import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-CcdugbDf.js";
|
|
3
3
|
import { t as resolveWhatsAppReactionLevel } from "./reaction-level-BqMOEBeq.js";
|
|
4
|
-
import { r as sendReactionWhatsApp } from "./send-
|
|
4
|
+
import { r as sendReactionWhatsApp } from "./send-BuORvrFd.js";
|
|
5
5
|
import { ToolAuthorizationError, createActionGate, jsonResult, readReactionParams, readStringParam } from "openclaw/plugin-sdk/channel-actions";
|
|
6
6
|
//#region extensions/whatsapp/src/action-runtime-target-auth.ts
|
|
7
7
|
function resolveAuthorizedWhatsAppOutboundTarget(params) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as handleWhatsAppAction } from "./action-runtime-
|
|
1
|
+
import { t as handleWhatsAppAction } from "./action-runtime-DcAQibC1.js";
|
|
2
2
|
export { handleWhatsAppAction };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as handleWhatsAppAction } from "./action-runtime-
|
|
1
|
+
import { t as handleWhatsAppAction } from "./action-runtime-DcAQibC1.js";
|
|
2
2
|
export { handleWhatsAppAction };
|
package/dist/api.js
CHANGED
|
@@ -3,14 +3,14 @@ import { a as resolveWhatsAppAccount, i as listWhatsAppAuthDirs, n as hasAnyWhat
|
|
|
3
3
|
import { a as normalizeWhatsAppAllowFromEntries, c as normalizeWhatsAppTarget, i as looksLikeWhatsAppTargetId, r as isWhatsAppUserTarget, s as normalizeWhatsAppMessagingTarget, t as isWhatsAppGroupJid } from "./normalize-target-bVWjgftN.js";
|
|
4
4
|
import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-CcdugbDf.js";
|
|
5
5
|
import "./reaction-level-BqMOEBeq.js";
|
|
6
|
-
import "./send-
|
|
6
|
+
import "./send-BuORvrFd.js";
|
|
7
7
|
import { c as assertWebChannel, d as markdownToWhatsApp, f as resolveJidToE164, l as isSelfChatMode, m as toWhatsappJidWithLid, n as normalizeE164, p as toWhatsappJid, r as resolveUserPath, u as jidToE164 } from "./text-runtime-Dk37KYHj.js";
|
|
8
|
-
import { t as whatsappPlugin } from "./channel-
|
|
8
|
+
import { t as whatsappPlugin } from "./channel-BfG9HEZG.js";
|
|
9
9
|
import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-base-DwCUu3ab.js";
|
|
10
10
|
import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
|
|
11
|
-
import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint } from "./setup-core-
|
|
11
|
+
import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint } from "./setup-core-mK3yptun.js";
|
|
12
12
|
import "./config-schema-CsNDlDpL.js";
|
|
13
|
-
import { t as whatsappSetupPlugin } from "./channel.setup-
|
|
13
|
+
import { t as whatsappSetupPlugin } from "./channel.setup-1zhfYJ9v.js";
|
|
14
14
|
import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-HU41RHGI.js";
|
|
15
15
|
import { n as listWhatsAppDirectoryGroupsFromConfig, r as listWhatsAppDirectoryPeersFromConfig } from "./directory-config-CfLFAK54.js";
|
|
16
16
|
import { n as testing } from "./access-control-otOXu5WK.js";
|
|
@@ -1,47 +1,17 @@
|
|
|
1
1
|
import { s as normalizeWhatsAppMessagingTarget } from "./normalize-target-bVWjgftN.js";
|
|
2
2
|
import "./normalize-Bxwqo-bW.js";
|
|
3
|
-
import {
|
|
3
|
+
import { c as unregisterWhatsAppApprovalReactionTarget, i as sendTypingWhatsApp, s as registerWhatsAppApprovalReactionTarget, t as sendMessageWhatsApp } from "./send-BuORvrFd.js";
|
|
4
4
|
import { n as getWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
|
|
5
5
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
|
7
|
+
import { buildApprovalReactionPendingContent } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
7
8
|
import { buildChannelApprovalNativeTargetKey } from "openclaw/plugin-sdk/approval-native-runtime";
|
|
8
|
-
import { buildApprovalResolvedReplyPayload, buildPluginApprovalExpiredMessage, buildPluginApprovalPendingReplyPayload, buildPluginApprovalResolvedMessage } from "openclaw/plugin-sdk/approval-runtime";
|
|
9
9
|
import { createChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
|
|
10
|
-
import {
|
|
10
|
+
import { buildApprovalResolvedReplyPayload, buildPluginApprovalExpiredMessage, buildPluginApprovalResolvedMessage } from "openclaw/plugin-sdk/approval-runtime";
|
|
11
11
|
//#region extensions/whatsapp/src/approval-handler.runtime.ts
|
|
12
12
|
const log = createSubsystemLogger("whatsapp/approvals");
|
|
13
|
-
function appendReactionHint(params) {
|
|
14
|
-
const hint = buildWhatsAppApprovalReactionHint(params.allowedDecisions);
|
|
15
|
-
return hint ? `${params.text}\n\n${hint}` : params.text;
|
|
16
|
-
}
|
|
17
|
-
function replaceApprovalIdPlaceholder(text, approvalId) {
|
|
18
|
-
return (text ?? "").replace(/\/approve\s+<id>/g, `/approve ${approvalId}`);
|
|
19
|
-
}
|
|
20
13
|
function buildPendingPayload(params) {
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
text: appendReactionHint({
|
|
24
|
-
text: replaceApprovalIdPlaceholder((params.approvalKind === "plugin" ? buildPluginApprovalPendingReplyPayload({
|
|
25
|
-
request: params.request,
|
|
26
|
-
nowMs: params.nowMs,
|
|
27
|
-
allowedDecisions
|
|
28
|
-
}) : buildExecApprovalPendingReplyPayload$1({
|
|
29
|
-
approvalId: params.request.id,
|
|
30
|
-
approvalSlug: params.request.id.slice(0, 8),
|
|
31
|
-
approvalCommandId: params.request.id,
|
|
32
|
-
warningText: params.view.approvalKind === "exec" ? params.view.warningText ?? void 0 : void 0,
|
|
33
|
-
command: params.view.approvalKind === "exec" ? params.view.commandText : "",
|
|
34
|
-
cwd: params.view.approvalKind === "exec" ? params.view.cwd ?? void 0 : void 0,
|
|
35
|
-
host: params.view.approvalKind === "exec" && params.view.host === "node" ? "node" : "gateway",
|
|
36
|
-
nodeId: params.view.approvalKind === "exec" ? params.view.nodeId ?? void 0 : void 0,
|
|
37
|
-
allowedDecisions,
|
|
38
|
-
expiresAtMs: params.request.expiresAtMs,
|
|
39
|
-
nowMs: params.nowMs
|
|
40
|
-
})).text, params.request.id),
|
|
41
|
-
allowedDecisions
|
|
42
|
-
}),
|
|
43
|
-
allowedDecisions
|
|
44
|
-
};
|
|
14
|
+
return buildApprovalReactionPendingContent(params);
|
|
45
15
|
}
|
|
46
16
|
function buildResolvedText(params) {
|
|
47
17
|
if (params.view.approvalKind === "plugin") return buildPluginApprovalResolvedMessage(params.resolved);
|
|
@@ -66,11 +36,10 @@ const whatsappApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter(
|
|
|
66
36
|
shouldHandle: ({ context }) => Boolean(context)
|
|
67
37
|
},
|
|
68
38
|
presentation: {
|
|
69
|
-
buildPendingPayload: ({ request,
|
|
39
|
+
buildPendingPayload: ({ request, nowMs, view }) => buildPendingPayload({
|
|
70
40
|
request,
|
|
71
|
-
|
|
72
|
-
nowMs
|
|
73
|
-
view
|
|
41
|
+
view,
|
|
42
|
+
nowMs
|
|
74
43
|
}),
|
|
75
44
|
buildResolvedResult: ({ request, resolved, view }) => ({
|
|
76
45
|
kind: "update",
|
|
@@ -110,7 +79,7 @@ const whatsappApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter(
|
|
|
110
79
|
cfg,
|
|
111
80
|
...preparedTarget.accountId ? { accountId: preparedTarget.accountId } : {}
|
|
112
81
|
}).catch(() => {});
|
|
113
|
-
const result = await sendMessageWhatsApp(preparedTarget.to, pendingPayload.text, {
|
|
82
|
+
const result = await sendMessageWhatsApp(preparedTarget.to, pendingPayload.reactionPayload.text ?? "", {
|
|
114
83
|
cfg,
|
|
115
84
|
verbose,
|
|
116
85
|
preserveLeadingWhitespace: true,
|
|
@@ -145,7 +114,7 @@ const whatsappApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter(
|
|
|
145
114
|
remoteJid: entry.remoteJid,
|
|
146
115
|
messageId: entry.messageId,
|
|
147
116
|
approvalId: request.id,
|
|
148
|
-
allowedDecisions: pendingPayload.allowedDecisions,
|
|
117
|
+
allowedDecisions: pendingPayload.reactionPayload.allowedDecisions,
|
|
149
118
|
ttlMs: Math.max(1, view.expiresAtMs - Date.now())
|
|
150
119
|
}) ? true : null,
|
|
151
120
|
unbindPending: ({ entry }) => {
|
|
@@ -4,13 +4,13 @@ import { c as normalizeWhatsAppTarget, i as looksLikeWhatsAppTargetId, n as isWh
|
|
|
4
4
|
import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-CcdugbDf.js";
|
|
5
5
|
import { t as resolveWhatsAppReactionLevel } from "./reaction-level-BqMOEBeq.js";
|
|
6
6
|
import "./normalize-Bxwqo-bW.js";
|
|
7
|
-
import {
|
|
7
|
+
import { i as sendTypingWhatsApp, l as getWhatsAppApprovalApprovers, n as sendPollWhatsApp, t as sendMessageWhatsApp, u as whatsappApprovalAuth } from "./send-BuORvrFd.js";
|
|
8
8
|
import { n as getWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
|
|
9
9
|
import { r as normalizeWhatsAppPayloadTextPreservingIndentation } from "./outbound-media-contract-CA2OGvjJ.js";
|
|
10
10
|
import { t as createWhatsAppLoginTool } from "./agent-tools-login-BDzvb3ee.js";
|
|
11
11
|
import { t as createWhatsAppOutboundBase } from "./outbound-base-DwCUu3ab.js";
|
|
12
12
|
import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
|
|
13
|
-
import { a as resolveWhatsAppGroupRequireMention, c as resolveWhatsAppMentionStripRegexes, i as whatsappSetupWizardProxy, l as formatWhatsAppConfigAllowFromEntries, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, r as loadWhatsAppChannelRuntime, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-
|
|
13
|
+
import { a as resolveWhatsAppGroupRequireMention, c as resolveWhatsAppMentionStripRegexes, i as whatsappSetupWizardProxy, l as formatWhatsAppConfigAllowFromEntries, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, r as loadWhatsAppChannelRuntime, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-mK3yptun.js";
|
|
14
14
|
import { f as readWebAuthExistsForDecision, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-BrKb0mwT.js";
|
|
15
15
|
import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-D_BmQUR9.js";
|
|
16
16
|
import { createActionGate as createActionGate$1 } from "openclaw/plugin-sdk/channel-actions";
|
|
@@ -18,6 +18,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "opencl
|
|
|
18
18
|
import { asString, collectIssuesForEnabledAccounts, createAsyncComputedAccountStatusAdapter, createDefaultChannelRuntimeState, isRecord as isRecord$1 } from "openclaw/plugin-sdk/status-helpers";
|
|
19
19
|
import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
|
|
20
20
|
import { buildChannelOutboundSessionRoute } from "openclaw/plugin-sdk/core";
|
|
21
|
+
import { buildApprovalReactionPromptPayloadForRequest } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
21
22
|
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
22
23
|
import { buildDmGroupAccountAllowlistAdapter } from "openclaw/plugin-sdk/allowlist-config-edit";
|
|
23
24
|
import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
@@ -25,19 +26,12 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
|
25
26
|
import { matchesApprovalRequestFilters } from "openclaw/plugin-sdk/approval-client-runtime";
|
|
26
27
|
import { createChannelApprovalCapability, splitChannelApprovalCapability } from "openclaw/plugin-sdk/approval-delivery-runtime";
|
|
27
28
|
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
28
|
-
import { createChannelApproverDmTargetResolver, createChannelNativeOriginTargetResolver, doesApprovalRequestMatchChannelAccount, resolveApprovalRequestSessionTarget } from "openclaw/plugin-sdk/approval-native-runtime";
|
|
29
|
-
import { buildExecApprovalPendingReplyPayload, buildPluginApprovalPendingReplyPayload, resolveExecApprovalCommandDisplay, resolveExecApprovalRequestAllowedDecisions } from "openclaw/plugin-sdk/approval-runtime";
|
|
30
|
-
import { channelRouteTargetsMatchExact } from "openclaw/plugin-sdk/channel-route";
|
|
29
|
+
import { createChannelApproverDmTargetResolver, createChannelNativeOriginTargetResolver, createNativeApprovalForwardingFallbackSuppressor, doesApprovalRequestMatchChannelAccount, nativeApprovalTargetsMatch, resolveApprovalRequestSessionTarget } from "openclaw/plugin-sdk/approval-native-runtime";
|
|
31
30
|
import { normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/routing";
|
|
32
31
|
import { createMessageReceiptFromOutboundResults, defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-message";
|
|
33
32
|
import { chunkText } from "openclaw/plugin-sdk/reply-chunking";
|
|
34
33
|
//#region extensions/whatsapp/src/approval-native.ts
|
|
35
34
|
const DEFAULT_APPROVAL_FORWARDING_MODE = "session";
|
|
36
|
-
const DEFAULT_PLUGIN_APPROVAL_DECISIONS = [
|
|
37
|
-
"allow-once",
|
|
38
|
-
"allow-always",
|
|
39
|
-
"deny"
|
|
40
|
-
];
|
|
41
35
|
function isWhatsAppApprovalTransportEnabled(params) {
|
|
42
36
|
return resolveWhatsAppAccount({
|
|
43
37
|
cfg: params.cfg,
|
|
@@ -91,22 +85,6 @@ function normalizeWhatsAppForwardTarget(target) {
|
|
|
91
85
|
threadId: target.threadId ?? null
|
|
92
86
|
};
|
|
93
87
|
}
|
|
94
|
-
function nativeApprovalTargetsMatch(params) {
|
|
95
|
-
return channelRouteTargetsMatchExact({
|
|
96
|
-
left: {
|
|
97
|
-
channel: "whatsapp",
|
|
98
|
-
to: params.left.to,
|
|
99
|
-
accountId: params.left.accountId,
|
|
100
|
-
threadId: params.left.threadId
|
|
101
|
-
},
|
|
102
|
-
right: {
|
|
103
|
-
channel: "whatsapp",
|
|
104
|
-
to: params.right.to,
|
|
105
|
-
accountId: params.right.accountId,
|
|
106
|
-
threadId: params.right.threadId
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
88
|
function hasMatchingWhatsAppTarget(params) {
|
|
111
89
|
const candidateTarget = params.target ? normalizeWhatsAppForwardTarget(params.target) : null;
|
|
112
90
|
return (params.config.targets ?? []).some((target) => {
|
|
@@ -119,6 +97,7 @@ function hasMatchingWhatsAppTarget(params) {
|
|
|
119
97
|
})) return false;
|
|
120
98
|
if (!candidateTarget) return true;
|
|
121
99
|
return nativeApprovalTargetsMatch({
|
|
100
|
+
channel: "whatsapp",
|
|
122
101
|
left: configuredTarget,
|
|
123
102
|
right: candidateTarget
|
|
124
103
|
});
|
|
@@ -251,57 +230,24 @@ const resolveWhatsAppApproverDmTargets = createChannelApproverDmTargetResolver({
|
|
|
251
230
|
};
|
|
252
231
|
}
|
|
253
232
|
});
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
233
|
+
const shouldSuppressWhatsAppForwardingFallback = createNativeApprovalForwardingFallbackSuppressor({
|
|
234
|
+
channel: "whatsapp",
|
|
235
|
+
normalizeForwardTarget: normalizeWhatsAppForwardTarget,
|
|
236
|
+
resolveAccountId: ({ forwardingTarget, request }) => forwardingTarget.accountId ?? normalizeOptionalString(request.request.turnSourceAccountId),
|
|
237
|
+
resolveForwardingTargetForMatch: ({ forwardingTarget, accountId }) => ({
|
|
238
|
+
...forwardingTarget,
|
|
239
|
+
accountId
|
|
240
|
+
}),
|
|
241
|
+
isSessionRouteEligible: isWhatsAppSessionApprovalEligible,
|
|
242
|
+
isExplicitTargetEligible: isWhatsAppExplicitTargetEligible,
|
|
243
|
+
resolveOriginTarget: resolveWhatsAppOriginTarget,
|
|
244
|
+
resolveApproverDmTargets: resolveWhatsAppApproverDmTargets
|
|
245
|
+
});
|
|
263
246
|
function buildWhatsAppExecPendingPayload(params) {
|
|
264
|
-
|
|
265
|
-
const command = resolveExecApprovalCommandDisplay(params.request.request).commandText;
|
|
266
|
-
const payload = buildExecApprovalPendingReplyPayload({
|
|
267
|
-
approvalId: params.request.id,
|
|
268
|
-
approvalSlug: params.request.id.slice(0, 8),
|
|
269
|
-
approvalCommandId: params.request.id,
|
|
270
|
-
warningText: params.request.request.warningText ?? void 0,
|
|
271
|
-
ask: params.request.request.ask ?? null,
|
|
272
|
-
agentId: params.request.request.agentId ?? null,
|
|
273
|
-
allowedDecisions,
|
|
274
|
-
command,
|
|
275
|
-
cwd: params.request.request.cwd ?? void 0,
|
|
276
|
-
host: params.request.request.host === "node" ? "node" : "gateway",
|
|
277
|
-
nodeId: params.request.request.nodeId ?? void 0,
|
|
278
|
-
sessionKey: params.request.request.sessionKey ?? null,
|
|
279
|
-
expiresAtMs: params.request.expiresAtMs,
|
|
280
|
-
nowMs: params.nowMs
|
|
281
|
-
});
|
|
282
|
-
return {
|
|
283
|
-
...payload,
|
|
284
|
-
text: appendWhatsAppReactionHint({
|
|
285
|
-
text: replaceApprovalIdPlaceholder(payload.text, params.request.id),
|
|
286
|
-
allowedDecisions
|
|
287
|
-
})
|
|
288
|
-
};
|
|
247
|
+
return buildApprovalReactionPromptPayloadForRequest(params);
|
|
289
248
|
}
|
|
290
249
|
function buildWhatsAppPluginPendingPayload(params) {
|
|
291
|
-
|
|
292
|
-
const allowedDecisions = configuredDecisions && configuredDecisions.length > 0 ? configuredDecisions : DEFAULT_PLUGIN_APPROVAL_DECISIONS;
|
|
293
|
-
const payload = buildPluginApprovalPendingReplyPayload({
|
|
294
|
-
request: params.request,
|
|
295
|
-
nowMs: params.nowMs,
|
|
296
|
-
allowedDecisions
|
|
297
|
-
});
|
|
298
|
-
return {
|
|
299
|
-
...payload,
|
|
300
|
-
text: appendWhatsAppReactionHint({
|
|
301
|
-
text: replaceApprovalIdPlaceholder(payload.text, params.request.id),
|
|
302
|
-
allowedDecisions
|
|
303
|
-
})
|
|
304
|
-
};
|
|
250
|
+
return buildApprovalReactionPromptPayloadForRequest(params);
|
|
305
251
|
}
|
|
306
252
|
const whatsappApprovalCapability = createChannelApprovalCapability({
|
|
307
253
|
...whatsappApprovalAuth,
|
|
@@ -333,47 +279,7 @@ const whatsappApprovalCapability = createChannelApprovalCapability({
|
|
|
333
279
|
accountId
|
|
334
280
|
}).length > 0;
|
|
335
281
|
}),
|
|
336
|
-
shouldSuppressForwardingFallback:
|
|
337
|
-
const forwardingTarget = normalizeWhatsAppForwardTarget(target);
|
|
338
|
-
if (!forwardingTarget) return false;
|
|
339
|
-
const accountId = forwardingTarget.accountId ?? normalizeOptionalString(request.request.turnSourceAccountId);
|
|
340
|
-
const forwardingTargetForMatch = {
|
|
341
|
-
...forwardingTarget,
|
|
342
|
-
accountId
|
|
343
|
-
};
|
|
344
|
-
const kind = resolveApprovalKind(request, approvalKind);
|
|
345
|
-
if (!(target.source === "target" ? isWhatsAppExplicitTargetEligible({
|
|
346
|
-
cfg,
|
|
347
|
-
accountId,
|
|
348
|
-
approvalKind: kind,
|
|
349
|
-
request,
|
|
350
|
-
target
|
|
351
|
-
}) : isWhatsAppSessionApprovalEligible({
|
|
352
|
-
cfg,
|
|
353
|
-
accountId,
|
|
354
|
-
approvalKind: kind,
|
|
355
|
-
request
|
|
356
|
-
}))) return false;
|
|
357
|
-
const originTarget = resolveWhatsAppOriginTarget({
|
|
358
|
-
cfg,
|
|
359
|
-
accountId,
|
|
360
|
-
approvalKind: kind,
|
|
361
|
-
request
|
|
362
|
-
});
|
|
363
|
-
if (originTarget && nativeApprovalTargetsMatch({
|
|
364
|
-
left: forwardingTargetForMatch,
|
|
365
|
-
right: originTarget
|
|
366
|
-
})) return true;
|
|
367
|
-
return resolveWhatsAppApproverDmTargets({
|
|
368
|
-
cfg,
|
|
369
|
-
accountId,
|
|
370
|
-
approvalKind: kind,
|
|
371
|
-
request
|
|
372
|
-
}).some((approverTarget) => nativeApprovalTargetsMatch({
|
|
373
|
-
left: forwardingTargetForMatch,
|
|
374
|
-
right: approverTarget
|
|
375
|
-
}));
|
|
376
|
-
}
|
|
282
|
+
shouldSuppressForwardingFallback: shouldSuppressWhatsAppForwardingFallback
|
|
377
283
|
},
|
|
378
284
|
render: {
|
|
379
285
|
exec: { buildPendingPayload: ({ request, nowMs }) => buildWhatsAppExecPendingPayload({
|
|
@@ -422,7 +328,7 @@ const whatsappApprovalCapability = createChannelApprovalCapability({
|
|
|
422
328
|
accountId,
|
|
423
329
|
request
|
|
424
330
|
}),
|
|
425
|
-
load: async () => (await import("./approval-handler.runtime-
|
|
331
|
+
load: async () => (await import("./approval-handler.runtime-D0hxugEn.js")).whatsappApprovalNativeRuntime
|
|
426
332
|
})
|
|
427
333
|
});
|
|
428
334
|
splitChannelApprovalCapability(whatsappApprovalCapability);
|
|
@@ -704,7 +610,7 @@ function collectWhatsAppStatusIssues(accounts) {
|
|
|
704
610
|
//#endregion
|
|
705
611
|
//#region extensions/whatsapp/src/channel.ts
|
|
706
612
|
const loadWhatsAppDirectoryConfig = createLazyRuntimeModule(() => import("./directory-config-CfLFAK54.js").then((n) => n.t));
|
|
707
|
-
const loadWhatsAppChannelReactAction = createLazyRuntimeModule(() => import("./channel-react-action-
|
|
613
|
+
const loadWhatsAppChannelReactAction = createLazyRuntimeModule(() => import("./channel-react-action-VgsrmO3-.js"));
|
|
708
614
|
function resolveWhatsAppTargetInfo(raw) {
|
|
709
615
|
const normalized = normalizeWhatsAppTarget(raw);
|
|
710
616
|
if (!normalized) return null;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as whatsappPlugin } from "./channel-
|
|
1
|
+
import { t as whatsappPlugin } from "./channel-BfG9HEZG.js";
|
|
2
2
|
export { whatsappPlugin };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-B3diVrr6.js";
|
|
2
2
|
import { c as normalizeWhatsAppTarget, t as isWhatsAppGroupJid } from "./normalize-target-bVWjgftN.js";
|
|
3
|
-
import { r as resolveAuthorizedWhatsAppOutboundTarget, t as handleWhatsAppAction } from "./action-runtime-
|
|
3
|
+
import { r as resolveAuthorizedWhatsAppOutboundTarget, t as handleWhatsAppAction } from "./action-runtime-DcAQibC1.js";
|
|
4
4
|
import "./normalize-Bxwqo-bW.js";
|
|
5
|
-
import { t as sendMessageWhatsApp } from "./send-
|
|
5
|
+
import { t as sendMessageWhatsApp } from "./send-BuORvrFd.js";
|
|
6
6
|
import { jsonResult, readStringOrNumberParam, readStringParam as readStringParam$1, resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
|
|
7
7
|
//#region extensions/whatsapp/src/channel-react-action.ts
|
|
8
8
|
const WHATSAPP_CHANNEL = "whatsapp";
|
|
@@ -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-BrKb0mwT.js";
|
|
3
3
|
import { t as getActiveWebListener$1 } from "./active-listener-B4SDebQ6.js";
|
|
4
|
-
import { t as monitorWebChannel$1 } from "./monitor-
|
|
4
|
+
import { t as monitorWebChannel$1 } from "./monitor-Cxk7UHkH.js";
|
|
5
5
|
import { t as loginWeb$1 } from "./login-CympQtg8.js";
|
|
6
|
-
import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-
|
|
6
|
+
import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-sCDFlWd2.js";
|
|
7
7
|
//#region extensions/whatsapp/src/channel.runtime.ts
|
|
8
8
|
function getActiveWebListener(...args) {
|
|
9
9
|
return getActiveWebListener$1(...args);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./accounts-B3diVrr6.js";
|
|
2
|
-
import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupWizardProxy, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-
|
|
2
|
+
import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupWizardProxy, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-mK3yptun.js";
|
|
3
3
|
import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-D_BmQUR9.js";
|
|
4
4
|
//#region extensions/whatsapp/src/channel.setup.ts
|
|
5
5
|
async function isWhatsAppAuthConfigured(account) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-B3diVrr6.js";
|
|
2
2
|
import { t as isWhatsAppGroupJid } from "./normalize-target-bVWjgftN.js";
|
|
3
3
|
import { t as resolveWhatsAppReactionLevel } from "./reaction-level-BqMOEBeq.js";
|
|
4
|
-
import {
|
|
4
|
+
import { o as maybeResolveWhatsAppApprovalReaction, r as sendReactionWhatsApp } from "./send-BuORvrFd.js";
|
|
5
5
|
import { n as getWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
|
|
6
6
|
import { i as prepareWhatsAppOutboundMedia, o as sendWhatsAppOutboundWithRetry, r as normalizeWhatsAppPayloadTextPreservingIndentation, t as normalizeWhatsAppOutboundPayload } from "./outbound-media-contract-CA2OGvjJ.js";
|
|
7
7
|
import { n as getStatusCode, t as formatError } from "./session-errors-BAj9D2La.js";
|
|
@@ -352,6 +352,11 @@ async function attachWebInboxToSocket(options) {
|
|
|
352
352
|
return `${msg.accountId}:${conversationKey}:${senderKey}`;
|
|
353
353
|
};
|
|
354
354
|
const shouldDebounceInboundMessage = (msg) => options.shouldDebounce?.(msg) ?? true;
|
|
355
|
+
const orderDebouncedInboundEntries = (entries) => entries.toSorted((a, b) => {
|
|
356
|
+
const timestampDiff = (a.timestamp ?? 0) - (b.timestamp ?? 0);
|
|
357
|
+
if (timestampDiff !== 0) return timestampDiff;
|
|
358
|
+
return (a.receiveOrder ?? 0) - (b.receiveOrder ?? 0);
|
|
359
|
+
});
|
|
355
360
|
const finalizeInboundDelivery = async (entries, error) => {
|
|
356
361
|
const dedupeKeys = uniqueStrings(entries.map((entry) => entry.dedupeKey).filter(isNonEmptyString));
|
|
357
362
|
const durableEntries = entries.filter((entry) => isNonEmptyString(entry.durableId));
|
|
@@ -375,17 +380,18 @@ async function attachWebInboxToSocket(options) {
|
|
|
375
380
|
});
|
|
376
381
|
activeInboundFlushes.add(flushTask);
|
|
377
382
|
try {
|
|
378
|
-
const
|
|
383
|
+
const orderedEntries = orderDebouncedInboundEntries(entries);
|
|
384
|
+
const last = orderedEntries.at(-1);
|
|
379
385
|
if (!last) return;
|
|
380
386
|
try {
|
|
381
|
-
if (
|
|
387
|
+
if (orderedEntries.length === 1) {
|
|
382
388
|
await options.onMessage(last);
|
|
383
|
-
await finalizeInboundDelivery(
|
|
389
|
+
await finalizeInboundDelivery(orderedEntries);
|
|
384
390
|
return;
|
|
385
391
|
}
|
|
386
392
|
const mentioned = /* @__PURE__ */ new Set();
|
|
387
|
-
for (const entry of
|
|
388
|
-
const combinedBody =
|
|
393
|
+
for (const entry of orderedEntries) for (const jid of entry.mentions ?? entry.mentionedJids ?? []) mentioned.add(jid);
|
|
394
|
+
const combinedBody = orderedEntries.map((entry) => entry.body).filter(Boolean).join("\n");
|
|
389
395
|
const combinedMessage = {
|
|
390
396
|
...last,
|
|
391
397
|
body: combinedBody,
|
|
@@ -394,9 +400,9 @@ async function attachWebInboxToSocket(options) {
|
|
|
394
400
|
isBatched: true
|
|
395
401
|
};
|
|
396
402
|
await options.onMessage(combinedMessage);
|
|
397
|
-
await finalizeInboundDelivery(
|
|
403
|
+
await finalizeInboundDelivery(orderedEntries);
|
|
398
404
|
} catch (error) {
|
|
399
|
-
await finalizeInboundDelivery(
|
|
405
|
+
await finalizeInboundDelivery(orderedEntries, error);
|
|
400
406
|
throw error;
|
|
401
407
|
}
|
|
402
408
|
} finally {
|
|
@@ -637,7 +643,7 @@ async function attachWebInboxToSocket(options) {
|
|
|
637
643
|
const msgTsNum = msgTsRaw != null ? Number(msgTsRaw) : NaN;
|
|
638
644
|
return (Number.isFinite(msgTsNum) ? msgTsNum * 1e3 : 0) < connectedAtMs - APPEND_RECENT_GRACE_MS;
|
|
639
645
|
};
|
|
640
|
-
const processDurableInboundMessage = async (msg, upsertType, stored) => {
|
|
646
|
+
const processDurableInboundMessage = async (msg, upsertType, receiveOrder, stored) => {
|
|
641
647
|
const inbound = await normalizeInboundMessage(msg);
|
|
642
648
|
if (!inbound) {
|
|
643
649
|
if (stored) await completeUndeliverableDurableInbound(stored.id, stored.metadata);
|
|
@@ -688,12 +694,13 @@ async function attachWebInboxToSocket(options) {
|
|
|
688
694
|
recordAcceptedInboundActivity(options.accountId);
|
|
689
695
|
await enqueueInboundMessage(msg, inbound, enriched, {
|
|
690
696
|
durableId,
|
|
691
|
-
readReceipt: deliveryReadReceipt
|
|
697
|
+
readReceipt: deliveryReadReceipt,
|
|
698
|
+
receiveOrder
|
|
692
699
|
});
|
|
693
700
|
};
|
|
694
701
|
const replayPendingDurableInboundMessages = async () => {
|
|
695
702
|
const pending = await durableInboundJournal.pending();
|
|
696
|
-
for (const record of pending) await processDurableInboundMessage(deserializeWhatsAppDurableInboundMessage(record.payload.message), record.payload.upsertType, {
|
|
703
|
+
for (const record of pending) await processDurableInboundMessage(deserializeWhatsAppDurableInboundMessage(record.payload.message), record.payload.upsertType, record.payload.receivedAt, {
|
|
697
704
|
id: record.id,
|
|
698
705
|
payload: record.payload,
|
|
699
706
|
metadata: record.metadata
|
|
@@ -816,7 +823,8 @@ async function attachWebInboxToSocket(options) {
|
|
|
816
823
|
mediaFileName: enriched.mediaFileName,
|
|
817
824
|
dedupeKey: inbound.id ? `${options.accountId}:${inbound.remoteJid}:${inbound.id}` : void 0,
|
|
818
825
|
durableId: durable.durableId,
|
|
819
|
-
readReceipt: durable.readReceipt
|
|
826
|
+
readReceipt: durable.readReceipt,
|
|
827
|
+
receiveOrder: durable.receiveOrder
|
|
820
828
|
};
|
|
821
829
|
const debounceKey = buildInboundDebounceKey(inboundMessage);
|
|
822
830
|
if (debounceKey) {
|
|
@@ -840,9 +848,11 @@ async function attachWebInboxToSocket(options) {
|
|
|
840
848
|
}
|
|
841
849
|
};
|
|
842
850
|
const pendingMessageHandlers = /* @__PURE__ */ new Set();
|
|
851
|
+
let nextReceiveOrder = 0;
|
|
843
852
|
const handleMessagesUpsert = async (upsert) => {
|
|
844
853
|
if (upsert.type !== "notify" && upsert.type !== "append") return;
|
|
845
854
|
for (const msg of upsert.messages ?? []) {
|
|
855
|
+
const receiveOrder = nextReceiveOrder++;
|
|
846
856
|
if (await maybeResolveWhatsAppApprovalReaction({
|
|
847
857
|
cfg: options.loadConfig?.() ?? options.cfg,
|
|
848
858
|
accountId: options.accountId,
|
|
@@ -852,7 +862,7 @@ async function attachWebInboxToSocket(options) {
|
|
|
852
862
|
resolveInboundJid,
|
|
853
863
|
logVerboseMessage: (message) => logWhatsAppVerbose(options.verbose, message)
|
|
854
864
|
})) continue;
|
|
855
|
-
await processDurableInboundMessage(msg, upsert.type);
|
|
865
|
+
await processDurableInboundMessage(msg, upsert.type, receiveOrder);
|
|
856
866
|
}
|
|
857
867
|
};
|
|
858
868
|
const handleMessagesUpsertEvent = (upsert) => {
|
|
@@ -7,7 +7,7 @@ import "openclaw/plugin-sdk/channel-send-result";
|
|
|
7
7
|
//#region extensions/whatsapp/src/outbound-adapter.ts
|
|
8
8
|
let whatsAppSendModulePromise;
|
|
9
9
|
function loadWhatsAppSendModule() {
|
|
10
|
-
whatsAppSendModulePromise ??= import("./send-
|
|
10
|
+
whatsAppSendModulePromise ??= import("./send-BuORvrFd.js").then((n) => n.a);
|
|
11
11
|
return whatsAppSendModulePromise;
|
|
12
12
|
}
|
|
13
13
|
function normalizeOutboundText(text) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as whatsappOutbound } from "./outbound-adapter-
|
|
1
|
+
import { t as whatsappOutbound } from "./outbound-adapter-BiLBIo1h.js";
|
|
2
2
|
export { whatsappOutbound };
|
package/dist/runtime-api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { o as resolveWebCredsBackupPath, r as hasWebCredsSync, s as resolveWebCredsPath } from "./creds-files-B1kSWtBg.js";
|
|
2
|
-
import { n as whatsAppActionRuntime, t as handleWhatsAppAction } from "./action-runtime-
|
|
3
|
-
import { i as sendTypingWhatsApp, n as sendPollWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./send-
|
|
2
|
+
import { n as whatsAppActionRuntime, t as handleWhatsAppAction } from "./action-runtime-DcAQibC1.js";
|
|
3
|
+
import { i as sendTypingWhatsApp, n as sendPollWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./send-BuORvrFd.js";
|
|
4
4
|
import { r as setWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
|
|
5
5
|
import { n as getStatusCode, t as formatError } from "./session-errors-BAj9D2La.js";
|
|
6
6
|
import { startWebLoginWithQr, waitForWebLogin } from "./login-qr-runtime.js";
|
|
@@ -10,7 +10,7 @@ import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-HU41RHGI.js";
|
|
|
10
10
|
import { d as extractLocationData, f as extractMediaPlaceholder, l as extractContactContext, m as extractText } from "./send-api-C3EWzdzp.js";
|
|
11
11
|
import { n as newConnectionId, r as waitForWaConnection, t as createWaSocket } from "./session-CDgpDc0l.js";
|
|
12
12
|
import { n as resolveWebAccountId, t as getActiveWebListener } from "./active-listener-B4SDebQ6.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-Cxk7UHkH.js";
|
|
14
14
|
import { t as loginWeb } from "./login-CympQtg8.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, extractMediaPlaceholder, 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 };
|
|
@@ -14,6 +14,7 @@ import { convertMarkdownTables, resolveMarkdownTableMode } from "openclaw/plugin
|
|
|
14
14
|
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
15
15
|
import { normalizePollInput } from "openclaw/plugin-sdk/poll-runtime";
|
|
16
16
|
import { createSubsystemLogger, getChildLogger as getChildLogger$1 } from "openclaw/plugin-sdk/runtime-env";
|
|
17
|
+
import { createApprovalReactionTargetStore, listApprovalReactionBindings, resolveApprovalReactionTarget } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
17
18
|
import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
18
19
|
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
|
|
19
20
|
//#region extensions/whatsapp/src/approval-auth.ts
|
|
@@ -57,24 +58,18 @@ const whatsappApprovalAuth = { authorizeActorAction({ cfg, accountId, senderId,
|
|
|
57
58
|
} };
|
|
58
59
|
//#endregion
|
|
59
60
|
//#region extensions/whatsapp/src/approval-reactions.ts
|
|
60
|
-
const WHATSAPP_APPROVAL_REACTION_META = {
|
|
61
|
-
"allow-once": {
|
|
62
|
-
emoji: "👍",
|
|
63
|
-
label: "Allow Once"
|
|
64
|
-
},
|
|
65
|
-
deny: {
|
|
66
|
-
emoji: "👎",
|
|
67
|
-
label: "Deny"
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const WHATSAPP_APPROVAL_REACTION_ORDER = ["allow-once", "deny"];
|
|
71
61
|
const PERSISTENT_NAMESPACE = "whatsapp.approval-reactions";
|
|
72
62
|
const PERSISTENT_MAX_ENTRIES = 1e3;
|
|
73
63
|
const DEFAULT_REACTION_TARGET_TTL_MS = 1440 * 60 * 1e3;
|
|
74
|
-
const whatsappApprovalReactionTargets = /* @__PURE__ */ new Map();
|
|
75
|
-
let persistentStore;
|
|
76
|
-
let persistentStoreDisabled = false;
|
|
77
64
|
let resolverRuntimePromise;
|
|
65
|
+
const whatsappApprovalReactionTargets = createApprovalReactionTargetStore({
|
|
66
|
+
namespace: PERSISTENT_NAMESPACE,
|
|
67
|
+
maxEntries: PERSISTENT_MAX_ENTRIES,
|
|
68
|
+
defaultTtlMs: DEFAULT_REACTION_TARGET_TTL_MS,
|
|
69
|
+
openStore: (storeParams) => getOptionalWhatsAppRuntime()?.state.openKeyedStore(storeParams),
|
|
70
|
+
logPersistentError: reportPersistentApprovalReactionError,
|
|
71
|
+
readPersistedTarget
|
|
72
|
+
});
|
|
78
73
|
function loadApprovalResolver() {
|
|
79
74
|
resolverRuntimePromise ??= import("./approval-resolver-e1hAVRRy.js");
|
|
80
75
|
return resolverRuntimePromise;
|
|
@@ -94,106 +89,17 @@ function reportPersistentApprovalReactionError(error) {
|
|
|
94
89
|
}).warn("WhatsApp persistent approval reaction state failed", { error: String(error) });
|
|
95
90
|
} catch {}
|
|
96
91
|
}
|
|
97
|
-
function
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const runtime = getOptionalWhatsAppRuntime();
|
|
106
|
-
if (!runtime) return;
|
|
107
|
-
try {
|
|
108
|
-
persistentStore = runtime.state.openKeyedStore({
|
|
109
|
-
namespace: PERSISTENT_NAMESPACE,
|
|
110
|
-
maxEntries: PERSISTENT_MAX_ENTRIES,
|
|
111
|
-
defaultTtlMs: DEFAULT_REACTION_TARGET_TTL_MS
|
|
112
|
-
});
|
|
113
|
-
return persistentStore;
|
|
114
|
-
} catch (error) {
|
|
115
|
-
disablePersistentApprovalReactionStore(error);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function readPersistedTarget(value) {
|
|
120
|
-
const persisted = value;
|
|
121
|
-
if (persisted?.version !== 1 || !persisted.target || typeof persisted.target.approvalId !== "string" || !Array.isArray(persisted.target.allowedDecisions)) return null;
|
|
122
|
-
return persisted.target;
|
|
123
|
-
}
|
|
124
|
-
function rememberPersistentApprovalReactionTarget(params) {
|
|
125
|
-
const ttlMs = params.ttlMs == null ? DEFAULT_REACTION_TARGET_TTL_MS : Math.max(1, params.ttlMs);
|
|
126
|
-
const store = getPersistentApprovalReactionStore();
|
|
127
|
-
if (!store) return;
|
|
128
|
-
store.register(params.key, {
|
|
129
|
-
version: 1,
|
|
130
|
-
target: params.target
|
|
131
|
-
}, { ttlMs }).catch(disablePersistentApprovalReactionStore);
|
|
132
|
-
}
|
|
133
|
-
function forgetPersistentApprovalReactionTarget(key) {
|
|
134
|
-
const store = getPersistentApprovalReactionStore();
|
|
135
|
-
if (!store) return;
|
|
136
|
-
store.delete(key).catch(disablePersistentApprovalReactionStore);
|
|
137
|
-
}
|
|
138
|
-
async function lookupPersistentApprovalReactionTarget(key) {
|
|
139
|
-
const store = getPersistentApprovalReactionStore();
|
|
140
|
-
if (!store) return null;
|
|
141
|
-
try {
|
|
142
|
-
return readPersistedTarget(await store.lookup(key));
|
|
143
|
-
} catch (error) {
|
|
144
|
-
disablePersistentApprovalReactionStore(error);
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
92
|
+
function readPersistedTarget(target) {
|
|
93
|
+
const value = target;
|
|
94
|
+
if (!value || typeof value.approvalId !== "string" || !Array.isArray(value.allowedDecisions)) return null;
|
|
95
|
+
return {
|
|
96
|
+
approvalId: value.approvalId,
|
|
97
|
+
...value.approvalKind === "exec" || value.approvalKind === "plugin" ? { approvalKind: value.approvalKind } : {},
|
|
98
|
+
allowedDecisions: value.allowedDecisions
|
|
99
|
+
};
|
|
147
100
|
}
|
|
148
101
|
function listWhatsAppApprovalReactionBindings(allowedDecisions) {
|
|
149
|
-
|
|
150
|
-
return WHATSAPP_APPROVAL_REACTION_ORDER.filter((decision) => allowed.has(decision)).map((decision) => ({
|
|
151
|
-
decision,
|
|
152
|
-
emoji: WHATSAPP_APPROVAL_REACTION_META[decision].emoji,
|
|
153
|
-
label: WHATSAPP_APPROVAL_REACTION_META[decision].label
|
|
154
|
-
}));
|
|
155
|
-
}
|
|
156
|
-
function buildWhatsAppApprovalReactionHint(allowedDecisions) {
|
|
157
|
-
const bindings = listWhatsAppApprovalReactionBindings(allowedDecisions);
|
|
158
|
-
if (bindings.length === 0) return null;
|
|
159
|
-
return `React with:\n\n${bindings.map((binding) => `${binding.emoji} ${binding.label}`).join("\n")}`;
|
|
160
|
-
}
|
|
161
|
-
function insertWhatsAppApprovalReactionHintNearHeader(params) {
|
|
162
|
-
const lines = params.text.split(/\r?\n/);
|
|
163
|
-
const idLineIndex = lines.findIndex((line) => /^ID:\s*\S+/.test(line.trim()));
|
|
164
|
-
if (idLineIndex >= 0) {
|
|
165
|
-
const before = lines.slice(0, idLineIndex + 1).join("\n");
|
|
166
|
-
const after = lines.slice(idLineIndex + 1).join("\n").replace(/^\n+/, "");
|
|
167
|
-
return after ? `${before}\n\n${params.hint}\n\n${after}` : `${before}\n\n${params.hint}`;
|
|
168
|
-
}
|
|
169
|
-
return `${params.hint}\n\n${params.text}`;
|
|
170
|
-
}
|
|
171
|
-
function addWhatsAppApprovalReactionHintToText(params) {
|
|
172
|
-
if (/(^|\n)React with:\s*(\n|$)/i.test(params.text)) return params.text;
|
|
173
|
-
const hint = buildWhatsAppApprovalReactionHint(params.allowedDecisions);
|
|
174
|
-
return hint ? insertWhatsAppApprovalReactionHintNearHeader({
|
|
175
|
-
text: params.text,
|
|
176
|
-
hint
|
|
177
|
-
}) : params.text;
|
|
178
|
-
}
|
|
179
|
-
function appendWhatsAppApprovalReactionHintForOutboundMessage(text) {
|
|
180
|
-
if (/(^|\n)React with:\s*(\n|$)/i.test(text)) return text;
|
|
181
|
-
const binding = extractWhatsAppApprovalPromptBinding(text);
|
|
182
|
-
if (!binding) return text;
|
|
183
|
-
return addWhatsAppApprovalReactionHintToText({
|
|
184
|
-
text,
|
|
185
|
-
allowedDecisions: binding.allowedDecisions
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
function resolveWhatsAppApprovalReactionDecision(reactionKey, allowedDecisions) {
|
|
189
|
-
const normalizedReaction = reactionKey.trim();
|
|
190
|
-
if (!normalizedReaction) return null;
|
|
191
|
-
const allowed = new Set(allowedDecisions);
|
|
192
|
-
for (const decision of WHATSAPP_APPROVAL_REACTION_ORDER) {
|
|
193
|
-
if (!allowed.has(decision)) continue;
|
|
194
|
-
if (WHATSAPP_APPROVAL_REACTION_META[decision].emoji === normalizedReaction) return decision;
|
|
195
|
-
}
|
|
196
|
-
return null;
|
|
102
|
+
return listApprovalReactionBindings({ allowedDecisions });
|
|
197
103
|
}
|
|
198
104
|
function normalizeApprovalDecision(value) {
|
|
199
105
|
const normalized = value.trim().toLowerCase();
|
|
@@ -201,21 +107,23 @@ function normalizeApprovalDecision(value) {
|
|
|
201
107
|
if (normalized === "allow-once" || normalized === "allow-always" || normalized === "deny") return normalized;
|
|
202
108
|
return null;
|
|
203
109
|
}
|
|
110
|
+
const APPROVAL_ID_LINE_RE = /^\s*ID:\s*([A-Za-z0-9][A-Za-z0-9._:-]*)\s*$/i;
|
|
111
|
+
const APPROVE_COMMAND_LINE_RE = /\/approve(?:@[^\s]+)?\s+([A-Za-z0-9][A-Za-z0-9._:-]*)\s+(.+)$/i;
|
|
204
112
|
function extractWhatsAppApprovalPromptBinding(text) {
|
|
113
|
+
const lines = text.split(/\r?\n/);
|
|
114
|
+
const idHeaderMatch = lines.map((line) => line.match(APPROVAL_ID_LINE_RE)).find((match) => Boolean(match));
|
|
115
|
+
if (!idHeaderMatch) return null;
|
|
116
|
+
const approvalId = idHeaderMatch[1];
|
|
205
117
|
const allowedDecisions = [];
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (approvalId && match[1] !== approvalId) continue;
|
|
211
|
-
approvalId ||= match[1];
|
|
212
|
-
const decisions = match[2].split(/[\s|,]+/);
|
|
213
|
-
for (const decisionText of decisions) {
|
|
118
|
+
for (const line of lines) {
|
|
119
|
+
const match = line.match(APPROVE_COMMAND_LINE_RE);
|
|
120
|
+
if (!match || match[1] !== approvalId) continue;
|
|
121
|
+
for (const decisionText of match[2].split(/[\s|,]+/)) {
|
|
214
122
|
const decision = normalizeApprovalDecision(decisionText);
|
|
215
123
|
if (decision && !allowedDecisions.includes(decision)) allowedDecisions.push(decision);
|
|
216
124
|
}
|
|
217
125
|
}
|
|
218
|
-
return
|
|
126
|
+
return allowedDecisions.length > 0 ? {
|
|
219
127
|
approvalId,
|
|
220
128
|
allowedDecisions
|
|
221
129
|
} : null;
|
|
@@ -227,14 +135,10 @@ function registerWhatsAppApprovalReactionTarget(params) {
|
|
|
227
135
|
if (!key || !approvalId || allowedDecisions.length === 0) return null;
|
|
228
136
|
const target = {
|
|
229
137
|
approvalId,
|
|
138
|
+
approvalKind: approvalId.startsWith("plugin:") ? "plugin" : "exec",
|
|
230
139
|
allowedDecisions
|
|
231
140
|
};
|
|
232
|
-
whatsappApprovalReactionTargets.
|
|
233
|
-
rememberPersistentApprovalReactionTarget({
|
|
234
|
-
key,
|
|
235
|
-
target,
|
|
236
|
-
ttlMs: params.ttlMs
|
|
237
|
-
});
|
|
141
|
+
whatsappApprovalReactionTargets.register(key, target, { ttlMs: params.ttlMs });
|
|
238
142
|
return target;
|
|
239
143
|
}
|
|
240
144
|
function registerWhatsAppApprovalReactionTargetForOutboundMessage(params) {
|
|
@@ -253,27 +157,22 @@ function unregisterWhatsAppApprovalReactionTarget(params) {
|
|
|
253
157
|
const key = buildReactionTargetKey(params);
|
|
254
158
|
if (!key) return;
|
|
255
159
|
whatsappApprovalReactionTargets.delete(key);
|
|
256
|
-
forgetPersistentApprovalReactionTarget(key);
|
|
257
160
|
}
|
|
258
161
|
function resolveTarget(params) {
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
162
|
+
const resolved = resolveApprovalReactionTarget({
|
|
163
|
+
target: params.target,
|
|
164
|
+
reactionKey: params.reactionKey
|
|
165
|
+
});
|
|
166
|
+
return resolved ? {
|
|
167
|
+
approvalId: resolved.approvalId,
|
|
168
|
+
decision: resolved.decision
|
|
265
169
|
} : null;
|
|
266
170
|
}
|
|
267
171
|
async function resolveWhatsAppApprovalReactionTargetWithPersistence(params) {
|
|
268
172
|
const key = buildReactionTargetKey(params);
|
|
269
173
|
if (!key) return null;
|
|
270
|
-
const inMemory = resolveTarget({
|
|
271
|
-
target: whatsappApprovalReactionTargets.get(key),
|
|
272
|
-
reactionKey: params.reactionKey
|
|
273
|
-
});
|
|
274
|
-
if (inMemory) return inMemory;
|
|
275
174
|
return resolveTarget({
|
|
276
|
-
target: await
|
|
175
|
+
target: await whatsappApprovalReactionTargets.lookup(key),
|
|
277
176
|
reactionKey: params.reactionKey
|
|
278
177
|
});
|
|
279
178
|
}
|
|
@@ -503,17 +402,16 @@ async function sendMessageWhatsApp(to, body, options) {
|
|
|
503
402
|
...options.quotedMessageKey ? { quotedMessageKey: options.quotedMessageKey } : {},
|
|
504
403
|
accountId
|
|
505
404
|
} : void 0;
|
|
506
|
-
const
|
|
507
|
-
const result = sendOptions ? await active.sendMessage(to, outboundText, mediaBuffer, mediaType, sendOptions) : await active.sendMessage(to, outboundText, mediaBuffer, mediaType);
|
|
405
|
+
const result = sendOptions ? await active.sendMessage(to, text, mediaBuffer, mediaType, sendOptions) : await active.sendMessage(to, text, mediaBuffer, mediaType);
|
|
508
406
|
if (visibleTextAfterVoice) if (sendOptions) await active.sendMessage(to, visibleTextAfterVoice, void 0, void 0, sendOptions);
|
|
509
407
|
else await active.sendMessage(to, visibleTextAfterVoice, void 0, void 0);
|
|
510
408
|
const messageId = result?.messageId ?? "unknown";
|
|
511
409
|
const sentRemoteJid = resolveActualSentRemoteJid(result, jid);
|
|
512
|
-
if (messageId && messageId !== "unknown" &&
|
|
410
|
+
if (messageId && messageId !== "unknown" && text) registerWhatsAppApprovalReactionTargetForOutboundMessage({
|
|
513
411
|
accountId: resolvedAccountId,
|
|
514
412
|
remoteJid: sentRemoteJid,
|
|
515
413
|
messageId,
|
|
516
|
-
text
|
|
414
|
+
text
|
|
517
415
|
});
|
|
518
416
|
const durationMs = Date.now() - startedAt;
|
|
519
417
|
outboundLog.info(`Sent message ${messageId} -> ${redactedJid}${hasMedia ? " (media)" : ""} (${durationMs}ms)`);
|
|
@@ -622,4 +520,4 @@ async function sendPollWhatsApp(to, poll, options) {
|
|
|
622
520
|
}
|
|
623
521
|
}
|
|
624
522
|
//#endregion
|
|
625
|
-
export { send_exports as a,
|
|
523
|
+
export { send_exports as a, unregisterWhatsAppApprovalReactionTarget as c, sendTypingWhatsApp as i, getWhatsAppApprovalApprovers as l, sendPollWhatsApp as n, maybeResolveWhatsAppApprovalReaction as o, sendReactionWhatsApp as r, registerWhatsAppApprovalReactionTarget as s, sendMessageWhatsApp as t, whatsappApprovalAuth as u };
|
|
@@ -99,10 +99,10 @@ async function applyWhatsAppSecurityConfigFixes(params) {
|
|
|
99
99
|
//#region extensions/whatsapp/src/shared.ts
|
|
100
100
|
const WHATSAPP_CHANNEL = "whatsapp";
|
|
101
101
|
async function loadWhatsAppChannelRuntime() {
|
|
102
|
-
return await import("./channel.runtime-
|
|
102
|
+
return await import("./channel.runtime-0kQxYUcI.js");
|
|
103
103
|
}
|
|
104
104
|
async function loadWhatsAppSetupSurface() {
|
|
105
|
-
return await import("./setup-surface-
|
|
105
|
+
return await import("./setup-surface-sCDFlWd2.js");
|
|
106
106
|
}
|
|
107
107
|
const whatsappSetupWizardProxy = createWhatsAppSetupWizardProxy(async () => (await loadWhatsAppSetupSurface()).whatsappSetupWizard);
|
|
108
108
|
const whatsappConfigAdapter = createScopedChannelConfigAdapter({
|
|
@@ -2,7 +2,7 @@ import { r as resolveDefaultWhatsAppAccountId } from "./account-ids-CB5SOWjc.js"
|
|
|
2
2
|
import { r as hasWebCredsSync } from "./creds-files-B1kSWtBg.js";
|
|
3
3
|
import { a as resolveWhatsAppAccount, o as resolveWhatsAppAuthDir } from "./accounts-B3diVrr6.js";
|
|
4
4
|
import { a as normalizeWhatsAppAllowFromEntries, o as normalizeWhatsAppAllowFromEntry } from "./normalize-target-bVWjgftN.js";
|
|
5
|
-
import { t as whatsappSetupAdapter } from "./setup-core-
|
|
5
|
+
import { t as whatsappSetupAdapter } from "./setup-core-mK3yptun.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
|
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-1zhfYJ9v.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-CkiVDt0B.js")).finalizeWhatsAppSetup(params),
|
|
40
40
|
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false),
|
|
41
41
|
onAccountRecorded: (accountId, options) => {
|
|
42
42
|
options?.onAccountId?.(channel, accountId);
|
package/dist/test-api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { t as resolveWhatsAppRuntimeGroupPolicy } from "./runtime-group-policy-DeSRFXEV.js";
|
|
2
|
-
import { t as whatsappOutbound } from "./outbound-adapter-
|
|
2
|
+
import { t as whatsappOutbound } from "./outbound-adapter-BiLBIo1h.js";
|
|
3
3
|
export { resolveWhatsAppRuntimeGroupPolicy, whatsappOutbound };
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/whatsapp",
|
|
3
|
-
"version": "2026.5.26
|
|
3
|
+
"version": "2026.5.26",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/whatsapp",
|
|
9
|
-
"version": "2026.5.26
|
|
9
|
+
"version": "2026.5.26",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"audio-decode": "2.2.3",
|
|
12
12
|
"baileys": "7.0.0-rc13",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"typebox": "1.1.38"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"openclaw": ">=2026.5.26
|
|
17
|
+
"openclaw": ">=2026.5.26"
|
|
18
18
|
},
|
|
19
19
|
"peerDependenciesMeta": {
|
|
20
20
|
"openclaw": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/whatsapp",
|
|
3
|
-
"version": "2026.5.26
|
|
3
|
+
"version": "2026.5.26",
|
|
4
4
|
"description": "OpenClaw WhatsApp channel plugin",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"typebox": "1.1.38"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"openclaw": ">=2026.5.26
|
|
17
|
+
"openclaw": ">=2026.5.26"
|
|
18
18
|
},
|
|
19
19
|
"peerDependenciesMeta": {
|
|
20
20
|
"openclaw": {
|
|
@@ -57,10 +57,10 @@
|
|
|
57
57
|
"minHostVersion": ">=2026.4.25"
|
|
58
58
|
},
|
|
59
59
|
"compat": {
|
|
60
|
-
"pluginApi": ">=2026.5.26
|
|
60
|
+
"pluginApi": ">=2026.5.26"
|
|
61
61
|
},
|
|
62
62
|
"build": {
|
|
63
|
-
"openclawVersion": "2026.5.26
|
|
63
|
+
"openclawVersion": "2026.5.26"
|
|
64
64
|
},
|
|
65
65
|
"release": {
|
|
66
66
|
"publishToClawHub": true,
|