@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.
Files changed (48) hide show
  1. package/dist/{accounts-CSqLvCY5.js → accounts-BX2fZUyR.js} +1 -1
  2. package/dist/{action-runtime-BzfDFPbH.js → action-runtime-B4e3XFOY.js} +2 -2
  3. package/dist/action-runtime-api.js +1 -1
  4. package/dist/action-runtime.runtime.js +1 -1
  5. package/dist/{agent-tools-login-DE9MU98T.js → agent-tools-login-BjRpD-JQ.js} +5 -4
  6. package/dist/api.js +69 -127
  7. package/dist/{approval-handler.runtime-DrA59QSA.js → approval-handler.runtime-fgGZhALv.js} +4 -4
  8. package/dist/{approval-reactions-Cu66aYdq.js → approval-reactions-CmtJCxe_.js} +25 -73
  9. package/dist/auth-presence.js +1 -1
  10. package/dist/{auth-store-DcEpIOmE.js → auth-store-B_DQIdzp.js} +79 -12
  11. package/dist/call-tool-api.js +1 -1
  12. package/dist/{channel-Dg62olhy.js → channel-DJVQHz_V.js} +56 -160
  13. package/dist/channel-plugin-api.js +1 -1
  14. package/dist/{channel-react-action-J_YtyMGX.js → channel-react-action-d6OacTNj.js} +3 -3
  15. package/dist/{channel.runtime-BP0xNmLi.js → channel.runtime-RxuNGZ7w.js} +4 -4
  16. package/dist/channel.setup-Cmvd967u.js +14 -0
  17. package/dist/{connection-controller-BOB2MVKY.js → connection-controller-CUyZgGpf.js} +2 -3
  18. package/dist/contract-api.js +2 -3
  19. package/dist/{creds-files-B1kSWtBg.js → creds-files-W6B3EMZ8.js} +17 -1
  20. package/dist/{directory-config-DalGrfGN.js → directory-config-Pc4f07wB.js} +3 -3
  21. package/dist/directory-contract-api.js +1 -1
  22. package/dist/doctor-contract-api.js +37 -2
  23. package/dist/{group-session-key-DVMZlO3x.js → group-session-key-DmFc_Cqi.js} +23 -4
  24. package/dist/light-runtime-api.js +2 -2
  25. package/dist/{login-CvY2Dhch.js → login-D6_rfxTZ.js} +4 -4
  26. package/dist/{login-qr-Bncpb6js.js → login-qr-B0VyVSqQ.js} +4 -4
  27. package/dist/login-qr-runtime.js +1 -1
  28. package/dist/{monitor-CfkaUSL2.js → monitor-BCe5Mm-1.js} +574 -163
  29. package/dist/{question-reactions-CRsnyoMK.js → question-reactions-D3eAeB0i.js} +29 -78
  30. package/dist/runtime-api.js +9 -9
  31. package/dist/runtime-group-policy-DeSRFXEV.js +11 -0
  32. package/dist/{send-api-7wk6eQyW.js → send-api-DimZST3E.js} +86 -107
  33. package/dist/{send-D37ddk22.js → send-prK8F7Vj.js} +277 -16
  34. package/dist/setup-entry.js +1 -8
  35. package/dist/{setup-finalize-BZucx24W.js → setup-finalize-D3n71Uyx.js} +4 -4
  36. package/dist/setup-plugin-api.js +1 -1
  37. package/dist/{setup-surface-BkVcd769.js → setup-surface-BCZszf3l.js} +3 -3
  38. package/dist/{shared-CAxd15bp.js → shared-Dp9M3ZPX.js} +5 -6
  39. package/dist/{socket-close-DridEuzz.js → socket-close-09FojDO2.js} +4 -10
  40. package/openclaw.plugin.json +4 -0
  41. package/package.json +4 -5
  42. package/skills/wacli/SKILL.md +8 -1
  43. package/dist/access-control-pZcxTmd5.js +0 -363
  44. package/dist/approval-resolver-DoeBBt22.js +0 -16
  45. package/dist/channel.setup-pMwNVkCA.js +0 -19
  46. package/dist/identity-CPrT5aEU.js +0 -76
  47. package/dist/legacy-state-migrations-api.js +0 -2
  48. package/dist/state-migrations-CAMTrs2U.js +0 -33
