@openclaw/whatsapp 2026.7.2-beta.7 → 2026.8.1-beta.2
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/{accounts-CSqLvCY5.js → accounts-BX2fZUyR.js} +1 -1
- package/dist/{action-runtime-BzfDFPbH.js → action-runtime-B4e3XFOY.js} +2 -2
- package/dist/action-runtime-api.js +1 -1
- package/dist/action-runtime.runtime.js +1 -1
- package/dist/{agent-tools-login-DE9MU98T.js → agent-tools-login-BjRpD-JQ.js} +5 -4
- package/dist/api.js +69 -127
- package/dist/{approval-handler.runtime-DrA59QSA.js → approval-handler.runtime-fgGZhALv.js} +4 -4
- package/dist/{approval-reactions-Cu66aYdq.js → approval-reactions-CmtJCxe_.js} +25 -73
- package/dist/auth-presence.js +1 -1
- package/dist/{auth-store-DcEpIOmE.js → auth-store-B_DQIdzp.js} +79 -12
- package/dist/call-tool-api.js +1 -1
- package/dist/{channel-Dg62olhy.js → channel-DJVQHz_V.js} +56 -160
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-react-action-J_YtyMGX.js → channel-react-action-d6OacTNj.js} +3 -3
- package/dist/{channel.runtime-BP0xNmLi.js → channel.runtime-RxuNGZ7w.js} +4 -4
- package/dist/channel.setup-Cmvd967u.js +14 -0
- package/dist/{connection-controller-BOB2MVKY.js → connection-controller-CUyZgGpf.js} +2 -3
- package/dist/contract-api.js +2 -3
- package/dist/{creds-files-B1kSWtBg.js → creds-files-W6B3EMZ8.js} +17 -1
- package/dist/{directory-config-DalGrfGN.js → directory-config-Pc4f07wB.js} +3 -3
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +37 -2
- package/dist/{group-session-key-DVMZlO3x.js → group-session-key-DmFc_Cqi.js} +23 -4
- package/dist/light-runtime-api.js +2 -2
- package/dist/{login-CvY2Dhch.js → login-D6_rfxTZ.js} +4 -4
- package/dist/{login-qr-Bncpb6js.js → login-qr-B0VyVSqQ.js} +4 -4
- package/dist/login-qr-runtime.js +1 -1
- package/dist/{monitor-CfkaUSL2.js → monitor-BCe5Mm-1.js} +574 -163
- package/dist/{question-reactions-CRsnyoMK.js → question-reactions-D3eAeB0i.js} +29 -78
- package/dist/runtime-api.js +9 -9
- package/dist/runtime-group-policy-DeSRFXEV.js +11 -0
- package/dist/{send-api-7wk6eQyW.js → send-api-DimZST3E.js} +86 -107
- package/dist/{send-D37ddk22.js → send-prK8F7Vj.js} +277 -16
- package/dist/setup-entry.js +1 -8
- package/dist/{setup-finalize-BZucx24W.js → setup-finalize-D3n71Uyx.js} +4 -4
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-BkVcd769.js → setup-surface-BCZszf3l.js} +3 -3
- package/dist/{shared-CAxd15bp.js → shared-Dp9M3ZPX.js} +5 -6
- package/dist/{socket-close-DridEuzz.js → socket-close-09FojDO2.js} +4 -10
- package/openclaw.plugin.json +4 -0
- package/package.json +4 -5
- package/skills/wacli/SKILL.md +8 -1
- package/dist/access-control-pZcxTmd5.js +0 -363
- package/dist/approval-resolver-DoeBBt22.js +0 -16
- package/dist/channel.setup-pMwNVkCA.js +0 -19
- package/dist/identity-CPrT5aEU.js +0 -76
- package/dist/legacy-state-migrations-api.js +0 -2
- package/dist/state-migrations-CAMTrs2U.js +0 -33
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
import { a as resolveWhatsAppAccount } from "./accounts-CSqLvCY5.js";
|
|
2
|
-
import { n as isSelfChatMode } from "./targets-runtime-TMk0lGuy.js";
|
|
3
|
-
import { t as normalizeE164 } from "./text-runtime-CaKLhowd.js";
|
|
4
|
-
import { a as getSelfIdentity, o as getSenderIdentity } from "./identity-CPrT5aEU.js";
|
|
5
|
-
import { defaultRuntime } from "openclaw/plugin-sdk/runtime-env";
|
|
6
|
-
import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
|
|
7
|
-
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
8
|
-
import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
|
9
|
-
import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
10
|
-
import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
11
|
-
import { resolveGroupSessionKey } from "openclaw/plugin-sdk/session-store-runtime";
|
|
12
|
-
//#region extensions/whatsapp/src/inbound/group-conversation.ts
|
|
13
|
-
function resolveWhatsAppGroupConversationId(conversationId) {
|
|
14
|
-
return resolveGroupSessionKey({
|
|
15
|
-
From: conversationId,
|
|
16
|
-
ChatType: "group",
|
|
17
|
-
Provider: "whatsapp"
|
|
18
|
-
})?.id ?? conversationId;
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region extensions/whatsapp/src/inbound/admission.ts
|
|
22
|
-
function copyAccount(account) {
|
|
23
|
-
const copied = {
|
|
24
|
-
accountId: account.accountId,
|
|
25
|
-
enabled: account.enabled,
|
|
26
|
-
sendReadReceipts: account.sendReadReceipts
|
|
27
|
-
};
|
|
28
|
-
if (account.name) copied.name = account.name;
|
|
29
|
-
if (typeof account.selfChatMode === "boolean") copied.selfChatMode = account.selfChatMode;
|
|
30
|
-
if (account.replyToMode) copied.replyToMode = account.replyToMode;
|
|
31
|
-
return copied;
|
|
32
|
-
}
|
|
33
|
-
function buildWhatsAppInboundAdmission(params) {
|
|
34
|
-
return {
|
|
35
|
-
accountId: params.policy.account.accountId,
|
|
36
|
-
isSelfChat: params.policy.isSelfChat,
|
|
37
|
-
account: copyAccount(params.policy.account),
|
|
38
|
-
conversation: {
|
|
39
|
-
kind: params.isGroup ? "group" : "direct",
|
|
40
|
-
id: params.conversationId,
|
|
41
|
-
groupSessionId: resolveWhatsAppGroupConversationId(params.conversationId)
|
|
42
|
-
},
|
|
43
|
-
sender: {
|
|
44
|
-
id: params.senderId,
|
|
45
|
-
isSamePhone: params.policy.isSamePhone(params.senderId)
|
|
46
|
-
},
|
|
47
|
-
ingress: {
|
|
48
|
-
admission: params.access.ingress.admission,
|
|
49
|
-
decision: params.access.ingress.decision,
|
|
50
|
-
decisiveGateId: params.access.ingress.decisiveGateId,
|
|
51
|
-
reasonCode: params.access.ingress.reasonCode
|
|
52
|
-
},
|
|
53
|
-
senderAccess: {
|
|
54
|
-
allowed: params.access.senderAccess.allowed,
|
|
55
|
-
decision: params.access.senderAccess.decision,
|
|
56
|
-
reasonCode: params.access.senderAccess.reasonCode,
|
|
57
|
-
providerMissingFallbackApplied: params.access.senderAccess.providerMissingFallbackApplied
|
|
58
|
-
},
|
|
59
|
-
commandAccess: {
|
|
60
|
-
requested: params.access.commandAccess.requested,
|
|
61
|
-
authorized: params.access.commandAccess.authorized,
|
|
62
|
-
shouldBlockControlCommand: params.access.commandAccess.shouldBlockControlCommand,
|
|
63
|
-
reasonCode: params.access.commandAccess.reasonCode
|
|
64
|
-
},
|
|
65
|
-
activationAccess: {
|
|
66
|
-
ran: params.access.activationAccess.ran,
|
|
67
|
-
allowed: params.access.activationAccess.allowed,
|
|
68
|
-
shouldSkip: params.access.activationAccess.shouldSkip,
|
|
69
|
-
reasonCode: params.access.activationAccess.reasonCode
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function buildDeprecatedFlatWhatsAppInboundAdmission(msg) {
|
|
74
|
-
const conversationId = msg.conversationId || msg.from;
|
|
75
|
-
if (!conversationId || !msg.accountId || !msg.chatType) throw new Error("WhatsApp legacy flat inbound messages must include deprecated top-level admission fields.");
|
|
76
|
-
const accountId = msg.accountId;
|
|
77
|
-
const admitted = msg.accessControlPassed !== false;
|
|
78
|
-
const platformSender = msg.platform?.sender;
|
|
79
|
-
const senderE164 = platformSender?.e164 ?? msg.platform?.senderE164 ?? msg.senderE164;
|
|
80
|
-
const senderJid = platformSender?.jid ?? msg.platform?.senderJid ?? msg.senderJid;
|
|
81
|
-
const senderName = platformSender?.name ?? msg.platform?.senderName ?? msg.senderName;
|
|
82
|
-
const senderId = msg.chatType === "group" ? senderE164 ?? senderJid ?? senderName ?? conversationId : senderE164 ?? conversationId;
|
|
83
|
-
const reasonCode = admitted ? msg.chatType === "group" ? "group_policy_allowed" : "dm_policy_allowlisted" : "no_policy_match";
|
|
84
|
-
return buildWhatsAppInboundAdmission({
|
|
85
|
-
policy: {
|
|
86
|
-
account: {
|
|
87
|
-
accountId,
|
|
88
|
-
enabled: true,
|
|
89
|
-
sendReadReceipts: true
|
|
90
|
-
},
|
|
91
|
-
isSelfChat: false,
|
|
92
|
-
isSamePhone: () => false
|
|
93
|
-
},
|
|
94
|
-
access: {
|
|
95
|
-
ingress: {
|
|
96
|
-
admission: admitted ? "dispatch" : "drop",
|
|
97
|
-
decision: admitted ? "allow" : "block",
|
|
98
|
-
decisiveGateId: "legacy-flat-compat",
|
|
99
|
-
reasonCode
|
|
100
|
-
},
|
|
101
|
-
senderAccess: {
|
|
102
|
-
allowed: admitted,
|
|
103
|
-
decision: admitted ? "allow" : "block",
|
|
104
|
-
reasonCode,
|
|
105
|
-
providerMissingFallbackApplied: false
|
|
106
|
-
},
|
|
107
|
-
commandAccess: {
|
|
108
|
-
requested: false,
|
|
109
|
-
authorized: false,
|
|
110
|
-
shouldBlockControlCommand: false,
|
|
111
|
-
reasonCode: "command_authorized"
|
|
112
|
-
},
|
|
113
|
-
activationAccess: {
|
|
114
|
-
ran: false,
|
|
115
|
-
allowed: admitted,
|
|
116
|
-
shouldSkip: !admitted,
|
|
117
|
-
reasonCode: admitted ? "activation_allowed" : "activation_skipped"
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
isGroup: msg.chatType === "group",
|
|
121
|
-
conversationId,
|
|
122
|
-
senderId
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
function requireWhatsAppInboundAdmission(params) {
|
|
126
|
-
if (!params.admission) throw new Error("WhatsApp inbound message is missing admission facts");
|
|
127
|
-
return params.admission;
|
|
128
|
-
}
|
|
129
|
-
function requireAdmittedWhatsAppInboundMessage(msg) {
|
|
130
|
-
requireWhatsAppInboundAdmission(msg);
|
|
131
|
-
return msg;
|
|
132
|
-
}
|
|
133
|
-
//#endregion
|
|
134
|
-
//#region extensions/whatsapp/src/runtime-group-policy.ts
|
|
135
|
-
function resolveWhatsAppRuntimeGroupPolicy(params) {
|
|
136
|
-
return resolveOpenProviderRuntimeGroupPolicy({
|
|
137
|
-
providerConfigPresent: params.providerConfigPresent,
|
|
138
|
-
groupPolicy: params.groupPolicy,
|
|
139
|
-
defaultGroupPolicy: params.defaultGroupPolicy
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
//#endregion
|
|
143
|
-
//#region extensions/whatsapp/src/inbound-policy.ts
|
|
144
|
-
function normalizeWhatsAppIngressPhone(value) {
|
|
145
|
-
const trimmed = value.trim();
|
|
146
|
-
if (!trimmed) return null;
|
|
147
|
-
return normalizeE164(trimmed);
|
|
148
|
-
}
|
|
149
|
-
function maybeSamePhoneDmAllowFrom(params) {
|
|
150
|
-
if (params.isGroup || !params.dmSenderId || !params.policy.isSamePhone(params.dmSenderId)) return [];
|
|
151
|
-
return [params.dmSenderId];
|
|
152
|
-
}
|
|
153
|
-
function buildResolvedWhatsAppGroupConfig(params) {
|
|
154
|
-
return { channels: { whatsapp: {
|
|
155
|
-
groupPolicy: params.groupPolicy,
|
|
156
|
-
groups: params.groups
|
|
157
|
-
} } };
|
|
158
|
-
}
|
|
159
|
-
function resolveWhatsAppInboundPolicy(params) {
|
|
160
|
-
const account = resolveWhatsAppAccount({
|
|
161
|
-
cfg: params.cfg,
|
|
162
|
-
accountId: params.accountId
|
|
163
|
-
});
|
|
164
|
-
const configuredAllowFrom = account.allowFrom ?? [];
|
|
165
|
-
const dmPolicy = account.dmPolicy ?? "pairing";
|
|
166
|
-
const dmAllowFrom = configuredAllowFrom.length > 0 ? configuredAllowFrom : params.selfE164 ? [params.selfE164] : [];
|
|
167
|
-
const groupAllowFrom = (Array.isArray(account.groupAllowFrom) && account.groupAllowFrom.length > 0 ? account.groupAllowFrom : void 0) ?? (configuredAllowFrom.length > 0 ? configuredAllowFrom : void 0) ?? [];
|
|
168
|
-
const defaultGroupPolicy = resolveDefaultGroupPolicy(params.cfg);
|
|
169
|
-
const { groupPolicy, providerMissingFallbackApplied } = resolveWhatsAppRuntimeGroupPolicy({
|
|
170
|
-
providerConfigPresent: params.cfg.channels?.whatsapp !== void 0,
|
|
171
|
-
groupPolicy: account.groupPolicy,
|
|
172
|
-
defaultGroupPolicy
|
|
173
|
-
});
|
|
174
|
-
const resolvedGroupCfg = buildResolvedWhatsAppGroupConfig({
|
|
175
|
-
groupPolicy,
|
|
176
|
-
groups: account.groups
|
|
177
|
-
});
|
|
178
|
-
const isSamePhone = (value) => typeof value === "string" && typeof params.selfE164 === "string" && value === params.selfE164;
|
|
179
|
-
return {
|
|
180
|
-
account,
|
|
181
|
-
dmPolicy,
|
|
182
|
-
groupPolicy,
|
|
183
|
-
configuredAllowFrom,
|
|
184
|
-
dmAllowFrom,
|
|
185
|
-
groupAllowFrom,
|
|
186
|
-
isSelfChat: account.selfChatMode ?? isSelfChatMode(params.selfE164, configuredAllowFrom),
|
|
187
|
-
providerMissingFallbackApplied,
|
|
188
|
-
isSamePhone,
|
|
189
|
-
resolveConversationGroupPolicy: (conversationId) => resolveChannelGroupPolicy({
|
|
190
|
-
cfg: resolvedGroupCfg,
|
|
191
|
-
channel: "whatsapp",
|
|
192
|
-
groupId: resolveWhatsAppGroupConversationId(conversationId),
|
|
193
|
-
hasGroupAllowFrom: groupAllowFrom.length > 0
|
|
194
|
-
}),
|
|
195
|
-
resolveConversationRequireMention: (conversationId) => resolveChannelGroupRequireMention({
|
|
196
|
-
cfg: resolvedGroupCfg,
|
|
197
|
-
channel: "whatsapp",
|
|
198
|
-
groupId: resolveWhatsAppGroupConversationId(conversationId)
|
|
199
|
-
})
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
async function resolveWhatsAppIngressAccess(params) {
|
|
203
|
-
const samePhoneDmAllowFrom = maybeSamePhoneDmAllowFrom({
|
|
204
|
-
isGroup: params.isGroup,
|
|
205
|
-
policy: params.policy,
|
|
206
|
-
dmSenderId: params.dmSenderId
|
|
207
|
-
});
|
|
208
|
-
const dmAllowFrom = [...params.policy.dmAllowFrom, ...samePhoneDmAllowFrom];
|
|
209
|
-
return await resolveStableChannelMessageIngress({
|
|
210
|
-
channelId: "whatsapp",
|
|
211
|
-
accountId: params.policy.account.accountId,
|
|
212
|
-
identity: {
|
|
213
|
-
key: "whatsapp-sender-phone",
|
|
214
|
-
kind: "phone",
|
|
215
|
-
normalize: normalizeWhatsAppIngressPhone,
|
|
216
|
-
sensitivity: "pii",
|
|
217
|
-
entryIdPrefix: "whatsapp-entry"
|
|
218
|
-
},
|
|
219
|
-
cfg: params.cfg,
|
|
220
|
-
useDefaultPairingStore: true,
|
|
221
|
-
subject: { stableId: params.senderId ?? "" },
|
|
222
|
-
conversation: {
|
|
223
|
-
kind: params.isGroup ? "group" : "direct",
|
|
224
|
-
id: params.conversationId
|
|
225
|
-
},
|
|
226
|
-
dmPolicy: params.policy.dmPolicy,
|
|
227
|
-
groupPolicy: params.policy.groupPolicy,
|
|
228
|
-
policy: { groupAllowFromFallbackToAllowFrom: false },
|
|
229
|
-
providerMissingFallbackApplied: params.policy.providerMissingFallbackApplied,
|
|
230
|
-
allowFrom: dmAllowFrom,
|
|
231
|
-
groupAllowFrom: params.policy.groupAllowFrom,
|
|
232
|
-
command: params.includeCommand === true ? {} : void 0
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
async function resolveWhatsAppCommandAuthorized(params) {
|
|
236
|
-
const self = getSelfIdentity(params.msg, params.authDir);
|
|
237
|
-
const admission = requireWhatsAppInboundAdmission(params.msg);
|
|
238
|
-
const policy = params.policy ?? resolveWhatsAppInboundPolicy({
|
|
239
|
-
cfg: params.cfg,
|
|
240
|
-
accountId: admission.accountId,
|
|
241
|
-
selfE164: self.e164 ?? null
|
|
242
|
-
});
|
|
243
|
-
const isGroup = admission.conversation.kind === "group";
|
|
244
|
-
const sender = getSenderIdentity(params.msg, params.authDir);
|
|
245
|
-
const dmSender = sender.e164 ?? admission.conversation.id;
|
|
246
|
-
const groupSender = sender.e164 ?? "";
|
|
247
|
-
if (!normalizeE164(isGroup ? groupSender : dmSender)) return false;
|
|
248
|
-
return (await resolveWhatsAppIngressAccess({
|
|
249
|
-
cfg: params.cfg,
|
|
250
|
-
policy,
|
|
251
|
-
isGroup,
|
|
252
|
-
conversationId: admission.conversation.id,
|
|
253
|
-
senderId: isGroup ? groupSender : dmSender,
|
|
254
|
-
dmSenderId: dmSender,
|
|
255
|
-
includeCommand: true
|
|
256
|
-
})).commandAccess.authorized;
|
|
257
|
-
}
|
|
258
|
-
//#endregion
|
|
259
|
-
//#region extensions/whatsapp/src/inbound/access-control.ts
|
|
260
|
-
const PAIRING_REPLY_HISTORY_GRACE_MS = 3e4;
|
|
261
|
-
function logWhatsAppVerbose(enabled, message) {
|
|
262
|
-
if (!enabled) return;
|
|
263
|
-
defaultRuntime.log(message);
|
|
264
|
-
}
|
|
265
|
-
function blockedInboundAccess(policy) {
|
|
266
|
-
return {
|
|
267
|
-
allowed: false,
|
|
268
|
-
shouldMarkRead: false,
|
|
269
|
-
isSelfChat: policy.isSelfChat,
|
|
270
|
-
resolvedAccountId: policy.account.accountId
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
async function checkInboundAccessControl(params) {
|
|
274
|
-
const policy = resolveWhatsAppInboundPolicy({
|
|
275
|
-
cfg: params.cfg,
|
|
276
|
-
accountId: params.accountId,
|
|
277
|
-
selfE164: params.selfE164
|
|
278
|
-
});
|
|
279
|
-
const pairingGraceMs = typeof params.pairingGraceMs === "number" && params.pairingGraceMs > 0 ? params.pairingGraceMs : PAIRING_REPLY_HISTORY_GRACE_MS;
|
|
280
|
-
const suppressPairingReply = typeof params.connectedAtMs === "number" && typeof params.messageTimestampMs === "number" && params.messageTimestampMs < params.connectedAtMs - pairingGraceMs;
|
|
281
|
-
warnMissingProviderGroupPolicyFallbackOnce({
|
|
282
|
-
providerMissingFallbackApplied: policy.providerMissingFallbackApplied,
|
|
283
|
-
providerKey: "whatsapp",
|
|
284
|
-
accountId: policy.account.accountId,
|
|
285
|
-
log: (message) => logWhatsAppVerbose(params.verbose, message)
|
|
286
|
-
});
|
|
287
|
-
const conversationId = params.group ? params.remoteJid : params.from;
|
|
288
|
-
const accessSenderId = params.group ? params.senderE164 : params.from;
|
|
289
|
-
const admissionSenderId = params.group ? params.senderE164 ?? params.senderJid ?? params.from : params.from;
|
|
290
|
-
const access = await resolveWhatsAppIngressAccess({
|
|
291
|
-
cfg: params.cfg,
|
|
292
|
-
policy,
|
|
293
|
-
isGroup: params.group,
|
|
294
|
-
conversationId,
|
|
295
|
-
senderId: accessSenderId,
|
|
296
|
-
dmSenderId: params.from
|
|
297
|
-
});
|
|
298
|
-
const { senderAccess } = access;
|
|
299
|
-
if (params.group && senderAccess.decision !== "allow") {
|
|
300
|
-
if (senderAccess.reasonCode === "group_policy_disabled") logWhatsAppVerbose(params.verbose, "Blocked group message (groupPolicy: disabled)");
|
|
301
|
-
else if (senderAccess.reasonCode === "group_policy_empty_allowlist") logWhatsAppVerbose(params.verbose, "Blocked group message (groupPolicy: allowlist, no groupAllowFrom)");
|
|
302
|
-
else logWhatsAppVerbose(params.verbose, `Blocked group message from ${params.senderE164 ?? "unknown sender"} (groupPolicy: allowlist)`);
|
|
303
|
-
return blockedInboundAccess(policy);
|
|
304
|
-
}
|
|
305
|
-
if (!params.group) {
|
|
306
|
-
if (params.isFromMe && !policy.isSamePhone(params.from)) {
|
|
307
|
-
logWhatsAppVerbose(params.verbose, "Skipping outbound DM (fromMe); no pairing reply needed.");
|
|
308
|
-
return blockedInboundAccess(policy);
|
|
309
|
-
}
|
|
310
|
-
if (senderAccess.decision === "block" && senderAccess.reasonCode === "dm_policy_disabled") {
|
|
311
|
-
logWhatsAppVerbose(params.verbose, "Blocked dm (dmPolicy: disabled)");
|
|
312
|
-
return blockedInboundAccess(policy);
|
|
313
|
-
}
|
|
314
|
-
if (senderAccess.decision === "pairing" && !policy.isSamePhone(params.from)) {
|
|
315
|
-
const candidate = params.from;
|
|
316
|
-
if (suppressPairingReply) logWhatsAppVerbose(params.verbose, `Skipping pairing reply for historical DM from ${candidate}.`);
|
|
317
|
-
else await createChannelPairingChallengeIssuer({
|
|
318
|
-
channel: "whatsapp",
|
|
319
|
-
accountId: policy.account.accountId,
|
|
320
|
-
upsertPairingRequest: async ({ id, meta }) => await upsertChannelPairingRequest({
|
|
321
|
-
channel: "whatsapp",
|
|
322
|
-
id,
|
|
323
|
-
accountId: policy.account.accountId,
|
|
324
|
-
meta
|
|
325
|
-
})
|
|
326
|
-
})({
|
|
327
|
-
senderId: candidate,
|
|
328
|
-
senderIdLine: `Your WhatsApp phone number: ${candidate}`,
|
|
329
|
-
meta: { name: (params.pushName ?? "").trim() || void 0 },
|
|
330
|
-
onCreated: () => {
|
|
331
|
-
logWhatsAppVerbose(params.verbose, `whatsapp pairing request sender=${candidate} name=${params.pushName ?? "unknown"}`);
|
|
332
|
-
},
|
|
333
|
-
sendPairingReply: async (text) => {
|
|
334
|
-
await params.sock.sendMessage(params.remoteJid, { text });
|
|
335
|
-
},
|
|
336
|
-
onReplyError: (err) => {
|
|
337
|
-
logWhatsAppVerbose(params.verbose, `whatsapp pairing reply failed for ${candidate}: ${String(err)}`);
|
|
338
|
-
}
|
|
339
|
-
});
|
|
340
|
-
return blockedInboundAccess(policy);
|
|
341
|
-
}
|
|
342
|
-
if (senderAccess.decision !== "allow") {
|
|
343
|
-
logWhatsAppVerbose(params.verbose, `Blocked unauthorized sender ${params.from} (dmPolicy=${policy.dmPolicy})`);
|
|
344
|
-
return blockedInboundAccess(policy);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
return {
|
|
348
|
-
allowed: true,
|
|
349
|
-
shouldMarkRead: true,
|
|
350
|
-
isSelfChat: policy.isSelfChat,
|
|
351
|
-
resolvedAccountId: policy.account.accountId,
|
|
352
|
-
admission: buildWhatsAppInboundAdmission({
|
|
353
|
-
policy,
|
|
354
|
-
access,
|
|
355
|
-
isGroup: params.group,
|
|
356
|
-
conversationId,
|
|
357
|
-
senderId: admissionSenderId
|
|
358
|
-
})
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
const testing = { resolveWhatsAppInboundPolicy };
|
|
362
|
-
//#endregion
|
|
363
|
-
export { resolveWhatsAppRuntimeGroupPolicy as a, requireWhatsAppInboundAdmission as c, resolveWhatsAppInboundPolicy as i, resolveWhatsAppGroupConversationId as l, testing as n, buildDeprecatedFlatWhatsAppInboundAdmission as o, resolveWhatsAppCommandAuthorized as r, requireAdmittedWhatsAppInboundMessage as s, checkInboundAccessControl as t };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { isApprovalNotFoundError } from "openclaw/plugin-sdk/error-runtime";
|
|
2
|
-
import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-gateway-runtime";
|
|
3
|
-
//#region extensions/whatsapp/src/approval-resolver.ts
|
|
4
|
-
async function resolveWhatsAppApproval(params) {
|
|
5
|
-
return await resolveApprovalOverGateway({
|
|
6
|
-
cfg: params.cfg,
|
|
7
|
-
approvalId: params.approvalId,
|
|
8
|
-
approvalKind: params.approvalKind,
|
|
9
|
-
decision: params.decision,
|
|
10
|
-
senderId: params.senderId,
|
|
11
|
-
gatewayUrl: params.gatewayUrl,
|
|
12
|
-
clientDisplayName: `WhatsApp approval (${params.senderId?.trim() || "unknown"})`
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
export { isApprovalNotFoundError, resolveWhatsAppApproval };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, r as whatsappSetupAdapter, t as createWhatsAppPluginBase } from "./shared-CAxd15bp.js";
|
|
2
|
-
import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-CAMTrs2U.js";
|
|
3
|
-
//#region extensions/whatsapp/src/channel.setup.ts
|
|
4
|
-
const whatsappSetupPlugin = {
|
|
5
|
-
...createWhatsAppPluginBase({
|
|
6
|
-
groups: {
|
|
7
|
-
resolveRequireMention: resolveWhatsAppGroupRequireMention,
|
|
8
|
-
resolveToolPolicy: resolveWhatsAppGroupToolPolicy
|
|
9
|
-
},
|
|
10
|
-
setupWizard: whatsappSetupWizardProxy,
|
|
11
|
-
setup: whatsappSetupAdapter,
|
|
12
|
-
setupContract: whatsappSetupContract,
|
|
13
|
-
isConfigured: (account) => Boolean(account.authDir),
|
|
14
|
-
isLinked: async (account) => await readWhatsAppAccountLinkState(account.authDir)
|
|
15
|
-
}),
|
|
16
|
-
lifecycle: { detectLegacyStateMigrations: ({ oauthDir }) => detectWhatsAppLegacyStateMigrations({ oauthDir }) }
|
|
17
|
-
};
|
|
18
|
-
//#endregion
|
|
19
|
-
export { whatsappSetupPlugin as t };
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { r as jidToE164 } from "./targets-runtime-TMk0lGuy.js";
|
|
2
|
-
import { t as normalizeE164 } from "./text-runtime-CaKLhowd.js";
|
|
3
|
-
//#region extensions/whatsapp/src/identity.ts
|
|
4
|
-
const WHATSAPP_LID_RE = /@(lid|hosted\.lid)$/i;
|
|
5
|
-
function normalizeDeviceScopedJid(jid) {
|
|
6
|
-
return jid ? jid.replace(/:\d+/, "") : null;
|
|
7
|
-
}
|
|
8
|
-
function isLidJid(jid) {
|
|
9
|
-
return Boolean(jid && WHATSAPP_LID_RE.test(jid));
|
|
10
|
-
}
|
|
11
|
-
function resolveComparableIdentity(identity, authDir) {
|
|
12
|
-
const rawJid = normalizeDeviceScopedJid(identity?.jid);
|
|
13
|
-
const lid = normalizeDeviceScopedJid(identity?.lid) ?? (isLidJid(rawJid) ? rawJid : null);
|
|
14
|
-
const jid = rawJid && !isLidJid(rawJid) ? rawJid : null;
|
|
15
|
-
const e164 = identity?.e164 != null ? normalizeE164(identity.e164) : (jid ? jidToE164(jid, authDir ? { authDir } : void 0) : null) ?? (lid ? jidToE164(lid, authDir ? { authDir } : void 0) : null);
|
|
16
|
-
return {
|
|
17
|
-
...identity,
|
|
18
|
-
jid,
|
|
19
|
-
lid,
|
|
20
|
-
e164
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function getComparableIdentityValues(identity) {
|
|
24
|
-
const resolved = resolveComparableIdentity(identity);
|
|
25
|
-
return [
|
|
26
|
-
resolved.e164,
|
|
27
|
-
resolved.jid,
|
|
28
|
-
resolved.lid
|
|
29
|
-
].filter((value) => Boolean(value));
|
|
30
|
-
}
|
|
31
|
-
function identitiesOverlap(left, right) {
|
|
32
|
-
const leftValues = new Set(getComparableIdentityValues(left));
|
|
33
|
-
if (leftValues.size === 0) return false;
|
|
34
|
-
return getComparableIdentityValues(right).some((value) => leftValues.has(value));
|
|
35
|
-
}
|
|
36
|
-
function getSenderIdentity(msg, authDir) {
|
|
37
|
-
return resolveComparableIdentity(msg.platform.sender ?? {
|
|
38
|
-
jid: msg.platform.senderJid ?? null,
|
|
39
|
-
e164: msg.platform.senderE164 ?? null,
|
|
40
|
-
name: msg.platform.senderName ?? null
|
|
41
|
-
}, authDir);
|
|
42
|
-
}
|
|
43
|
-
function getSelfIdentity(msg, authDir) {
|
|
44
|
-
return resolveComparableIdentity(msg.platform.self ?? {
|
|
45
|
-
jid: msg.platform.selfJid ?? null,
|
|
46
|
-
lid: msg.platform.selfLid ?? null,
|
|
47
|
-
e164: msg.platform.selfE164 ?? null
|
|
48
|
-
}, authDir);
|
|
49
|
-
}
|
|
50
|
-
function getReplyContext(msg, authDir) {
|
|
51
|
-
if (msg.quote?.context) return {
|
|
52
|
-
...msg.quote.context,
|
|
53
|
-
sender: resolveComparableIdentity(msg.quote.context.sender, authDir)
|
|
54
|
-
};
|
|
55
|
-
if (!msg.quote?.body) return null;
|
|
56
|
-
return {
|
|
57
|
-
id: msg.quote.id,
|
|
58
|
-
body: msg.quote.body,
|
|
59
|
-
sender: resolveComparableIdentity({
|
|
60
|
-
jid: msg.quote.sender?.jid ?? null,
|
|
61
|
-
e164: msg.quote.sender?.e164 ?? null,
|
|
62
|
-
label: msg.quote.sender?.displayName ?? null
|
|
63
|
-
}, authDir)
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function getMentionJids(msg) {
|
|
67
|
-
return msg.group?.mentions?.jids ?? [];
|
|
68
|
-
}
|
|
69
|
-
function getMentionIdentities(msg, authDir) {
|
|
70
|
-
return getMentionJids(msg).map((jid) => resolveComparableIdentity({ jid }, authDir));
|
|
71
|
-
}
|
|
72
|
-
function getPrimaryIdentityId(identity) {
|
|
73
|
-
return identity?.e164 || identity?.jid?.trim() || identity?.lid || null;
|
|
74
|
-
}
|
|
75
|
-
//#endregion
|
|
76
|
-
export { getSelfIdentity as a, resolveComparableIdentity as c, getReplyContext as i, getMentionIdentities as n, getSenderIdentity as o, getPrimaryIdentityId as r, identitiesOverlap as s, getComparableIdentityValues as t };
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileExists } from "openclaw/plugin-sdk/security-runtime";
|
|
4
|
-
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
5
|
-
//#region extensions/whatsapp/src/state-migrations.ts
|
|
6
|
-
function isLegacyWhatsAppAuthFile(name) {
|
|
7
|
-
if (name === "creds.json" || name === "creds.json.bak") return true;
|
|
8
|
-
if (!name.endsWith(".json")) return false;
|
|
9
|
-
return /^(app-state-sync|session|sender-key|pre-key)-/.test(name);
|
|
10
|
-
}
|
|
11
|
-
function detectWhatsAppLegacyStateMigrations(params) {
|
|
12
|
-
const targetDir = path.join(params.oauthDir, "whatsapp", DEFAULT_ACCOUNT_ID);
|
|
13
|
-
return (() => {
|
|
14
|
-
try {
|
|
15
|
-
return fs.readdirSync(params.oauthDir, { withFileTypes: true });
|
|
16
|
-
} catch {
|
|
17
|
-
return [];
|
|
18
|
-
}
|
|
19
|
-
})().flatMap((entry) => {
|
|
20
|
-
if (!entry.isFile() || entry.name === "oauth.json" || !isLegacyWhatsAppAuthFile(entry.name)) return [];
|
|
21
|
-
const sourcePath = path.join(params.oauthDir, entry.name);
|
|
22
|
-
const targetPath = path.join(targetDir, entry.name);
|
|
23
|
-
if (fileExists(targetPath)) return [];
|
|
24
|
-
return [{
|
|
25
|
-
kind: "move",
|
|
26
|
-
label: `WhatsApp auth ${entry.name}`,
|
|
27
|
-
sourcePath,
|
|
28
|
-
targetPath
|
|
29
|
-
}];
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
//#endregion
|
|
33
|
-
export { detectWhatsAppLegacyStateMigrations as t };
|