@openclaw/whatsapp 2026.5.2 → 2026.5.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-control-BQ3tCkH8.js +288 -0
- package/dist/account-config-CNQ33oav.js +47 -0
- package/dist/account-ids-DG18xddX.js +5 -0
- package/dist/accounts-BDqgpFEB.js +116 -0
- package/dist/action-runtime-DTGNgG-i.js +74 -0
- package/dist/action-runtime-api.js +2 -0
- package/dist/action-runtime.runtime.js +2 -0
- package/dist/active-listener-N7GFKsuN.js +11 -0
- package/dist/agent-tools-login-DpRxLNRB.js +89 -0
- package/dist/api.js +148 -0
- package/dist/audio-preflight.runtime-Bcdsl_ri.js +7 -0
- package/dist/auth-presence.js +32 -0
- package/dist/auth-store-BjCb50Ry.js +381 -0
- package/dist/channel-DQ-5Xoj9.js +542 -0
- package/dist/channel-config-api.js +2 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel-react-action-Df20qAy9.js +42 -0
- package/dist/channel.runtime-DKXRnA8x.js +55 -0
- package/dist/channel.setup-DOHR2BGp.js +20 -0
- package/dist/command-policy-O8sRnqUV.js +8 -0
- package/dist/config-schema-Dmo66Ubb.js +27 -0
- package/dist/connection-controller-BiHAsTM8.js +596 -0
- package/dist/connection-controller-registry-D_iIGz5m.js +22 -0
- package/dist/constants-DLGCIbfl.js +4 -0
- package/dist/constants.js +2 -0
- package/dist/contract-api.js +19 -0
- package/dist/creds-files-_2V8jzQa.js +19 -0
- package/dist/directory-config-DVs4ffXu.js +37 -0
- package/dist/directory-contract-api.js +2 -0
- package/dist/doctor-A9tXm9Om.js +48 -0
- package/dist/doctor-contract-api.js +10 -0
- package/dist/group-session-contract-B8QBn0I2.js +15 -0
- package/dist/identity-QHAlV7Fu.js +75 -0
- package/dist/index.js +18 -0
- package/dist/legacy-session-surface-api.js +8 -0
- package/dist/legacy-state-migrations-api.js +2 -0
- package/dist/light-runtime-api.js +5 -0
- package/dist/login-DymdrKca.js +52 -0
- package/dist/login-qr-DIS0Iv-7.js +378 -0
- package/dist/login-qr-api.js +2 -0
- package/dist/login-qr-runtime.js +16 -0
- package/dist/monitor-C4Fhg_lD.js +3349 -0
- package/dist/normalize-CWYiGkXw.js +2 -0
- package/dist/normalize-target-BPVHNsM5.js +74 -0
- package/dist/outbound-adapter-BssVnZdz.js +29 -0
- package/dist/outbound-base-Bq1UYEK5.js +119 -0
- package/dist/outbound-media-contract-CGss_QHy.js +163 -0
- package/dist/outbound-payload-test-api.js +2 -0
- package/dist/quoted-message-TENQzyxV.js +108 -0
- package/dist/reaction-level-CRVEVAfi.js +16 -0
- package/dist/reply-resolver.runtime-BRCgoO4C.js +2 -0
- package/dist/resolve-outbound-target-CN-Wo6IY.js +39 -0
- package/dist/rolldown-runtime-RkAeH_Qm.js +27 -0
- package/dist/runtime-6fZ67abR.js +8 -0
- package/dist/runtime-api.js +15 -0
- package/dist/runtime-group-policy-Gp1lQ0at.js +11 -0
- package/dist/secret-contract-api.js +5 -0
- package/dist/security-contract-DqH8JDX6.js +26 -0
- package/dist/security-contract-api.js +2 -0
- package/dist/send-CIyLFxdZ.js +234 -0
- package/dist/session-contract-B0efQf9P.js +27 -0
- package/dist/session-errors-CSuKZPub.js +63 -0
- package/dist/session.runtime-C1eSE_KK.js +13 -0
- package/dist/setup-core-DZKvpzbH.js +46 -0
- package/dist/setup-entry.js +23 -0
- package/dist/setup-plugin-api.js +2 -0
- package/dist/setup-surface-ieFnIW4g.js +344 -0
- package/dist/shared-D_wzSVar.js +307 -0
- package/dist/state-migrations-DnCdvoYD.js +39 -0
- package/dist/targets.js +2 -0
- package/dist/test-api.js +3 -0
- package/dist/text-runtime-C1zNiZeO.js +116 -0
- package/package.json +14 -6
- package/action-runtime-api.ts +0 -1
- package/action-runtime.runtime.ts +0 -1
- package/api.ts +0 -213
- package/auth-presence.ts +0 -80
- package/channel-config-api.ts +0 -1
- package/channel-plugin-api.ts +0 -3
- package/config-api.ts +0 -4
- package/constants.ts +0 -1
- package/contract-api.ts +0 -29
- package/directory-contract-api.ts +0 -4
- package/doctor-contract-api.ts +0 -8
- package/index.test.ts +0 -13
- package/index.ts +0 -16
- package/legacy-session-surface-api.ts +0 -6
- package/legacy-state-migrations-api.ts +0 -1
- package/light-runtime-api.ts +0 -12
- package/login-qr-api.ts +0 -1
- package/login-qr-runtime.ts +0 -23
- package/outbound-payload-test-api.ts +0 -1
- package/runtime-api.ts +0 -84
- package/secret-contract-api.ts +0 -4
- package/security-contract-api.ts +0 -4
- package/setup-entry.test.ts +0 -21
- package/setup-entry.ts +0 -21
- package/setup-plugin-api.ts +0 -3
- package/src/account-config.ts +0 -77
- package/src/account-ids.ts +0 -13
- package/src/account-types.ts +0 -5
- package/src/accounts.test.ts +0 -182
- package/src/accounts.ts +0 -176
- package/src/accounts.whatsapp-auth.test.ts +0 -59
- package/src/action-runtime-target-auth.ts +0 -27
- package/src/action-runtime.test.ts +0 -330
- package/src/action-runtime.ts +0 -76
- package/src/active-listener.test.ts +0 -65
- package/src/active-listener.ts +0 -17
- package/src/agent-tools-login.test.ts +0 -81
- package/src/agent-tools-login.ts +0 -113
- package/src/approval-auth.test.ts +0 -24
- package/src/approval-auth.ts +0 -27
- package/src/auth-store.runtime.ts +0 -1
- package/src/auth-store.test.ts +0 -311
- package/src/auth-store.ts +0 -502
- package/src/auto-reply/config.runtime.ts +0 -16
- package/src/auto-reply/constants.ts +0 -1
- package/src/auto-reply/deliver-reply.test.ts +0 -843
- package/src/auto-reply/deliver-reply.ts +0 -279
- package/src/auto-reply/loggers.ts +0 -6
- package/src/auto-reply/mentions.ts +0 -131
- package/src/auto-reply/monitor/ack-reaction.test.ts +0 -170
- package/src/auto-reply/monitor/ack-reaction.ts +0 -99
- package/src/auto-reply/monitor/audio-preflight.runtime.ts +0 -9
- package/src/auto-reply/monitor/broadcast.ts +0 -153
- package/src/auto-reply/monitor/commands.ts +0 -19
- package/src/auto-reply/monitor/echo.ts +0 -64
- package/src/auto-reply/monitor/group-activation.runtime.ts +0 -1
- package/src/auto-reply/monitor/group-activation.test.ts +0 -189
- package/src/auto-reply/monitor/group-activation.ts +0 -73
- package/src/auto-reply/monitor/group-gating.audio-preflight.test.ts +0 -103
- package/src/auto-reply/monitor/group-gating.runtime.ts +0 -8
- package/src/auto-reply/monitor/group-gating.ts +0 -217
- package/src/auto-reply/monitor/group-members.test.ts +0 -56
- package/src/auto-reply/monitor/group-members.ts +0 -65
- package/src/auto-reply/monitor/inbound-context.test.ts +0 -97
- package/src/auto-reply/monitor/inbound-context.ts +0 -92
- package/src/auto-reply/monitor/inbound-dispatch.runtime.ts +0 -21
- package/src/auto-reply/monitor/inbound-dispatch.test.ts +0 -895
- package/src/auto-reply/monitor/inbound-dispatch.ts +0 -422
- package/src/auto-reply/monitor/last-route.test.ts +0 -37
- package/src/auto-reply/monitor/last-route.ts +0 -61
- package/src/auto-reply/monitor/message-line.runtime.ts +0 -38
- package/src/auto-reply/monitor/message-line.ts +0 -54
- package/src/auto-reply/monitor/on-message.audio-preflight.test.ts +0 -354
- package/src/auto-reply/monitor/on-message.ts +0 -291
- package/src/auto-reply/monitor/peer.ts +0 -17
- package/src/auto-reply/monitor/process-message.audio-preflight.test.ts +0 -420
- package/src/auto-reply/monitor/process-message.test.ts +0 -355
- package/src/auto-reply/monitor/process-message.ts +0 -531
- package/src/auto-reply/monitor/runtime-api.ts +0 -30
- package/src/auto-reply/monitor-state.test.ts +0 -64
- package/src/auto-reply/monitor-state.ts +0 -106
- package/src/auto-reply/monitor.ts +0 -600
- package/src/auto-reply/reply-resolver.runtime.ts +0 -1
- package/src/auto-reply/types.ts +0 -48
- package/src/auto-reply/util.ts +0 -63
- package/src/auto-reply/web-auto-reply-monitor.test.ts +0 -687
- package/src/auto-reply/web-auto-reply-utils.test.ts +0 -392
- package/src/auto-reply.broadcast-groups.combined.test.ts +0 -246
- package/src/auto-reply.broadcast-groups.test-harness.ts +0 -47
- package/src/auto-reply.impl.ts +0 -6
- package/src/auto-reply.test-harness.ts +0 -421
- package/src/auto-reply.ts +0 -1
- package/src/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts +0 -427
- package/src/auto-reply.web-auto-reply.connection-and-logging.e2e.test.ts +0 -908
- package/src/auto-reply.web-auto-reply.last-route.test.ts +0 -184
- package/src/channel-actions.runtime.ts +0 -7
- package/src/channel-actions.test.ts +0 -216
- package/src/channel-actions.ts +0 -84
- package/src/channel-outbound.test.ts +0 -131
- package/src/channel-outbound.ts +0 -36
- package/src/channel-react-action.runtime.ts +0 -7
- package/src/channel-react-action.test.ts +0 -294
- package/src/channel-react-action.ts +0 -84
- package/src/channel.runtime.ts +0 -117
- package/src/channel.setup.test.ts +0 -461
- package/src/channel.setup.ts +0 -28
- package/src/channel.ts +0 -339
- package/src/command-policy.ts +0 -7
- package/src/config-accessors.test.ts +0 -34
- package/src/config-accessors.ts +0 -22
- package/src/config-schema.test.ts +0 -121
- package/src/config-schema.ts +0 -6
- package/src/config-ui-hints.ts +0 -24
- package/src/connection-controller-registry.test.ts +0 -27
- package/src/connection-controller-registry.ts +0 -49
- package/src/connection-controller.test.ts +0 -282
- package/src/connection-controller.ts +0 -679
- package/src/creds-files.ts +0 -19
- package/src/creds-persistence.ts +0 -102
- package/src/directory-config.test.ts +0 -60
- package/src/directory-config.ts +0 -40
- package/src/directory-contract.test.ts +0 -56
- package/src/doctor-contract.ts +0 -11
- package/src/doctor.test.ts +0 -74
- package/src/doctor.ts +0 -56
- package/src/group-intro.ts +0 -15
- package/src/group-policy.test.ts +0 -36
- package/src/group-policy.ts +0 -40
- package/src/group-session-contract.ts +0 -20
- package/src/group-session-key.test.ts +0 -53
- package/src/group-session-key.ts +0 -41
- package/src/heartbeat.ts +0 -34
- package/src/identity.ts +0 -164
- package/src/inbound/access-control.test-harness.ts +0 -37
- package/src/inbound/access-control.test.ts +0 -375
- package/src/inbound/access-control.ts +0 -237
- package/src/inbound/dedupe.ts +0 -132
- package/src/inbound/extract.test.ts +0 -282
- package/src/inbound/extract.ts +0 -488
- package/src/inbound/lifecycle.ts +0 -39
- package/src/inbound/media.node.test.ts +0 -83
- package/src/inbound/media.ts +0 -102
- package/src/inbound/monitor.ts +0 -890
- package/src/inbound/runtime-api.ts +0 -7
- package/src/inbound/save-media.runtime.ts +0 -1
- package/src/inbound/send-api.test.ts +0 -319
- package/src/inbound/send-api.ts +0 -145
- package/src/inbound/send-result.ts +0 -61
- package/src/inbound/types.ts +0 -106
- package/src/inbound-context.contract.test.ts +0 -32
- package/src/inbound-policy.ts +0 -231
- package/src/inbound.media.test.ts +0 -320
- package/src/inbound.test.ts +0 -290
- package/src/inbound.ts +0 -9
- package/src/login-qr.test.ts +0 -483
- package/src/login-qr.ts +0 -542
- package/src/login.coverage.test.ts +0 -133
- package/src/login.test.ts +0 -89
- package/src/login.ts +0 -70
- package/src/logout.test.ts +0 -162
- package/src/media.test.ts +0 -480
- package/src/media.ts +0 -10
- package/src/monitor-inbox.allows-messages-from-senders-allowfrom-list.test-support.ts +0 -400
- package/src/monitor-inbox.append-upsert.test-support.ts +0 -133
- package/src/monitor-inbox.behavior.test.ts +0 -5
- package/src/monitor-inbox.blocks-messages-from-unauthorized-senders-not-allowfrom.test-support.ts +0 -362
- package/src/monitor-inbox.captures-media-path-image-messages.test-support.ts +0 -306
- package/src/monitor-inbox.streams-inbound-messages.test-support.ts +0 -729
- package/src/monitor-inbox.test-harness.ts +0 -304
- package/src/normalize-target.ts +0 -123
- package/src/normalize.ts +0 -7
- package/src/outbound-adapter.poll.test.ts +0 -62
- package/src/outbound-adapter.sendpayload.test.ts +0 -195
- package/src/outbound-adapter.ts +0 -36
- package/src/outbound-base.test.ts +0 -560
- package/src/outbound-base.ts +0 -244
- package/src/outbound-media-contract.ts +0 -278
- package/src/outbound-media.runtime.ts +0 -36
- package/src/outbound-payload.contract.test.ts +0 -61
- package/src/outbound-send-deps.ts +0 -1
- package/src/outbound-test-support.ts +0 -16
- package/src/pairing-security.test-harness.ts +0 -59
- package/src/qr-image.ts +0 -1
- package/src/qr-terminal.ts +0 -1
- package/src/quoted-message.test.ts +0 -83
- package/src/quoted-message.ts +0 -184
- package/src/reaction-level.test.ts +0 -94
- package/src/reaction-level.ts +0 -21
- package/src/reconnect.test.ts +0 -51
- package/src/reconnect.ts +0 -55
- package/src/resolve-outbound-target.test.ts +0 -288
- package/src/resolve-outbound-target.ts +0 -58
- package/src/resolve-target.test.ts +0 -120
- package/src/runtime-api.ts +0 -59
- package/src/runtime-group-policy.ts +0 -16
- package/src/runtime.ts +0 -9
- package/src/security-contract.ts +0 -47
- package/src/security-fix.ts +0 -71
- package/src/send.test.ts +0 -534
- package/src/send.ts +0 -292
- package/src/session-contract.test.ts +0 -31
- package/src/session-contract.ts +0 -43
- package/src/session-errors.ts +0 -125
- package/src/session-route.test.ts +0 -41
- package/src/session-route.ts +0 -32
- package/src/session.runtime.ts +0 -8
- package/src/session.test.ts +0 -559
- package/src/session.ts +0 -330
- package/src/setup-core.ts +0 -52
- package/src/setup-finalize.ts +0 -446
- package/src/setup-surface.test.ts +0 -367
- package/src/setup-surface.ts +0 -69
- package/src/setup-test-helpers.ts +0 -216
- package/src/shared.ts +0 -291
- package/src/socket-timing.test.ts +0 -49
- package/src/socket-timing.ts +0 -38
- package/src/state-migrations.ts +0 -54
- package/src/status-issues.test.ts +0 -137
- package/src/status-issues.ts +0 -185
- package/src/system-prompt.test.ts +0 -199
- package/src/system-prompt.ts +0 -31
- package/src/targets-runtime.ts +0 -180
- package/src/test-helpers.ts +0 -690
- package/src/text-runtime.test.ts +0 -162
- package/src/text-runtime.ts +0 -11
- package/src/vcard.ts +0 -84
- package/targets.ts +0 -5
- package/test-api.ts +0 -2
- package/tsconfig.json +0 -16
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
import { t as listAccountIds } from "./account-ids-DG18xddX.js";
|
|
2
|
+
import { a as resolveWhatsAppAccount } from "./accounts-BDqgpFEB.js";
|
|
3
|
+
import { i as looksLikeWhatsAppTargetId, n as isWhatsAppNewsletterJid, o as normalizeWhatsAppMessagingTarget, s as normalizeWhatsAppTarget, t as isWhatsAppGroupJid } from "./normalize-target-BPVHNsM5.js";
|
|
4
|
+
import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-CN-Wo6IY.js";
|
|
5
|
+
import { t as resolveWhatsAppReactionLevel } from "./reaction-level-CRVEVAfi.js";
|
|
6
|
+
import "./normalize-CWYiGkXw.js";
|
|
7
|
+
import { r as normalizeWhatsAppPayloadTextPreservingIndentation } from "./outbound-media-contract-CGss_QHy.js";
|
|
8
|
+
import { i as sendTypingWhatsApp, n as sendPollWhatsApp, t as sendMessageWhatsApp } from "./send-CIyLFxdZ.js";
|
|
9
|
+
import { t as createWhatsAppLoginTool } from "./agent-tools-login-DpRxLNRB.js";
|
|
10
|
+
import { t as createWhatsAppOutboundBase } from "./outbound-base-Bq1UYEK5.js";
|
|
11
|
+
import { t as getWhatsAppRuntime } from "./runtime-6fZ67abR.js";
|
|
12
|
+
import { t as whatsappCommandPolicy } from "./command-policy-O8sRnqUV.js";
|
|
13
|
+
import { a as resolveWhatsAppGroupToolPolicy, c as formatWhatsAppConfigAllowFromEntries, i as resolveWhatsAppGroupRequireMention, n as loadWhatsAppChannelRuntime, o as resolveWhatsAppGroupIntroHint, r as whatsappSetupWizardProxy, s as resolveWhatsAppMentionStripRegexes, t as createWhatsAppPluginBase } from "./shared-D_wzSVar.js";
|
|
14
|
+
import { d as readWebAuthExistsForDecision, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-BjCb50Ry.js";
|
|
15
|
+
import { t as whatsappSetupAdapter } from "./setup-core-DZKvpzbH.js";
|
|
16
|
+
import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-DnCdvoYD.js";
|
|
17
|
+
import { createActionGate as createActionGate$1 } from "openclaw/plugin-sdk/channel-actions";
|
|
18
|
+
import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
|
|
19
|
+
import { buildChannelOutboundSessionRoute } from "openclaw/plugin-sdk/core";
|
|
20
|
+
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
21
|
+
import { buildDmGroupAccountAllowlistAdapter } from "openclaw/plugin-sdk/allowlist-config-edit";
|
|
22
|
+
import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
23
|
+
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
24
|
+
import { asString, collectIssuesForEnabledAccounts, createAsyncComputedAccountStatusAdapter, createDefaultChannelRuntimeState, isRecord } from "openclaw/plugin-sdk/status-helpers";
|
|
25
|
+
import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
26
|
+
import { chunkText } from "openclaw/plugin-sdk/reply-chunking";
|
|
27
|
+
//#region extensions/whatsapp/src/approval-auth.ts
|
|
28
|
+
function normalizeWhatsAppApproverId(value) {
|
|
29
|
+
const normalized = normalizeWhatsAppTarget(String(value));
|
|
30
|
+
if (!normalized || normalized.endsWith("@g.us")) return;
|
|
31
|
+
return normalized;
|
|
32
|
+
}
|
|
33
|
+
const whatsappApprovalAuth = createResolvedApproverActionAuthAdapter({
|
|
34
|
+
channelLabel: "WhatsApp",
|
|
35
|
+
resolveApprovers: ({ cfg, accountId }) => {
|
|
36
|
+
const account = resolveWhatsAppAccount({
|
|
37
|
+
cfg,
|
|
38
|
+
accountId
|
|
39
|
+
});
|
|
40
|
+
return resolveApprovalApprovers({
|
|
41
|
+
allowFrom: account.allowFrom,
|
|
42
|
+
defaultTo: account.defaultTo,
|
|
43
|
+
normalizeApprover: normalizeWhatsAppApproverId
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
normalizeSenderId: (value) => normalizeWhatsAppApproverId(value)
|
|
47
|
+
});
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region extensions/whatsapp/src/channel-actions.ts
|
|
50
|
+
function areWhatsAppAgentReactionsEnabled(params) {
|
|
51
|
+
if (!params.cfg.channels?.whatsapp) return false;
|
|
52
|
+
if (!createActionGate$1(params.cfg.channels.whatsapp.actions)("reactions")) return false;
|
|
53
|
+
return resolveWhatsAppReactionLevel({
|
|
54
|
+
cfg: params.cfg,
|
|
55
|
+
accountId: params.accountId
|
|
56
|
+
}).agentReactionsEnabled;
|
|
57
|
+
}
|
|
58
|
+
function hasAnyWhatsAppAccountWithAgentReactionsEnabled(cfg) {
|
|
59
|
+
if (!cfg.channels?.whatsapp) return false;
|
|
60
|
+
return listAccountIds(cfg).some((accountId) => {
|
|
61
|
+
if (!resolveWhatsAppAccount({
|
|
62
|
+
cfg,
|
|
63
|
+
accountId
|
|
64
|
+
}).enabled) return false;
|
|
65
|
+
return areWhatsAppAgentReactionsEnabled({
|
|
66
|
+
cfg,
|
|
67
|
+
accountId
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function resolveWhatsAppAgentReactionGuidance(params) {
|
|
72
|
+
if (!params.cfg.channels?.whatsapp) return;
|
|
73
|
+
if (!createActionGate$1(params.cfg.channels.whatsapp.actions)("reactions")) return;
|
|
74
|
+
const resolved = resolveWhatsAppReactionLevel({
|
|
75
|
+
cfg: params.cfg,
|
|
76
|
+
accountId: params.accountId
|
|
77
|
+
});
|
|
78
|
+
if (!resolved.agentReactionsEnabled) return;
|
|
79
|
+
return resolved.agentReactionGuidance;
|
|
80
|
+
}
|
|
81
|
+
function describeWhatsAppMessageActions(params) {
|
|
82
|
+
if (!params.cfg.channels?.whatsapp) return null;
|
|
83
|
+
const gate = createActionGate$1(params.cfg.channels.whatsapp.actions);
|
|
84
|
+
const actions = /* @__PURE__ */ new Set();
|
|
85
|
+
if (params.accountId != null ? areWhatsAppAgentReactionsEnabled({
|
|
86
|
+
cfg: params.cfg,
|
|
87
|
+
accountId: params.accountId ?? void 0
|
|
88
|
+
}) : hasAnyWhatsAppAccountWithAgentReactionsEnabled(params.cfg)) actions.add("react");
|
|
89
|
+
if (gate("polls")) actions.add("poll");
|
|
90
|
+
return { actions: Array.from(actions) };
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region extensions/whatsapp/src/channel-outbound.ts
|
|
94
|
+
function normalizeWhatsAppChannelPayloadText(text) {
|
|
95
|
+
return normalizeWhatsAppPayloadTextPreservingIndentation(text);
|
|
96
|
+
}
|
|
97
|
+
function normalizeWhatsAppChannelSendText(text) {
|
|
98
|
+
const normalized = normalizeWhatsAppChannelPayloadText(text);
|
|
99
|
+
return normalized.trim() ? normalized : "";
|
|
100
|
+
}
|
|
101
|
+
const whatsappChannelOutbound = {
|
|
102
|
+
...createWhatsAppOutboundBase({
|
|
103
|
+
chunker: chunkText,
|
|
104
|
+
sendMessageWhatsApp: async (to, text, options) => await sendMessageWhatsApp(to, text, {
|
|
105
|
+
...options,
|
|
106
|
+
preserveLeadingWhitespace: true
|
|
107
|
+
}),
|
|
108
|
+
sendPollWhatsApp,
|
|
109
|
+
shouldLogVerbose: () => getWhatsAppRuntime().logging.shouldLogVerbose(),
|
|
110
|
+
resolveTarget: ({ to, allowFrom, mode }) => resolveWhatsAppOutboundTarget({
|
|
111
|
+
to,
|
|
112
|
+
allowFrom,
|
|
113
|
+
mode
|
|
114
|
+
}),
|
|
115
|
+
normalizeText: normalizeWhatsAppChannelSendText
|
|
116
|
+
}),
|
|
117
|
+
sendTextOnlyErrorPayloads: true,
|
|
118
|
+
normalizePayload: ({ payload }) => ({
|
|
119
|
+
...payload,
|
|
120
|
+
text: normalizeWhatsAppChannelPayloadText(payload.text)
|
|
121
|
+
})
|
|
122
|
+
};
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region extensions/whatsapp/src/heartbeat.ts
|
|
125
|
+
async function checkWhatsAppHeartbeatReady(params) {
|
|
126
|
+
if (params.cfg.web?.enabled === false) return {
|
|
127
|
+
ok: false,
|
|
128
|
+
reason: "whatsapp-disabled"
|
|
129
|
+
};
|
|
130
|
+
const account = resolveWhatsAppAccount({
|
|
131
|
+
cfg: params.cfg,
|
|
132
|
+
accountId: params.accountId
|
|
133
|
+
});
|
|
134
|
+
const authState = await (params.deps?.readWebAuthExistsForDecision ?? readWebAuthExistsForDecision)(account.authDir);
|
|
135
|
+
if (authState.outcome === "unstable") return {
|
|
136
|
+
ok: false,
|
|
137
|
+
reason: WHATSAPP_AUTH_UNSTABLE_CODE
|
|
138
|
+
};
|
|
139
|
+
if (!authState.exists) return {
|
|
140
|
+
ok: false,
|
|
141
|
+
reason: "whatsapp-not-linked"
|
|
142
|
+
};
|
|
143
|
+
if (!(params.deps?.hasActiveWebListener ? params.deps.hasActiveWebListener(account.accountId) : Boolean((await loadWhatsAppChannelRuntime()).getActiveWebListener(account.accountId)))) return {
|
|
144
|
+
ok: false,
|
|
145
|
+
reason: "whatsapp-not-running"
|
|
146
|
+
};
|
|
147
|
+
return {
|
|
148
|
+
ok: true,
|
|
149
|
+
reason: "ok"
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region extensions/whatsapp/src/session-route.ts
|
|
154
|
+
function resolveWhatsAppOutboundSessionRoute(params) {
|
|
155
|
+
const normalized = normalizeWhatsAppTarget(params.target);
|
|
156
|
+
if (!normalized) return null;
|
|
157
|
+
const isGroup = isWhatsAppGroupJid(normalized);
|
|
158
|
+
const isNewsletter = isWhatsAppNewsletterJid(normalized);
|
|
159
|
+
const chatType = isGroup ? "group" : isNewsletter ? "channel" : "direct";
|
|
160
|
+
return buildChannelOutboundSessionRoute({
|
|
161
|
+
cfg: params.cfg,
|
|
162
|
+
agentId: params.agentId,
|
|
163
|
+
channel: "whatsapp",
|
|
164
|
+
accountId: params.accountId,
|
|
165
|
+
peer: {
|
|
166
|
+
kind: chatType,
|
|
167
|
+
id: normalized
|
|
168
|
+
},
|
|
169
|
+
chatType,
|
|
170
|
+
from: normalized,
|
|
171
|
+
to: normalized
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region extensions/whatsapp/src/status-issues.ts
|
|
176
|
+
const RECENT_DISCONNECT_WARNING_WINDOW_MS = 900 * 1e3;
|
|
177
|
+
function readWhatsAppAccountStatus(value) {
|
|
178
|
+
if (!isRecord(value)) return null;
|
|
179
|
+
return {
|
|
180
|
+
accountId: value.accountId,
|
|
181
|
+
statusState: value.statusState,
|
|
182
|
+
enabled: value.enabled,
|
|
183
|
+
linked: value.linked,
|
|
184
|
+
connected: value.connected,
|
|
185
|
+
running: value.running,
|
|
186
|
+
reconnectAttempts: value.reconnectAttempts,
|
|
187
|
+
lastDisconnect: value.lastDisconnect,
|
|
188
|
+
lastInboundAt: value.lastInboundAt,
|
|
189
|
+
lastError: value.lastError,
|
|
190
|
+
healthState: value.healthState
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function readLastDisconnect(value) {
|
|
194
|
+
if (typeof value === "string") {
|
|
195
|
+
const error = asString(value);
|
|
196
|
+
return error ? {
|
|
197
|
+
at: null,
|
|
198
|
+
error
|
|
199
|
+
} : null;
|
|
200
|
+
}
|
|
201
|
+
if (!isRecord(value)) return null;
|
|
202
|
+
return {
|
|
203
|
+
at: typeof value.at === "number" ? value.at : null,
|
|
204
|
+
error: asString(value.error)
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function isRecentDisconnect(disconnect, now = Date.now()) {
|
|
208
|
+
if (disconnect?.at == null) return false;
|
|
209
|
+
return now - disconnect.at <= RECENT_DISCONNECT_WARNING_WINDOW_MS;
|
|
210
|
+
}
|
|
211
|
+
function collectWhatsAppStatusIssues(accounts) {
|
|
212
|
+
return collectIssuesForEnabledAccounts({
|
|
213
|
+
accounts,
|
|
214
|
+
readAccount: readWhatsAppAccountStatus,
|
|
215
|
+
collectIssues: ({ account, accountId, issues }) => {
|
|
216
|
+
const linked = account.linked === true;
|
|
217
|
+
const statusState = asString(account.statusState);
|
|
218
|
+
const running = account.running === true;
|
|
219
|
+
const connected = account.connected === true;
|
|
220
|
+
const reconnectAttempts = typeof account.reconnectAttempts === "number" ? account.reconnectAttempts : null;
|
|
221
|
+
const lastInboundAt = typeof account.lastInboundAt === "number" ? account.lastInboundAt : null;
|
|
222
|
+
const lastDisconnect = readLastDisconnect(account.lastDisconnect);
|
|
223
|
+
const lastError = asString(account.lastError) ?? lastDisconnect?.error;
|
|
224
|
+
const healthState = asString(account.healthState);
|
|
225
|
+
if (statusState === "unstable") {
|
|
226
|
+
issues.push({
|
|
227
|
+
channel: "whatsapp",
|
|
228
|
+
accountId,
|
|
229
|
+
kind: "auth",
|
|
230
|
+
message: "Auth state is still stabilizing.",
|
|
231
|
+
fix: "Wait a moment for queued credential writes to finish, then retry the command or rerun health."
|
|
232
|
+
});
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (!linked) {
|
|
236
|
+
issues.push({
|
|
237
|
+
channel: "whatsapp",
|
|
238
|
+
accountId,
|
|
239
|
+
kind: "auth",
|
|
240
|
+
message: "Not linked (no WhatsApp Web session).",
|
|
241
|
+
fix: `Run: ${formatCliCommand("openclaw channels login")} (scan QR on the gateway host).`
|
|
242
|
+
});
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (healthState === "stale") {
|
|
246
|
+
const staleSuffix = lastInboundAt != null ? ` (last inbound ${Math.max(0, Math.floor((Date.now() - lastInboundAt) / 6e4))}m ago)` : "";
|
|
247
|
+
issues.push({
|
|
248
|
+
channel: "whatsapp",
|
|
249
|
+
accountId,
|
|
250
|
+
kind: "runtime",
|
|
251
|
+
message: `Linked but stale${staleSuffix}${lastError ? `: ${lastError}` : "."}`,
|
|
252
|
+
fix: `Run: ${formatCliCommand("openclaw doctor")} (or restart the gateway). If it persists, relink via channels login and check logs.`
|
|
253
|
+
});
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (healthState === "reconnecting" || healthState === "conflict" || healthState === "stopped") {
|
|
257
|
+
const stateLabel = healthState === "conflict" ? "session conflict" : healthState === "reconnecting" ? "reconnecting" : "stopped";
|
|
258
|
+
issues.push({
|
|
259
|
+
channel: "whatsapp",
|
|
260
|
+
accountId,
|
|
261
|
+
kind: "runtime",
|
|
262
|
+
message: `Linked but ${stateLabel}${reconnectAttempts != null ? ` (reconnectAttempts=${reconnectAttempts})` : ""}${lastError ? `: ${lastError}` : "."}`,
|
|
263
|
+
fix: `Run: ${formatCliCommand("openclaw doctor")} (or restart the gateway). If it persists, relink via channels login and check logs.`
|
|
264
|
+
});
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (healthState === "logged-out") {
|
|
268
|
+
issues.push({
|
|
269
|
+
channel: "whatsapp",
|
|
270
|
+
accountId,
|
|
271
|
+
kind: "auth",
|
|
272
|
+
message: `Linked session logged out${lastError ? `: ${lastError}` : "."}`,
|
|
273
|
+
fix: `Run: ${formatCliCommand("openclaw channels login")} (scan QR on the gateway host).`
|
|
274
|
+
});
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (linked && running && connected && reconnectAttempts != null && reconnectAttempts > 0 && isRecentDisconnect(lastDisconnect)) {
|
|
278
|
+
issues.push({
|
|
279
|
+
channel: "whatsapp",
|
|
280
|
+
accountId,
|
|
281
|
+
kind: "runtime",
|
|
282
|
+
message: `Linked but recently reconnected (reconnectAttempts=${reconnectAttempts})${lastError ? `: ${lastError}` : "."}`,
|
|
283
|
+
fix: `Watch: ${formatCliCommand("openclaw logs --follow")} and run ${formatCliCommand("openclaw channels status --probe")} if disconnects continue. If it keeps flapping, restart the gateway or relink via channels login.`
|
|
284
|
+
});
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (running && !connected) issues.push({
|
|
288
|
+
channel: "whatsapp",
|
|
289
|
+
accountId,
|
|
290
|
+
kind: "runtime",
|
|
291
|
+
message: `Linked but disconnected${reconnectAttempts != null ? ` (reconnectAttempts=${reconnectAttempts})` : ""}${lastError ? `: ${lastError}` : "."}`,
|
|
292
|
+
fix: `Run: ${formatCliCommand("openclaw doctor")} (or restart the gateway). If it persists, relink via channels login and check logs.`
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region extensions/whatsapp/src/channel.ts
|
|
299
|
+
const loadWhatsAppDirectoryConfig = createLazyRuntimeModule(() => import("./directory-config-DVs4ffXu.js").then((n) => n.t));
|
|
300
|
+
const loadWhatsAppChannelReactAction = createLazyRuntimeModule(() => import("./channel-react-action-Df20qAy9.js"));
|
|
301
|
+
function parseWhatsAppExplicitTarget(raw) {
|
|
302
|
+
const normalized = normalizeWhatsAppTarget(raw);
|
|
303
|
+
if (!normalized) return null;
|
|
304
|
+
return {
|
|
305
|
+
to: normalized,
|
|
306
|
+
chatType: isWhatsAppGroupJid(normalized) ? "group" : isWhatsAppNewsletterJid(normalized) ? "channel" : "direct"
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const whatsappPlugin = createChatChannelPlugin({
|
|
310
|
+
pairing: { idLabel: "whatsappSenderId" },
|
|
311
|
+
outbound: whatsappChannelOutbound,
|
|
312
|
+
threading: { scopedAccountReplyToMode: {
|
|
313
|
+
resolveAccount: (cfg, accountId) => resolveWhatsAppAccount({
|
|
314
|
+
cfg,
|
|
315
|
+
accountId
|
|
316
|
+
}),
|
|
317
|
+
resolveReplyToMode: (account) => account.replyToMode
|
|
318
|
+
} },
|
|
319
|
+
base: {
|
|
320
|
+
...createWhatsAppPluginBase({
|
|
321
|
+
groups: {
|
|
322
|
+
resolveRequireMention: resolveWhatsAppGroupRequireMention,
|
|
323
|
+
resolveToolPolicy: resolveWhatsAppGroupToolPolicy,
|
|
324
|
+
resolveGroupIntroHint: resolveWhatsAppGroupIntroHint
|
|
325
|
+
},
|
|
326
|
+
setupWizard: whatsappSetupWizardProxy,
|
|
327
|
+
setup: whatsappSetupAdapter,
|
|
328
|
+
isConfigured: async (account) => {
|
|
329
|
+
return await (await loadWhatsAppChannelRuntime()).readWebAuthState(account.authDir) === "linked";
|
|
330
|
+
}
|
|
331
|
+
}),
|
|
332
|
+
agentTools: () => [createWhatsAppLoginTool()],
|
|
333
|
+
allowlist: buildDmGroupAccountAllowlistAdapter({
|
|
334
|
+
channelId: "whatsapp",
|
|
335
|
+
resolveAccount: resolveWhatsAppAccount,
|
|
336
|
+
normalize: ({ values }) => formatWhatsAppConfigAllowFromEntries(values),
|
|
337
|
+
resolveDmAllowFrom: (account) => account.allowFrom,
|
|
338
|
+
resolveGroupAllowFrom: (account) => account.groupAllowFrom,
|
|
339
|
+
resolveDmPolicy: (account) => account.dmPolicy,
|
|
340
|
+
resolveGroupPolicy: (account) => account.groupPolicy
|
|
341
|
+
}),
|
|
342
|
+
mentions: { stripRegexes: ({ ctx }) => resolveWhatsAppMentionStripRegexes(ctx) },
|
|
343
|
+
commands: whatsappCommandPolicy,
|
|
344
|
+
agentPrompt: { reactionGuidance: ({ cfg, accountId }) => {
|
|
345
|
+
const level = resolveWhatsAppAgentReactionGuidance({
|
|
346
|
+
cfg,
|
|
347
|
+
accountId: accountId ?? void 0
|
|
348
|
+
});
|
|
349
|
+
return level ? {
|
|
350
|
+
level,
|
|
351
|
+
channelLabel: "WhatsApp"
|
|
352
|
+
} : void 0;
|
|
353
|
+
} },
|
|
354
|
+
messaging: {
|
|
355
|
+
targetPrefixes: ["whatsapp"],
|
|
356
|
+
normalizeTarget: normalizeWhatsAppMessagingTarget,
|
|
357
|
+
resolveOutboundSessionRoute: (params) => resolveWhatsAppOutboundSessionRoute(params),
|
|
358
|
+
parseExplicitTarget: ({ raw }) => parseWhatsAppExplicitTarget(raw),
|
|
359
|
+
inferTargetChatType: ({ to }) => parseWhatsAppExplicitTarget(to)?.chatType,
|
|
360
|
+
targetResolver: {
|
|
361
|
+
looksLikeId: looksLikeWhatsAppTargetId,
|
|
362
|
+
hint: "<E.164|group JID|newsletter JID>"
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
directory: {
|
|
366
|
+
self: async ({ cfg, accountId }) => {
|
|
367
|
+
const account = resolveWhatsAppAccount({
|
|
368
|
+
cfg,
|
|
369
|
+
accountId
|
|
370
|
+
});
|
|
371
|
+
const { e164, jid } = (await loadWhatsAppChannelRuntime()).readWebSelfId(account.authDir);
|
|
372
|
+
const id = e164 ?? jid;
|
|
373
|
+
if (!id) return null;
|
|
374
|
+
return {
|
|
375
|
+
kind: "user",
|
|
376
|
+
id,
|
|
377
|
+
name: account.name,
|
|
378
|
+
raw: {
|
|
379
|
+
e164,
|
|
380
|
+
jid
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
},
|
|
384
|
+
listPeers: async (params) => (await loadWhatsAppDirectoryConfig()).listWhatsAppDirectoryPeersFromConfig(params),
|
|
385
|
+
listGroups: async (params) => (await loadWhatsAppDirectoryConfig()).listWhatsAppDirectoryGroupsFromConfig(params)
|
|
386
|
+
},
|
|
387
|
+
actions: {
|
|
388
|
+
describeMessageTool: ({ cfg, accountId }) => describeWhatsAppMessageActions({
|
|
389
|
+
cfg,
|
|
390
|
+
accountId
|
|
391
|
+
}),
|
|
392
|
+
supportsAction: ({ action }) => action === "react",
|
|
393
|
+
resolveExecutionMode: ({ action }) => action === "react" ? "gateway" : "local",
|
|
394
|
+
handleAction: async ({ action, params, cfg, accountId, requesterSenderId, toolContext }) => await (await loadWhatsAppChannelReactAction()).handleWhatsAppReactAction({
|
|
395
|
+
action,
|
|
396
|
+
params,
|
|
397
|
+
cfg,
|
|
398
|
+
accountId,
|
|
399
|
+
requesterSenderId,
|
|
400
|
+
toolContext
|
|
401
|
+
})
|
|
402
|
+
},
|
|
403
|
+
approvalCapability: whatsappApprovalAuth,
|
|
404
|
+
auth: { login: async ({ cfg, accountId, runtime, verbose }) => {
|
|
405
|
+
const resolvedAccountId = accountId?.trim() || whatsappPlugin.config.defaultAccountId?.(cfg) || DEFAULT_ACCOUNT_ID;
|
|
406
|
+
await (await loadWhatsAppChannelRuntime()).loginWeb(Boolean(verbose), void 0, runtime, resolvedAccountId);
|
|
407
|
+
} },
|
|
408
|
+
lifecycle: { detectLegacyStateMigrations: ({ oauthDir }) => detectWhatsAppLegacyStateMigrations({ oauthDir }) },
|
|
409
|
+
heartbeat: {
|
|
410
|
+
checkReady: async ({ cfg, accountId, deps }) => await checkWhatsAppHeartbeatReady({
|
|
411
|
+
cfg,
|
|
412
|
+
accountId: accountId ?? void 0,
|
|
413
|
+
deps
|
|
414
|
+
}),
|
|
415
|
+
sendTyping: async ({ cfg, to, accountId }) => {
|
|
416
|
+
await sendTypingWhatsApp(to, {
|
|
417
|
+
cfg,
|
|
418
|
+
...accountId ? { accountId } : {}
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
status: createAsyncComputedAccountStatusAdapter({
|
|
423
|
+
defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID, {
|
|
424
|
+
connected: false,
|
|
425
|
+
reconnectAttempts: 0,
|
|
426
|
+
lastConnectedAt: null,
|
|
427
|
+
lastDisconnect: null,
|
|
428
|
+
lastInboundAt: null,
|
|
429
|
+
lastMessageAt: null,
|
|
430
|
+
lastEventAt: null,
|
|
431
|
+
healthState: "stopped"
|
|
432
|
+
}),
|
|
433
|
+
collectStatusIssues: collectWhatsAppStatusIssues,
|
|
434
|
+
buildChannelSummary: async ({ account, snapshot }) => {
|
|
435
|
+
const channelRuntime = await loadWhatsAppChannelRuntime();
|
|
436
|
+
const authDir = account.authDir;
|
|
437
|
+
const auth = authDir ? await channelRuntime.readWebAuthSnapshot(authDir) : {
|
|
438
|
+
state: "not-linked",
|
|
439
|
+
authAgeMs: null,
|
|
440
|
+
selfId: {
|
|
441
|
+
e164: null,
|
|
442
|
+
jid: null,
|
|
443
|
+
lid: null
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
const linked = typeof snapshot.linked === "boolean" ? snapshot.linked : auth.state === "unstable" ? void 0 : auth.state === "linked";
|
|
447
|
+
const summaryAuthState = auth.state === "unstable" ? auth.state : linked === true ? "linked" : linked === false ? "not-linked" : void 0;
|
|
448
|
+
const statusState = summaryAuthState === void 0 ? void 0 : summaryAuthState;
|
|
449
|
+
const configured = auth.state === "unstable" ? typeof snapshot.configured === "boolean" ? snapshot.configured : true : typeof linked === "boolean" ? linked : auth.state === "linked";
|
|
450
|
+
const authAgeMs = typeof linked === "boolean" && linked ? auth.authAgeMs : null;
|
|
451
|
+
const self = typeof linked === "boolean" && linked ? auth.selfId : {
|
|
452
|
+
e164: null,
|
|
453
|
+
jid: null,
|
|
454
|
+
lid: null
|
|
455
|
+
};
|
|
456
|
+
return {
|
|
457
|
+
configured,
|
|
458
|
+
...statusState ? { statusState } : {},
|
|
459
|
+
...typeof linked === "boolean" ? { linked } : {},
|
|
460
|
+
authAgeMs,
|
|
461
|
+
self,
|
|
462
|
+
running: snapshot.running ?? false,
|
|
463
|
+
connected: snapshot.connected ?? false,
|
|
464
|
+
lastConnectedAt: snapshot.lastConnectedAt ?? null,
|
|
465
|
+
lastDisconnect: snapshot.lastDisconnect ?? null,
|
|
466
|
+
reconnectAttempts: snapshot.reconnectAttempts,
|
|
467
|
+
lastInboundAt: snapshot.lastInboundAt ?? snapshot.lastMessageAt ?? null,
|
|
468
|
+
lastMessageAt: snapshot.lastMessageAt ?? null,
|
|
469
|
+
lastEventAt: snapshot.lastEventAt ?? null,
|
|
470
|
+
lastError: snapshot.lastError ?? null,
|
|
471
|
+
healthState: snapshot.healthState ?? void 0
|
|
472
|
+
};
|
|
473
|
+
},
|
|
474
|
+
resolveAccountSnapshot: async ({ account, runtime }) => {
|
|
475
|
+
const authState = await (await loadWhatsAppChannelRuntime()).readWebAuthState(account.authDir);
|
|
476
|
+
return {
|
|
477
|
+
accountId: account.accountId,
|
|
478
|
+
name: account.name,
|
|
479
|
+
enabled: account.enabled,
|
|
480
|
+
configured: true,
|
|
481
|
+
extra: {
|
|
482
|
+
statusState: authState,
|
|
483
|
+
...authState === "linked" ? { linked: true } : authState === "not-linked" ? { linked: false } : {},
|
|
484
|
+
connected: runtime?.connected ?? false,
|
|
485
|
+
reconnectAttempts: runtime?.reconnectAttempts,
|
|
486
|
+
lastConnectedAt: runtime?.lastConnectedAt ?? null,
|
|
487
|
+
lastDisconnect: runtime?.lastDisconnect ?? null,
|
|
488
|
+
lastInboundAt: runtime?.lastInboundAt ?? runtime?.lastMessageAt ?? null,
|
|
489
|
+
lastMessageAt: runtime?.lastMessageAt ?? null,
|
|
490
|
+
lastEventAt: runtime?.lastEventAt ?? null,
|
|
491
|
+
healthState: runtime?.healthState ?? void 0,
|
|
492
|
+
dmPolicy: account.dmPolicy,
|
|
493
|
+
allowFrom: account.allowFrom
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
},
|
|
497
|
+
resolveAccountState: ({ configured }) => configured ? "linked" : "not linked",
|
|
498
|
+
logSelfId: ({ account, runtime, includeChannelPrefix }) => {
|
|
499
|
+
loadWhatsAppChannelRuntime().then((runtimeExports) => runtimeExports.logWebSelfId(account.authDir, runtime, includeChannelPrefix));
|
|
500
|
+
}
|
|
501
|
+
}),
|
|
502
|
+
gateway: {
|
|
503
|
+
startAccount: async (ctx) => {
|
|
504
|
+
const account = ctx.account;
|
|
505
|
+
const { e164, jid } = (await loadWhatsAppChannelRuntime()).readWebSelfId(account.authDir);
|
|
506
|
+
const identity = e164 ? e164 : jid ? `jid ${jid}` : "unknown";
|
|
507
|
+
ctx.log?.info(`[${account.accountId}] starting provider (${identity})`);
|
|
508
|
+
return (await loadWhatsAppChannelRuntime()).monitorWebChannel(getWhatsAppRuntime().logging.shouldLogVerbose(), void 0, true, void 0, ctx.runtime, ctx.abortSignal, {
|
|
509
|
+
statusSink: (next) => ctx.setStatus({
|
|
510
|
+
accountId: ctx.accountId,
|
|
511
|
+
...next
|
|
512
|
+
}),
|
|
513
|
+
accountId: account.accountId
|
|
514
|
+
});
|
|
515
|
+
},
|
|
516
|
+
loginWithQrStart: async ({ accountId, force, timeoutMs, verbose }) => await (await loadWhatsAppChannelRuntime()).startWebLoginWithQr({
|
|
517
|
+
accountId,
|
|
518
|
+
force,
|
|
519
|
+
timeoutMs,
|
|
520
|
+
verbose
|
|
521
|
+
}),
|
|
522
|
+
loginWithQrWait: async ({ accountId, timeoutMs, currentQrDataUrl }) => await (await loadWhatsAppChannelRuntime()).waitForWebLogin({
|
|
523
|
+
accountId,
|
|
524
|
+
timeoutMs,
|
|
525
|
+
currentQrDataUrl
|
|
526
|
+
}),
|
|
527
|
+
logoutAccount: async ({ account, runtime }) => {
|
|
528
|
+
const cleared = await (await loadWhatsAppChannelRuntime()).logoutWeb({
|
|
529
|
+
authDir: account.authDir,
|
|
530
|
+
isLegacyAuthDir: account.isLegacyAuthDir,
|
|
531
|
+
runtime
|
|
532
|
+
});
|
|
533
|
+
return {
|
|
534
|
+
cleared,
|
|
535
|
+
loggedOut: cleared
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
//#endregion
|
|
542
|
+
export { whatsappPlugin as t };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { s as normalizeWhatsAppTarget, t as isWhatsAppGroupJid } from "./normalize-target-BPVHNsM5.js";
|
|
2
|
+
import { t as handleWhatsAppAction } from "./action-runtime-DTGNgG-i.js";
|
|
3
|
+
import "./normalize-CWYiGkXw.js";
|
|
4
|
+
import { readStringOrNumberParam, readStringParam as readStringParam$1, resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
|
|
5
|
+
//#region extensions/whatsapp/src/channel-react-action.ts
|
|
6
|
+
const WHATSAPP_CHANNEL = "whatsapp";
|
|
7
|
+
async function handleWhatsAppReactAction(params) {
|
|
8
|
+
if (params.action !== "react") throw new Error(`Action ${params.action} is not supported for provider ${WHATSAPP_CHANNEL}.`);
|
|
9
|
+
const isWhatsAppSource = params.toolContext?.currentChannelProvider === WHATSAPP_CHANNEL;
|
|
10
|
+
const explicitTarget = readStringParam$1(params.params, "chatJid") ?? readStringParam$1(params.params, "to");
|
|
11
|
+
const normalizedTarget = explicitTarget ? normalizeWhatsAppTarget(explicitTarget) : null;
|
|
12
|
+
const normalizedCurrent = isWhatsAppSource && params.toolContext?.currentChannelId ? normalizeWhatsAppTarget(params.toolContext.currentChannelId) : null;
|
|
13
|
+
const isCrossChat = normalizedTarget != null && (normalizedCurrent == null || normalizedTarget !== normalizedCurrent);
|
|
14
|
+
const scopedContext = !isWhatsAppSource || isCrossChat || !params.toolContext ? void 0 : {
|
|
15
|
+
currentChannelId: params.toolContext.currentChannelId ?? void 0,
|
|
16
|
+
currentChannelProvider: params.toolContext.currentChannelProvider ?? void 0,
|
|
17
|
+
currentMessageId: params.toolContext.currentMessageId ?? void 0
|
|
18
|
+
};
|
|
19
|
+
const messageIdRaw = resolveReactionMessageId({
|
|
20
|
+
args: params.params,
|
|
21
|
+
toolContext: scopedContext
|
|
22
|
+
});
|
|
23
|
+
if (messageIdRaw == null) readStringParam$1(params.params, "messageId", { required: true });
|
|
24
|
+
const messageId = String(messageIdRaw);
|
|
25
|
+
const explicitMessageId = readStringOrNumberParam(params.params, "messageId");
|
|
26
|
+
const emoji = readStringParam$1(params.params, "emoji", { allowEmpty: true });
|
|
27
|
+
const remove = typeof params.params.remove === "boolean" ? params.params.remove : void 0;
|
|
28
|
+
const explicitParticipant = readStringParam$1(params.params, "participant");
|
|
29
|
+
const inferredParticipant = explicitParticipant || explicitMessageId != null || !isWhatsAppSource || isCrossChat || !isWhatsAppGroupJid(explicitTarget ?? params.toolContext?.currentChannelId ?? "") ? void 0 : typeof params.requesterSenderId === "string" && params.requesterSenderId.trim().length > 0 ? params.requesterSenderId.trim() : void 0;
|
|
30
|
+
return await handleWhatsAppAction({
|
|
31
|
+
action: "react",
|
|
32
|
+
chatJid: readStringParam$1(params.params, "chatJid") ?? readStringParam$1(params.params, "to", { required: true }),
|
|
33
|
+
messageId,
|
|
34
|
+
emoji,
|
|
35
|
+
remove,
|
|
36
|
+
participant: explicitParticipant ?? inferredParticipant,
|
|
37
|
+
accountId: params.accountId ?? void 0,
|
|
38
|
+
fromMe: typeof params.params.fromMe === "boolean" ? params.params.fromMe : void 0
|
|
39
|
+
}, params.cfg);
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { handleWhatsAppReactAction };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { startWebLoginWithQr as startWebLoginWithQr$1, waitForWebLogin as waitForWebLogin$1 } from "./login-qr-runtime.js";
|
|
2
|
+
import { a as getWebAuthAgeMs$1, b as webAuthExists$1, d as readWebAuthExistsForDecision$1, f as readWebAuthSnapshot$1, h as readWebSelfId$1, m as readWebAuthState$1, o as logWebSelfId$1, p as readWebAuthSnapshotBestEffort$1, s as logoutWeb$1, u as readWebAuthExistsBestEffort$1 } from "./auth-store-BjCb50Ry.js";
|
|
3
|
+
import { t as getActiveWebListener$1 } from "./active-listener-N7GFKsuN.js";
|
|
4
|
+
import { t as monitorWebChannel$1 } from "./monitor-C4Fhg_lD.js";
|
|
5
|
+
import { t as loginWeb$1 } from "./login-DymdrKca.js";
|
|
6
|
+
import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-ieFnIW4g.js";
|
|
7
|
+
//#region extensions/whatsapp/src/channel.runtime.ts
|
|
8
|
+
function getActiveWebListener(...args) {
|
|
9
|
+
return getActiveWebListener$1(...args);
|
|
10
|
+
}
|
|
11
|
+
function getWebAuthAgeMs(...args) {
|
|
12
|
+
return getWebAuthAgeMs$1(...args);
|
|
13
|
+
}
|
|
14
|
+
function logWebSelfId(...args) {
|
|
15
|
+
return logWebSelfId$1(...args);
|
|
16
|
+
}
|
|
17
|
+
function logoutWeb(...args) {
|
|
18
|
+
return logoutWeb$1(...args);
|
|
19
|
+
}
|
|
20
|
+
function readWebAuthSnapshot(...args) {
|
|
21
|
+
return readWebAuthSnapshot$1(...args);
|
|
22
|
+
}
|
|
23
|
+
function readWebAuthState(...args) {
|
|
24
|
+
return readWebAuthState$1(...args);
|
|
25
|
+
}
|
|
26
|
+
function readWebAuthExistsBestEffort(...args) {
|
|
27
|
+
return readWebAuthExistsBestEffort$1(...args);
|
|
28
|
+
}
|
|
29
|
+
function readWebAuthExistsForDecision(...args) {
|
|
30
|
+
return readWebAuthExistsForDecision$1(...args);
|
|
31
|
+
}
|
|
32
|
+
function readWebAuthSnapshotBestEffort(...args) {
|
|
33
|
+
return readWebAuthSnapshotBestEffort$1(...args);
|
|
34
|
+
}
|
|
35
|
+
function readWebSelfId(...args) {
|
|
36
|
+
return readWebSelfId$1(...args);
|
|
37
|
+
}
|
|
38
|
+
function webAuthExists(...args) {
|
|
39
|
+
return webAuthExists$1(...args);
|
|
40
|
+
}
|
|
41
|
+
function loginWeb(...args) {
|
|
42
|
+
return loginWeb$1(...args);
|
|
43
|
+
}
|
|
44
|
+
async function startWebLoginWithQr(...args) {
|
|
45
|
+
return await startWebLoginWithQr$1(...args);
|
|
46
|
+
}
|
|
47
|
+
async function waitForWebLogin(...args) {
|
|
48
|
+
return await waitForWebLogin$1(...args);
|
|
49
|
+
}
|
|
50
|
+
const whatsappSetupWizard = { ...whatsappSetupWizard$1 };
|
|
51
|
+
function monitorWebChannel(...args) {
|
|
52
|
+
return monitorWebChannel$1(...args);
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { getActiveWebListener, getWebAuthAgeMs, logWebSelfId, loginWeb, logoutWeb, monitorWebChannel, readWebAuthExistsBestEffort, readWebAuthExistsForDecision, readWebAuthSnapshot, readWebAuthSnapshotBestEffort, readWebAuthState, readWebSelfId, startWebLoginWithQr, waitForWebLogin, webAuthExists, whatsappSetupWizard };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { a as resolveWhatsAppGroupToolPolicy, i as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupIntroHint, r as whatsappSetupWizardProxy, t as createWhatsAppPluginBase } from "./shared-D_wzSVar.js";
|
|
2
|
+
import { m as readWebAuthState } from "./auth-store-BjCb50Ry.js";
|
|
3
|
+
import { t as whatsappSetupAdapter } from "./setup-core-DZKvpzbH.js";
|
|
4
|
+
import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-DnCdvoYD.js";
|
|
5
|
+
//#region extensions/whatsapp/src/channel.setup.ts
|
|
6
|
+
const whatsappSetupPlugin = {
|
|
7
|
+
...createWhatsAppPluginBase({
|
|
8
|
+
groups: {
|
|
9
|
+
resolveRequireMention: resolveWhatsAppGroupRequireMention,
|
|
10
|
+
resolveToolPolicy: resolveWhatsAppGroupToolPolicy,
|
|
11
|
+
resolveGroupIntroHint: resolveWhatsAppGroupIntroHint
|
|
12
|
+
},
|
|
13
|
+
setupWizard: whatsappSetupWizardProxy,
|
|
14
|
+
setup: whatsappSetupAdapter,
|
|
15
|
+
isConfigured: async (account) => await readWebAuthState(account.authDir) === "linked"
|
|
16
|
+
}),
|
|
17
|
+
lifecycle: { detectLegacyStateMigrations: ({ oauthDir }) => detectWhatsAppLegacyStateMigrations({ oauthDir }) }
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { whatsappSetupPlugin as t };
|