@@ -1,43 +1,26 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { a as resolveWhatsAppAccount } from "./accounts-CSqLvCY5.js";
3
- import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
2
+ import { a as resolveWhatsAppAccount } from "./accounts-BX2fZUyR.js";
3
+ import { createQuestionReactionTargetStore, questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
4
4
  //#region extensions/whatsapp/src/question-reactions.ts
5
5
  var question_reactions_exports = /* @__PURE__ */ __exportAll({
6
- clearWhatsAppQuestionReactionTargetsForTest: () => clearWhatsAppQuestionReactionTargetsForTest,
7
6
  maybeResolveWhatsAppQuestionReaction: () => maybeResolveWhatsAppQuestionReaction,
8
7
  registerWhatsAppQuestionReactionTargetForDeliveredPayload: () => registerWhatsAppQuestionReactionTargetForDeliveredPayload
9
8
  });
10
- const TARGET_TTL_MS = 1440 * 60 * 1e3;
11
- const targets = /* @__PURE__ */ new Map();
12
- function storeTarget(key, binding) {
13
- const existing = targets.get(key);
14
- if (existing) clearTimeout(existing.cleanupTimer);
15
- const target = {
16
- ...binding,
17
- terminal: false,
18
- expiresAtMs: Date.now() + TARGET_TTL_MS,
19
- cleanupTimer: setTimeout(() => {
20
- if (targets.get(key) === target) targets.delete(key);
21
- }, TARGET_TTL_MS)
22
- };
23
- target.cleanupTimer.unref?.();
24
- targets.set(key, target);
25
- questionGatewayRuntime.registerChannelDelivery({
26
- questionId: binding.questionId,
27
- deliveryId: `whatsapp-reaction:${key}`,
28
- finalize: () => {
29
- target.terminal = true;
30
- }
31
- });
32
- }
33
- function buildKey(accountId, remoteJid, messageId) {
9
+ function buildKey(identity) {
34
10
  const parts = [
35
- accountId,
36
- remoteJid,
37
- messageId
11
+ identity.accountId,
12
+ identity.remoteJid,
13
+ identity.messageId
38
14
  ].map((part) => part.trim());
39
15
  return parts.every(Boolean) ? parts.join(":") : void 0;
40
16
  }
17
+ const questionReactionTargets = createQuestionReactionTargetStore({
18
+ channel: "whatsapp",
19
+ channelDisplayName: "WhatsApp",
20
+ buildKey,
21
+ registerChannelDelivery: questionGatewayRuntime.registerChannelDelivery,
22
+ resolveReaction: questionGatewayRuntime.resolveReaction
23
+ });
41
24
  function addCandidate(values, value) {
42
25
  const normalized = value?.trim();
43
26
  if (normalized && !values.includes(normalized)) values.push(normalized);
@@ -73,12 +56,10 @@ function registerWhatsAppQuestionReactionTargetForDeliveredPayload(params) {
73
56
  accountId: params.target.accountId
74
57
  }).accountId;
75
58
  let registered = false;
76
- for (const identity of listDeliveredIdentities(params.results)) {
77
- const key = buildKey(accountId, identity.remoteJid, identity.messageId);
78
- if (!key) continue;
79
- storeTarget(key, binding);
80
- registered = true;
81
- }
59
+ for (const identity of listDeliveredIdentities(params.results)) registered = questionReactionTargets.register(binding, {
60
+ accountId,
61
+ ...identity
62
+ }) || registered;
82
63
  return registered;
83
64
  }
84
65
  async function maybeResolveWhatsAppQuestionReaction(params) {
@@ -95,48 +76,18 @@ async function maybeResolveWhatsAppQuestionReaction(params) {
95
76
  addCandidate(candidates, remoteJid);
96
77
  for (const mapped of await params.resolveReactionTargetJids?.(remoteJid) ?? []) addCandidate(candidates, mapped);
97
78
  }
98
- let matched;
99
- for (const remoteJid of candidates) {
100
- const key = buildKey(params.accountId, remoteJid, messageId);
101
- const target = key ? targets.get(key) : void 0;
102
- if (key && target) {
103
- matched = {
104
- key,
105
- target
106
- };
107
- break;
108
- }
109
- }
110
- if (!matched) return false;
111
- if (matched.target.expiresAtMs <= Date.now() || matched.target.terminal) {
112
- matched.target.terminal = true;
113
- params.logDebug?.(`whatsapp: stale question reaction ignored id=${matched.target.questionId}`);
114
- return true;
115
- }
116
- const optionValue = matched.target.optionValues[optionIndex];
117
- if (!optionValue) {
118
- params.logDebug?.(`whatsapp: out-of-range question reaction ignored id=${matched.target.questionId}`);
119
- return true;
120
- }
121
- try {
122
- const result = await questionGatewayRuntime.resolveReaction({
123
- cfg: params.cfg,
124
- questionId: matched.target.questionId,
125
- optionValue,
126
- senderId: params.senderId,
127
- gatewayUrl: params.gatewayUrl,
128
- clientDisplayName: `WhatsApp question (${params.senderId})`
129
- });
130
- matched.target.terminal = result?.status === "answered" || result?.status === "already-terminal";
131
- if (result?.status === "already-terminal") params.logDebug?.(`whatsapp: stale question reaction ignored id=${matched.target.questionId}`);
132
- } catch (error) {
133
- params.logDebug?.(`whatsapp: question reaction failed id=${matched.target.questionId}: ${String(error)}`);
134
- }
135
- return true;
136
- }
137
- function clearWhatsAppQuestionReactionTargetsForTest() {
138
- for (const target of targets.values()) clearTimeout(target.cleanupTimer);
139
- targets.clear();
79
+ return await questionReactionTargets.resolve({
80
+ identities: candidates.map((remoteJid) => ({
81
+ accountId: params.accountId,
82
+ remoteJid,
83
+ messageId
84
+ })),
85
+ optionIndex,
86
+ cfg: params.cfg,
87
+ senderId: params.senderId,
88
+ gatewayUrl: params.gatewayUrl,
89
+ logDebug: params.logDebug
90
+ });
140
91
  }
141
92
  //#endregion
142
93
  export { question_reactions_exports as n, maybeResolveWhatsAppQuestionReaction as t };
@@ -1,16 +1,16 @@
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-BzfDFPbH.js";
3
- import { i as sendTypingWhatsApp, n as sendPollWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./send-D37ddk22.js";
1
+ import { c as resolveWebCredsPath, r as hasWebCredsSync, s as resolveWebCredsBackupPath } from "./creds-files-W6B3EMZ8.js";
2
+ import { n as whatsAppActionRuntime, t as handleWhatsAppAction } from "./action-runtime-B4e3XFOY.js";
3
+ import { i as sendTypingWhatsApp, n as sendPollWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./send-prK8F7Vj.js";
4
4
  import { a as setWhatsAppRuntime } from "./runtime-BLlToOi6.js";
5
5
  import { startWebLoginWithQr, waitForWebLogin } from "./login-qr-runtime.js";
6
- import { t as createWhatsAppLoginTool } from "./agent-tools-login-DE9MU98T.js";
7
- import { C as waitForCredsSaveQueue, T as writeCredsJsonAtomically, _ as readWebSelfIdentity, a as formatWhatsAppWebAuthStatusState, b as restoreCredsFromBackupIfNeeded, c as logoutWeb, d as readWebAuthExistsBestEffort, f as readWebAuthExistsForDecision, g as readWebSelfId, h as readWebAuthState, l as pickWebChannel, m as readWebAuthSnapshotBestEffort, n as WHATSAPP_AUTH_UNSTABLE_CODE, o as getWebAuthAgeMs, p as readWebAuthSnapshot, r as WhatsAppAuthUnstableError, s as logWebSelfId, t as WA_WEB_AUTH_DIR, u as readCredsJsonRaw, v as readWebSelfIdentityForDecision, w as waitForCredsSaveQueueWithTimeout, x as webAuthExists, y as resolveDefaultWebAuthDir } from "./auth-store-DcEpIOmE.js";
6
+ import { t as createWhatsAppLoginTool } from "./agent-tools-login-BjRpD-JQ.js";
7
+ import { M as waitForCredsSaveQueueWithTimeout, N as writeCredsJsonAtomically, _ as readWebSelfIdentity, a as formatWhatsAppWebAuthStatusState, b as restoreCredsFromBackupIfNeeded, c as logoutWeb, d as readWebAuthExistsBestEffort, f as readWebAuthExistsForDecision, g as readWebSelfId, h as readWebAuthState, j as waitForCredsSaveQueue, l as pickWebChannel, m as readWebAuthSnapshotBestEffort, n as WHATSAPP_AUTH_UNSTABLE_CODE, o as getWebAuthAgeMs, p as readWebAuthSnapshot, r as WhatsAppAuthUnstableError, s as logWebSelfId, t as WA_WEB_AUTH_DIR, u as readCredsJsonRaw, v as readWebSelfIdentityForDecision, x as webAuthExists, y as resolveDefaultWebAuthDir } from "./auth-store-B_DQIdzp.js";
8
8
  import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-HU41RHGI.js";
9
9
  import { n as resolveWebAccountId, t as getActiveWebListener } from "./active-listener-BEjWsCNM.js";
10
- import { a as waitForWaConnection, i as newConnectionId, r as createWaSocket } from "./socket-close-DridEuzz.js";
10
+ import { a as waitForWaConnection, i as newConnectionId, r as createWaSocket } from "./socket-close-09FojDO2.js";
11
11
  import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.js";
12
- import { g as extractLocationData, p as extractContactContext, y as extractText } from "./send-api-7wk6eQyW.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-CfkaUSL2.js";
14
- import { t as loginWeb } from "./login-CvY2Dhch.js";
12
+ import { p as extractText, s as extractContactContext, u as extractLocationData } from "./send-api-DimZST3E.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-BCe5Mm-1.js";
14
+ import { t as loginWeb } from "./login-D6_rfxTZ.js";
15
15
  import { HEARTBEAT_PROMPT, HEARTBEAT_TOKEN, SILENT_REPLY_TOKEN, stripHeartbeatToken } from "openclaw/plugin-sdk/reply-runtime";
16
16
  export { DEFAULT_WEB_MEDIA_BYTES, HEARTBEAT_PROMPT, HEARTBEAT_TOKEN, LocalMediaAccessError, SILENT_REPLY_TOKEN, WA_WEB_AUTH_DIR, WHATSAPP_AUTH_UNSTABLE_CODE, WhatsAppAuthUnstableError, createWaSocket, createWhatsAppLoginTool, extractContactContext, extractLocationData, extractText, formatError, formatWhatsAppWebAuthStatusState, getActiveWebListener, getDefaultLocalRoots, getStatusCode, getWebAuthAgeMs, handleWhatsAppAction, hasWebCredsSync, loadWebMedia, loadWebMediaRaw, logWebSelfId, loginWeb, logoutWeb, monitorWebChannel, monitorWebInbox, newConnectionId, optimizeImageToJpeg, optimizeImageToPng, pickWebChannel, readCredsJsonRaw, readWebAuthExistsBestEffort, readWebAuthExistsForDecision, readWebAuthSnapshot, readWebAuthSnapshotBestEffort, readWebAuthState, readWebSelfId, readWebSelfIdentity, readWebSelfIdentityForDecision, resetWebInboundDedupe, resolveDefaultWebAuthDir, resolveWebAccountId, resolveWebCredsBackupPath, resolveWebCredsPath, restoreCredsFromBackupIfNeeded, sendMessageWhatsApp, sendPollWhatsApp, sendReactionWhatsApp, sendTypingWhatsApp, setWhatsAppRuntime, startWebLoginWithQr, stripHeartbeatToken, waitForCredsSaveQueue, waitForCredsSaveQueueWithTimeout, waitForWaConnection, waitForWebLogin, webAuthExists, whatsAppActionRuntime, writeCredsJsonAtomically };
@@ -0,0 +1,11 @@
1
+ import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
2
+ //#region extensions/whatsapp/src/runtime-group-policy.ts
3
+ function resolveWhatsAppRuntimeGroupPolicy(params) {
4
+ return resolveOpenProviderRuntimeGroupPolicy({
5
+ providerConfigPresent: params.providerConfigPresent,
6
+ groupPolicy: params.groupPolicy,
7
+ defaultGroupPolicy: params.defaultGroupPolicy
8
+ });
9
+ }
10
+ //#endregion
11
+ export { resolveWhatsAppRuntimeGroupPolicy as t };
@@ -1,17 +1,15 @@
1
1
  import { n as isWhatsAppNewsletterJid } from "./normalize-target-CugRyONv.js";
2
- import { l as resolveWhatsAppDocumentFileName } from "./send-D37ddk22.js";
2
+ import { d as mergeWhatsAppAcceptedSendError, f as normalizeWhatsAppSendResult, g as resolveWhatsAppDocumentFileName, l as combineWhatsAppSendResults, p as rememberWhatsAppAcceptedSend } from "./send-prK8F7Vj.js";
3
3
  import "./normalize-C7Hkc_vE.js";
4
4
  import { c as toWhatsappJid, l as toWhatsappJidWithLid, r as jidToE164 } from "./targets-runtime-TMk0lGuy.js";
5
5
  import "./text-runtime-CaKLhowd.js";
6
- import { i as buildQuotedMessageOptions } from "./group-session-key-DVMZlO3x.js";
7
- import { c as resolveComparableIdentity } from "./identity-CPrT5aEU.js";
8
- import { normalizeLowercaseStringOrEmpty, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
6
+ import { i as buildQuotedMessageOptions } from "./group-session-key-DmFc_Cqi.js";
7
+ import { k as resolveComparableIdentity } from "./auth-store-B_DQIdzp.js";
8
+ import { isRecord, normalizeLowercaseStringOrEmpty, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
10
- import { createMessageReceiptFromOutboundResults, listMessageReceiptPlatformIds } from "openclaw/plugin-sdk/channel-outbound";
11
- import { getImageMetadata, resizeToJpeg } from "openclaw/plugin-sdk/media-runtime";
12
10
  import { formatLocationText } from "openclaw/plugin-sdk/channel-inbound";
13
- import { DisconnectReason, downloadMediaMessage, extractMessageContent, getContentType, isJidGroup, normalizeMessageContent, normalizeMessageContent as normalizeMessageContent$1 } from "baileys";
14
- import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
11
+ import { getImageMetadata, resizeToJpeg } from "openclaw/plugin-sdk/media-runtime";
12
+ import { extractMessageContent, getContentType, normalizeMessageContent } from "baileys";
15
13
  //#region extensions/whatsapp/src/vcard.ts
16
14
  const ALLOWED_VCARD_KEYS = /* @__PURE__ */ new Set([
17
15
  "FN",
@@ -79,11 +77,11 @@ function normalizeVcardPhone(value) {
79
77
  * Falls back to WhatsApp's standard formats when Baileys omits the MIME.
80
78
  */
81
79
  function resolveInboundMediaMimetype(message) {
82
- const explicit = message.imageMessage?.mimetype ?? message.videoMessage?.mimetype ?? message.documentMessage?.mimetype ?? message.audioMessage?.mimetype ?? message.stickerMessage?.mimetype ?? void 0;
80
+ const explicit = message.imageMessage?.mimetype ?? message.videoMessage?.mimetype ?? message.ptvMessage?.mimetype ?? message.documentMessage?.mimetype ?? message.audioMessage?.mimetype ?? message.stickerMessage?.mimetype ?? void 0;
83
81
  if (explicit) return explicit;
84
82
  if (message.audioMessage) return "audio/ogg; codecs=opus";
85
83
  if (message.imageMessage) return "image/jpeg";
86
- if (message.videoMessage) return "video/mp4";
84
+ if (message.videoMessage || message.ptvMessage) return "video/mp4";
87
85
  if (message.stickerMessage) return "image/webp";
88
86
  }
89
87
  //#endregion
@@ -108,6 +106,16 @@ function buildMessageChain(message) {
108
106
  }
109
107
  return chain;
110
108
  }
109
+ function findMessageSection(rawMessage, sectionNames) {
110
+ const chain = buildMessageChain(rawMessage);
111
+ for (const name of sectionNames) for (const message of chain) {
112
+ const value = message[name];
113
+ if (isRecord(value)) return {
114
+ name,
115
+ value
116
+ };
117
+ }
118
+ }
111
119
  function unwrapMessage(message) {
112
120
  return buildMessageChain(message).at(-1);
113
121
  }
@@ -140,20 +148,20 @@ function extractContextInfo(message) {
140
148
  }
141
149
  }
142
150
  function extractMentionedJids(rawMessage) {
143
- const message = unwrapMessage(rawMessage);
144
- if (!message) return;
145
- const flattened = [
146
- message.extendedTextMessage?.contextInfo?.mentionedJid,
147
- message.imageMessage?.contextInfo?.mentionedJid,
148
- message.videoMessage?.contextInfo?.mentionedJid,
149
- message.documentMessage?.contextInfo?.mentionedJid,
150
- message.audioMessage?.contextInfo?.mentionedJid,
151
- message.stickerMessage?.contextInfo?.mentionedJid,
152
- message.buttonsResponseMessage?.contextInfo?.mentionedJid,
153
- message.listResponseMessage?.contextInfo?.mentionedJid
154
- ].flatMap((arr) => arr ?? []).filter(Boolean);
155
- if (flattened.length === 0) return;
156
- return uniqueStrings(flattened);
151
+ const mentionedJids = extractContextInfo(rawMessage)?.mentionedJid?.filter(Boolean);
152
+ if (!mentionedJids?.length) return;
153
+ return uniqueStrings(mentionedJids);
154
+ }
155
+ function extractNativeFlowResponseText(response) {
156
+ const paramsJson = response?.nativeFlowResponseMessage?.paramsJson;
157
+ if (!paramsJson) return;
158
+ try {
159
+ const params = JSON.parse(paramsJson);
160
+ if (!isRecord(params)) return;
161
+ return [params.title, params.id].find((value) => typeof value === "string" && Boolean(value.trim()));
162
+ } catch {
163
+ return;
164
+ }
157
165
  }
158
166
  function extractText(rawMessage) {
159
167
  const message = unwrapMessage(rawMessage);
@@ -165,8 +173,24 @@ function extractText(rawMessage) {
165
173
  if (typeof candidate.conversation === "string" && candidate.conversation.trim()) return candidate.conversation.trim();
166
174
  const extended = candidate.extendedTextMessage?.text;
167
175
  if (extended?.trim()) return extended.trim();
168
- const caption = candidate.imageMessage?.caption ?? candidate.videoMessage?.caption ?? candidate.documentMessage?.caption;
176
+ const caption = candidate.imageMessage?.caption ?? candidate.videoMessage?.caption ?? candidate.ptvMessage?.caption ?? candidate.documentMessage?.caption;
169
177
  if (caption?.trim()) return caption.trim();
178
+ const interactiveSelection = [
179
+ candidate.buttonsResponseMessage?.selectedDisplayText,
180
+ candidate.buttonsResponseMessage?.selectedButtonId,
181
+ candidate.listResponseMessage?.title,
182
+ candidate.listResponseMessage?.singleSelectReply?.selectedRowId,
183
+ candidate.templateButtonReplyMessage?.selectedDisplayText,
184
+ candidate.templateButtonReplyMessage?.selectedId,
185
+ candidate.interactiveResponseMessage?.body?.text,
186
+ extractNativeFlowResponseText(candidate.interactiveResponseMessage)
187
+ ].find((value) => Boolean(value?.trim()));
188
+ if (interactiveSelection) return interactiveSelection.trim();
189
+ const poll = candidate.pollCreationMessage ?? candidate.pollCreationMessageV2 ?? candidate.pollCreationMessageV3 ?? candidate.pollCreationMessageV5;
190
+ if (poll) {
191
+ const pollText = [poll.name?.trim(), ...(poll.options ?? []).map((option) => option.optionName?.trim()).filter((option) => Boolean(option)).map((option) => `- ${option}`)].filter(Boolean).join("\n");
192
+ if (pollText) return pollText;
193
+ }
170
194
  }
171
195
  const contactPlaceholder = extractContactPlaceholder(message) ?? (extracted && extracted !== message ? extractContactPlaceholder(extracted) : void 0);
172
196
  if (contactPlaceholder) return contactPlaceholder;
@@ -188,7 +212,7 @@ function extractMediaKind(rawMessage) {
188
212
  const message = unwrapMessage(rawMessage);
189
213
  if (!message) return;
190
214
  if (message.imageMessage) return "image";
191
- if (message.videoMessage) return "video";
215
+ if (message.videoMessage || message.ptvMessage) return "video";
192
216
  if (message.audioMessage) return "audio";
193
217
  if (message.documentMessage) return "document";
194
218
  if (message.stickerMessage) return "sticker";
@@ -542,75 +566,7 @@ function addWhatsAppOutboundMentionsToContent(content, mentionedJids) {
542
566
  } : content;
543
567
  }
544
568
  //#endregion
545
- //#region extensions/whatsapp/src/inbound/send-result.ts
546
- function resolveWhatsAppReceiptKind(kind) {
547
- if (kind === "media" || kind === "text") return kind;
548
- return "unknown";
549
- }
550
- function toReceiptSourceResult(key) {
551
- return {
552
- channel: "whatsapp",
553
- messageId: key.id,
554
- ...key.remoteJid ? { toJid: key.remoteJid } : {},
555
- meta: {
556
- fromMe: key.fromMe,
557
- participant: key.participant
558
- }
559
- };
560
- }
561
- function createWhatsAppSendReceipt(kind, keys) {
562
- return createMessageReceiptFromOutboundResults({
563
- kind: resolveWhatsAppReceiptKind(kind),
564
- results: keys.map(toReceiptSourceResult)
565
- });
566
- }
567
- function normalizeKey(key) {
568
- const id = typeof key?.id === "string" ? key.id.trim() : "";
569
- if (!id) return;
570
- return {
571
- id,
572
- remoteJid: key?.remoteJid,
573
- fromMe: key?.fromMe,
574
- participant: key?.participant
575
- };
576
- }
577
- function normalizeWhatsAppSendResult(result, kind) {
578
- const key = normalizeKey(result?.key);
579
- return {
580
- kind,
581
- messageId: key?.id ?? "unknown",
582
- receipt: createWhatsAppSendReceipt(kind, key ? [key] : []),
583
- keys: key ? [key] : [],
584
- providerAccepted: Boolean(key)
585
- };
586
- }
587
- function combineWhatsAppSendResults(kind, results) {
588
- const messageIds = uniqueStrings(results.flatMap(listWhatsAppSendResultMessageIds));
589
- const keys = results.flatMap((result) => result.keys);
590
- return {
591
- kind,
592
- messageId: messageIds[0] ?? "unknown",
593
- receipt: createWhatsAppSendReceipt(kind, keys),
594
- keys,
595
- providerAccepted: results.some((result) => result.providerAccepted)
596
- };
597
- }
598
- function listWhatsAppSendResultMessageIds(result) {
599
- const receiptIds = result.receipt ? listMessageReceiptPlatformIds(result.receipt) : [];
600
- if (receiptIds.length > 0) return receiptIds;
601
- const keyIds = normalizeStringEntries(result.keys.map((key) => key.id));
602
- if (keyIds.length > 0) return uniqueStrings(keyIds);
603
- return [];
604
- }
605
- //#endregion
606
569
  //#region extensions/whatsapp/src/inbound/send-api.ts
607
- function recordWhatsAppOutbound(accountId) {
608
- recordChannelActivity({
609
- channel: "whatsapp",
610
- accountId,
611
- direction: "outbound"
612
- });
613
- }
614
570
  function supportsForcedDocumentMediaType(mediaType) {
615
571
  return mediaType.startsWith("image/") || mediaType.startsWith("video/");
616
572
  }
@@ -623,11 +579,30 @@ function createWebSendApi(params) {
623
579
  text,
624
580
  mentionedJids: []
625
581
  };
582
+ const runAcceptedSend = async (kind, accountId, send) => {
583
+ const results = [];
584
+ try {
585
+ await send((result, sendKind) => {
586
+ rememberWhatsAppAcceptedSend({
587
+ accountId,
588
+ result: normalizeWhatsAppSendResult(result, sendKind),
589
+ results
590
+ });
591
+ });
592
+ return combineWhatsAppSendResults(kind, results);
593
+ } catch (error) {
594
+ throw mergeWhatsAppAcceptedSendError({
595
+ error,
596
+ kind,
597
+ results
598
+ });
599
+ }
600
+ };
626
601
  const sendStructuredMessage = async (to, content, kind) => {
627
602
  const jid = resolveOutboundJid(to);
628
- const result = await params.sock.sendMessage(jid, content);
629
- recordWhatsAppOutbound(params.defaultAccountId);
630
- return normalizeWhatsAppSendResult(result, kind);
603
+ return await runAcceptedSend(kind, params.defaultAccountId, async (capture) => {
604
+ capture(await params.sock.sendMessage(jid, content), kind);
605
+ });
631
606
  };
632
607
  return {
633
608
  sendMessage: async (to, text, mediaBuffer, mediaTypeInput, sendOptions) => {
@@ -683,18 +658,22 @@ function createWebSendApi(params) {
683
658
  remoteJid: sendOptions?.quotedMessageKey?.remoteJid,
684
659
  fromMe: sendOptions?.quotedMessageKey?.fromMe,
685
660
  participant: sendOptions?.quotedMessageKey?.participant,
661
+ destinationJid: jid,
662
+ requestedJid: toWhatsappJid(to),
663
+ lookupTargetJid: sendOptions?.quotedMessageKey?.lookupTargetJid,
686
664
  messageText: sendOptions?.quotedMessageKey?.messageText,
687
665
  media: sendOptions?.quotedMessageKey?.media
688
666
  });
689
- const results = [normalizeWhatsAppSendResult(quotedOpts ? await params.sock.sendMessage(jid, payload, quotedOpts) : await params.sock.sendMessage(jid, payload), mediaBuffer ? "media" : "text")];
690
- if (shouldSendAudioText) {
691
- const resolvedAudioText = await resolveMentions(jid, text);
692
- const textPayload = addWhatsAppOutboundMentionsToContent({ text: resolvedAudioText.text }, resolvedAudioText.mentionedJids);
693
- const textResult = quotedOpts ? await params.sock.sendMessage(jid, textPayload, quotedOpts) : await params.sock.sendMessage(jid, textPayload);
694
- results.push(normalizeWhatsAppSendResult(textResult, "text"));
695
- }
696
- recordWhatsAppOutbound(sendOptions?.accountId ?? params.defaultAccountId);
697
- return combineWhatsAppSendResults(mediaBuffer ? "media" : "text", results);
667
+ const kind = mediaBuffer ? "media" : "text";
668
+ const accountId = sendOptions?.accountId ?? params.defaultAccountId;
669
+ return await runAcceptedSend(kind, accountId, async (capture) => {
670
+ const sendPayload = async (content) => quotedOpts ? await params.sock.sendMessage(jid, content, quotedOpts) : await params.sock.sendMessage(jid, content);
671
+ capture(await sendPayload(payload), kind);
672
+ if (shouldSendAudioText) {
673
+ const resolvedAudioText = await resolveMentions(jid, text);
674
+ capture(await sendPayload(addWhatsAppOutboundMentionsToContent({ text: resolvedAudioText.text }, resolvedAudioText.mentionedJids)), "text");
675
+ }
676
+ });
698
677
  },
699
678
  sendPoll: async (to, poll) => {
700
679
  return await sendStructuredMessage(to, { poll: {
@@ -746,4 +725,4 @@ function createWebSendApi(params) {
746
725
  };
747
726
  }
748
727
  //#endregion
749
- export { extractMediaKind as _, mayContainWhatsAppOutboundMention as a, hasInboundUserContent as b, DisconnectReason as c, normalizeMessageContent$1 as d, describeReplyContext as f, extractLocationData as g, extractExternalAdReplyContext as h, addWhatsAppOutboundMentionsToContent as i, downloadMediaMessage as l, extractContextInfo as m, listWhatsAppSendResultMessageIds as n, resolveWhatsAppOutboundMentions as o, extractContactContext as p, normalizeWhatsAppSendResult as r, addWhatsAppImagePreviewFields as s, createWebSendApi as t, isJidGroup as u, extractMentionedJids as v, resolveInboundMediaMimetype as x, extractText as y };
728
+ export { addWhatsAppImagePreviewFields as a, extractContextInfo as c, extractMediaKind as d, extractMentionedJids as f, resolveInboundMediaMimetype as g, hasInboundUserContent as h, resolveWhatsAppOutboundMentions as i, extractExternalAdReplyContext as l, findMessageSection as m, addWhatsAppOutboundMentionsToContent as n, describeReplyContext as o, extractText as p, mayContainWhatsAppOutboundMention as r, extractContactContext as s, createWebSendApi as t, extractLocationData as u };