@openclaw/whatsapp 2026.10.2 → 2026.10.5-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/.setup/{action-runtime-CE3zGstN.mjs → action-runtime-DUSkWTiZ.mjs} +2 -2
- package/dist/.setup/{agent-tools-login-B7VEvJO7.mjs → agent-tools-login-CB7OQbli.mjs} +5 -15
- package/dist/.setup/{approval-handler.runtime-CKposl6w.mjs → approval-handler.runtime-BEaAKSoU.mjs} +3 -3
- package/dist/.setup/{approval-reactions-CD6CDF9k.mjs → approval-reactions-CWkZ_ham.mjs} +7 -16
- package/dist/.setup/audio-preflight.runtime-Dg8oZgre.mjs +2 -0
- package/dist/.setup/{auth-store-D2rN-hP5.mjs → auth-store-DOBi5BPe.mjs} +10 -11
- package/dist/.setup/{channel-DNgKHMCz.mjs → channel-DcHw3Up2.mjs} +136 -135
- package/dist/.setup/{channel-react-action-BaBV9X6M.mjs → channel-react-action-C5E8_iDk.mjs} +3 -3
- package/dist/.setup/{channel.runtime-BniF8Swm.mjs → channel.runtime-DTj-wkEP.mjs} +5 -11
- package/dist/.setup/channel.setup-BJWEyQlF.mjs +5 -0
- package/dist/.setup/{connection-controller-COkcq48K.mjs → connection-controller-CejM7bhn.mjs} +50 -84
- package/dist/.setup/{directory-config-RYQomHyB.mjs → directory-config-DPLTUAqy.mjs} +22 -29
- package/dist/.setup/{group-session-key-BV8Le9r8.mjs → group-session-key-BbTPosdy.mjs} +12 -18
- package/dist/.setup/{login-CV_4V021.mjs → login-DUx5JYuW.mjs} +3 -3
- package/dist/.setup/{login-qr-DFhGc5yH.mjs → login-qr-BAWbPonj.mjs} +24 -45
- package/dist/.setup/{monitor-B5DS4PDV.mjs → monitor-CmXEQad9.mjs} +218 -367
- package/dist/.setup/{normalize-target-BGra1ZnM.mjs → normalize-target-D67Kc3g6.mjs} +5 -8
- package/dist/.setup/{question-reactions-LMeijbaq.mjs → question-reactions-DywNaX8m.mjs} +3 -10
- package/dist/.setup/reaction-target-CSPO7gtu.mjs +11 -0
- package/dist/.setup/{resolve-outbound-target-CzyNKmrl.mjs → resolve-outbound-target-qikGL4r0.mjs} +3 -4
- package/dist/.setup/{send-CGUsUdoX.mjs → send-CLBfAzd6.mjs} +34 -42
- package/dist/.setup/{send-api-B03VDwZ1.mjs → send-api-COzRvqXx.mjs} +28 -60
- package/dist/.setup/{setup-finalize-GtBmrO8p.mjs → setup-finalize-DSiP_-wa.mjs} +53 -69
- package/dist/.setup/setup-plugin-api-8WdNCjRW.mjs +3 -0
- package/dist/.setup/{setup-surface-BuA39k6K.mjs → setup-surface-C_flQyHy.mjs} +2 -2
- package/dist/.setup/{shared-CP_zs2U7.mjs → shared-SqcOkt51.mjs} +4 -4
- package/dist/.setup/{socket-close-DU7eerAa.mjs → socket-close-C9OU9mVN.mjs} +67 -86
- package/dist/.setup/{targets-runtime-Dls-Xh4F.mjs → targets-runtime-D5ryyPxh.mjs} +16 -25
- package/dist/action-runtime-api.js +1 -1
- package/dist/action-runtime.runtime.js +1 -1
- package/dist/agent-tools-api.js +4 -8
- package/dist/api.js +13 -15
- package/dist/channel-plugin-api.js +1 -1
- package/dist/contract-api.js +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +12 -32
- package/dist/light-runtime-api.js +2 -2
- package/dist/login-qr-runtime.js +2 -4
- package/dist/runtime-api.js +8 -8
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode/package.json +7 -7
- package/node_modules/audio-decode/node_modules/@audio/decode/readme.md +2 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/README.md +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/decode-aac.d.ts +22 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/decode-aac.js +142 -7
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/package.json +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/README.md +2 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/decode-caf.js +4 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/package.json +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/decode-flac.js +161 -29
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/package.json +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/README.md +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/decode-mp4.js +127 -28
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/package.json +3 -3
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/package.json +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/src/decode-opus.js +2 -2
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/README.md +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/decode-qoa.js +79 -227
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/package.json +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/decode-vorbis.js +51 -10
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/package.json +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/decode-wav.js +40 -18
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/package.json +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/LICENSE.ffmpeg +502 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/README.md +5 -5
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/decode-wma.js +15 -3
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/package.json +5 -4
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/src/wma.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/audio-type/audio-type.js +13 -0
- package/node_modules/audio-decode/node_modules/audio-type/package.json +1 -1
- package/node_modules/audio-decode/node_modules/audio-type/readme.md +1 -1
- package/node_modules/baileys/lib/Utils/messages-media.js +7 -11
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/diagnostics-channel-react-native.d.ts.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/diagnostics-channel-react-native.js.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/diagnostics-channel.d.ts +5 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/diagnostics-channel.js +7 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/index.d.ts +1400 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/index.d.ts.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/index.js +1733 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/index.js.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/perf.d.ts +12 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/perf.d.ts.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/perf.js +10 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/commonjs/react-native/perf.js.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/diagnostics-channel-react-native.d.ts.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/diagnostics-channel-react-native.js.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/diagnostics-channel.d.ts +5 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/diagnostics-channel.js +4 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/index.d.ts +1400 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/index.d.ts.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/index.js +1729 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/index.js.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/perf.d.ts +12 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/perf.d.ts.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/perf.js +7 -0
- package/node_modules/baileys/node_modules/lru-cache/dist/esm/react-native/perf.js.map +1 -0
- package/node_modules/baileys/node_modules/lru-cache/package.json +27 -1
- package/node_modules/baileys/node_modules/music-metadata/README.md +35 -32
- package/node_modules/baileys/node_modules/music-metadata/lib/ParserFactory.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ParserFactory.js +17 -13
- package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffParser.js +19 -12
- package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffToken.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffToken.js +2 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Parser.d.ts +4 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Parser.js +59 -16
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2TagMapper.js +1 -0
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Token.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Token.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfGuid.js +56 -50
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfObject.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfObject.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfParser.js +15 -7
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfTagMapper.d.ts +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfTagMapper.js +21 -4
- package/node_modules/baileys/node_modules/music-metadata/lib/common/CaseInsensitiveTagMap.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/common/CombinedTagMapper.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/common/CombinedTagMapper.js +6 -6
- package/node_modules/baileys/node_modules/music-metadata/lib/common/FourCC.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/common/GenericTagMapper.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/common/GenericTagTypes.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/common/MetadataCollector.d.ts +3 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/common/MetadataCollector.js +28 -9
- package/node_modules/baileys/node_modules/music-metadata/lib/common/Util.js +25 -17
- package/node_modules/baileys/node_modules/music-metadata/lib/core.d.ts +4 -4
- package/node_modules/baileys/node_modules/music-metadata/lib/core.js +18 -11
- package/node_modules/baileys/node_modules/music-metadata/lib/dsdiff/DsdiffParser.js +29 -16
- package/node_modules/baileys/node_modules/music-metadata/lib/dsf/DsfChunk.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/dsf/DsfParser.js +3 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/ebml/EbmlIterator.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ebml/EbmlIterator.js +35 -6
- package/node_modules/baileys/node_modules/music-metadata/lib/ebml/types.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ebml/types.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacParser.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacParser.js +6 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacToken.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacToken.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v1/ID3v1Parser.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v1/ID3v1Parser.js +212 -42
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/AbstractID3Parser.js +5 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameHeader.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameHeader.js +8 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameParser.d.ts +2 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameParser.js +54 -23
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v22TagMapper.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v22TagMapper.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v24TagMapper.js +3 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2ChapterToken.js +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Parser.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Parser.js +32 -16
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Token.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Token.js +2 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/index.js +6 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/lrc/LyricsParser.js +3 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/matroska/MatroskaDtd.js +7 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/matroska/MatroskaParser.js +22 -11
- package/node_modules/baileys/node_modules/music-metadata/lib/matroska/types.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/Atom.d.ts +4 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/Atom.js +44 -11
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/AtomToken.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/AtomToken.js +30 -8
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4Parser.d.ts +2 -0
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4Parser.js +79 -54
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4TagMapper.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/MpegLoader.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/MpegParser.js +41 -19
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/ReplayGainDataFormat.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/ReplayGainDataFormat.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/XingTag.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/MusepackParser.js +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/BitReader.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/MpcSv7Parser.js +4 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/StreamVersion7.js +3 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv8/MpcSv8Parser.js +7 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv8/StreamVersion8.js +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/OggParser.js +23 -13
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/OggToken.d.ts +2 -0
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/OggToken.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/flac/FlacStream.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/flac/FlacStream.js +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/opus/OpusStream.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/opus/OpusStream.js +8 -4
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/speex/SpeexStream.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/speex/SpeexStream.js +2 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/theora/TheoraStream.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/Vorbis.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisDecoder.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisStream.d.ts +4 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisStream.js +16 -9
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisTagMapper.js +4 -0
- package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffChunk.d.ts +3 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffChunk.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffInfoTagMap.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/type.d.ts +3 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/type.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveChunk.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveChunk.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveParser.d.ts +6 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveParser.js +75 -22
- package/node_modules/baileys/node_modules/music-metadata/lib/wavpack/WavPackParser.js +22 -13
- package/node_modules/baileys/node_modules/music-metadata/lib/wavpack/WavPackToken.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/package.json +3 -2
- package/node_modules/baileys/node_modules/uint8array-extras/index.d.ts +7 -7
- package/node_modules/baileys/node_modules/uint8array-extras/index.js +27 -13
- package/node_modules/baileys/node_modules/uint8array-extras/package.json +6 -6
- package/node_modules/baileys/node_modules/uint8array-extras/readme.md +7 -7
- package/node_modules/baileys/node_modules/ws/lib/websocket.js +17 -3
- package/node_modules/baileys/node_modules/ws/package.json +1 -1
- package/package.json +4 -4
- package/dist/.setup/audio-preflight.runtime-C_glQhZY.mjs +0 -7
- package/dist/.setup/channel.setup-CsS_NAKQ.mjs +0 -5
- package/dist/.setup/setup-plugin-api-Bsp7jI-r.mjs +0 -3
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { n as __reExport, t as __exportAll } from "./rolldown-runtime-BBjsoOtd.mjs";
|
|
2
2
|
import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-F0vHuze2.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { c as prepareWhatsAppOutboundMedia, d as listWhatsAppSendResultMessageIds, f as mergeWhatsAppAcceptedSendError, g as withWhatsAppLogicalDeliveryActivity, h as rememberWhatsAppPartialSend, m as rememberWhatsAppAcceptedSend, o as normalizeWhatsAppOutboundPayload, p as normalizeWhatsAppSendResult, r as sendReactionWhatsApp, s as normalizeWhatsAppPayloadTextPreservingIndentation, v as resolveWhatsAppReactionLevel } from "./send-CLBfAzd6.mjs";
|
|
4
4
|
import { i as getWhatsAppRuntime } from "./runtime-BLlToOi6.mjs";
|
|
5
5
|
import { r as getWhatsAppConnectionController } from "./connection-controller-runtime-context-hgLJoRc8.mjs";
|
|
6
|
-
import { a as markdownToWhatsAppChunks, c as toWhatsappJid, l as toWhatsappJidWithLid, n as isSelfChatMode, o as resolveEquivalentWhatsAppDirectChatJids, r as jidToE164, s as resolveJidToE164 } from "./targets-runtime-
|
|
7
|
-
import { a as lookupInboundMessageMeta, i as cacheInboundMessageMeta, n as resolveWhatsAppGroupSessionRoute, r as buildQuotedMessageOptions } from "./group-session-key-
|
|
8
|
-
import { C as getPrimaryIdentityId, D as identitiesOverlap, E as getSenderIdentity, O as resolveComparableIdentity, S as getMentionIdentities, T as getSelfIdentity, _ as readWebSelfIdentityForDecision, h as readWebSelfId, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, w as getReplyContext, x as getComparableIdentityValues } from "./auth-store-
|
|
6
|
+
import { a as markdownToWhatsAppChunks, c as toWhatsappJid, l as toWhatsappJidWithLid, n as isSelfChatMode, o as resolveEquivalentWhatsAppDirectChatJids, r as jidToE164, s as resolveJidToE164 } from "./targets-runtime-D5ryyPxh.mjs";
|
|
7
|
+
import { a as lookupInboundMessageMeta, i as cacheInboundMessageMeta, n as resolveWhatsAppGroupSessionRoute, r as buildQuotedMessageOptions } from "./group-session-key-BbTPosdy.mjs";
|
|
8
|
+
import { C as getPrimaryIdentityId, D as identitiesOverlap, E as getSenderIdentity, O as resolveComparableIdentity, S as getMentionIdentities, T as getSelfIdentity, _ as readWebSelfIdentityForDecision, h as readWebSelfId, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, w as getReplyContext, x as getComparableIdentityValues } from "./auth-store-DOBi5BPe.mjs";
|
|
9
9
|
import { n as resolveWhatsAppGroupsConfigPath } from "./group-config-path-BPrak_bJ.mjs";
|
|
10
|
-
import { a as DEFAULT_RECONNECT_POLICY, c as resolveHeartbeatSeconds, f as createWhatsAppSocketOperationTimeoutAdapter, g as withWhatsAppSocketOperationTimeout, h as resolveWhatsAppSocketTiming, i as waitForWaConnection, l as resolveReconnectPolicy, m as resolveWhatsAppSocketOperationTimeoutMs, o as computeBackoff, p as isWhatsAppSocketOperationTimeoutError, r as createWaSocket, s as newConnectionId, u as sleepWithAbort$1 } from "./socket-close-
|
|
10
|
+
import { a as DEFAULT_RECONNECT_POLICY, c as resolveHeartbeatSeconds, f as createWhatsAppSocketOperationTimeoutAdapter, g as withWhatsAppSocketOperationTimeout, h as resolveWhatsAppSocketTiming, i as waitForWaConnection, l as resolveReconnectPolicy, m as resolveWhatsAppSocketOperationTimeoutMs, o as computeBackoff, p as isWhatsAppSocketOperationTimeoutError, r as createWaSocket, s as newConnectionId, u as sleepWithAbort$1 } from "./socket-close-C9OU9mVN.mjs";
|
|
11
11
|
import { n as getStatusCode, t as formatError } from "./session-errors-B8UcAnZN.mjs";
|
|
12
12
|
import { t as BufferJSON } from "./session.runtime-st1konFI.mjs";
|
|
13
|
-
import { _ as resolveInboundMediaMimetype, a as addWhatsAppImagePreviewFields, c as extractContextInfo, d as extractMediaKind, f as extractMentionedJids, g as projectWhatsAppInboundMessage, h as hasInboundUserContent, i as resolveWhatsAppOutboundMentions, l as extractExternalAdReplyContext, n as addWhatsAppOutboundMentionsToContent, o as describeReplyContext, p as extractText, r as mayContainWhatsAppOutboundMention, s as extractContactContext, t as createWebSendApi, u as extractLocationData } from "./send-api-
|
|
14
|
-
import { n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController } from "./connection-controller-
|
|
15
|
-
import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-
|
|
16
|
-
import { t as maybeResolveWhatsAppQuestionReaction } from "./question-reactions-
|
|
13
|
+
import { _ as resolveInboundMediaMimetype, a as addWhatsAppImagePreviewFields, c as extractContextInfo, d as extractMediaKind, f as extractMentionedJids, g as projectWhatsAppInboundMessage, h as hasInboundUserContent, i as resolveWhatsAppOutboundMentions, l as extractExternalAdReplyContext, n as addWhatsAppOutboundMentionsToContent, o as describeReplyContext, p as extractText, r as mayContainWhatsAppOutboundMention, s as extractContactContext, t as createWebSendApi, u as extractLocationData } from "./send-api-COzRvqXx.mjs";
|
|
14
|
+
import { n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController } from "./connection-controller-CejM7bhn.mjs";
|
|
15
|
+
import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-CWkZ_ham.mjs";
|
|
16
|
+
import { t as maybeResolveWhatsAppQuestionReaction } from "./question-reactions-DywNaX8m.mjs";
|
|
17
17
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
18
18
|
import { createAckReactionHandle, createStatusReactionController, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
19
19
|
import { bindIngressLifecycleToReplyOptions, createChannelIngressMonitor, createChannelMessageReplyPipeline, createMessageReceiptFromOutboundResults, listMessageReceiptPlatformIds, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
|
|
@@ -24,11 +24,10 @@ import { resolveMarkdownTableMode as resolveMarkdownTableMode$1 } from "openclaw
|
|
|
24
24
|
import { createSubsystemLogger as createSubsystemLogger$1, defaultRuntime, formatDurationPrecise, getChildLogger as getChildLogger$1, logVerbose, logVerbose as logVerbose$1, registerUnhandledRejectionHandler, shouldLogVerbose, shouldLogVerbose as shouldLogVerbose$1, warn } from "openclaw/plugin-sdk/runtime-env";
|
|
25
25
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
26
26
|
import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
|
|
27
|
-
import { buildChannelInboundEventContext, createChannelPartialDeliveryError, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundEnvelope as formatInboundEnvelope$1, formatInboundMediaUnavailableText, formatLocationText, formatMediaPlaceholderText, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, readAgentRunTerminalOutcome, resolveGroupThreadConfig,
|
|
27
|
+
import { buildChannelInboundEventContext, createChannelPartialDeliveryError, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundEnvelope as formatInboundEnvelope$1, formatInboundMediaUnavailableText, formatLocationText, formatMediaPlaceholderText, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, readAgentRunTerminalOutcome, resolveGroupThreadConfig, resolveInboundSessionEnvelopeContextAsync, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, runGroupThread, shouldDebounceTextInbound, toInboundMediaFactsWithMetadata, toLocationContext } from "openclaw/plugin-sdk/channel-inbound";
|
|
28
28
|
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
|
|
29
29
|
import { isReasoningReplyPayload, resolveSendableOutboundReplyParts, resolveTextChunksWithFallback, sendMediaWithLeadingCaption } from "openclaw/plugin-sdk/reply-payload";
|
|
30
30
|
import { normalizeE164, normalizeE164 as normalizeE164$1, normalizeE164 as normalizeE164$2, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
31
|
-
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
32
31
|
import { DisconnectReason, downloadMediaMessage, isHostedLidUser, isHostedPnUser, isJidGroup, isJidGroup as isJidGroup$1, jidDecode, jidEncode, jidNormalizedUser, normalizeMessageContent as normalizeMessageContent$1 } from "baileys";
|
|
33
32
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
34
33
|
import { DEFAULT_MAIN_KEY, buildAgentMainSessionKey, buildAgentSessionKey, buildGroupHistoryKey, deriveLastRoutePolicy, resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
@@ -382,22 +381,14 @@ function createWhatsAppGroupMetadataCacheOwner(params) {
|
|
|
382
381
|
});
|
|
383
382
|
};
|
|
384
383
|
const applyOutboundMentions = async (jid, content) => {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
if (typeof caption === "string") {
|
|
394
|
-
const resolved = await resolveOutboundMentions(jid, caption);
|
|
395
|
-
return addWhatsAppOutboundMentionsToContent({
|
|
396
|
-
...content,
|
|
397
|
-
caption: resolved.text
|
|
398
|
-
}, resolved.mentionedJids);
|
|
399
|
-
}
|
|
400
|
-
return content;
|
|
384
|
+
const field = "text" in content && typeof content.text === "string" ? "text" : "caption";
|
|
385
|
+
const text = content[field];
|
|
386
|
+
if (typeof text !== "string") return content;
|
|
387
|
+
const resolved = await resolveOutboundMentions(jid, text);
|
|
388
|
+
return addWhatsAppOutboundMentionsToContent({
|
|
389
|
+
...content,
|
|
390
|
+
[field]: resolved.text
|
|
391
|
+
}, resolved.mentionedJids);
|
|
401
392
|
};
|
|
402
393
|
const start = () => {
|
|
403
394
|
if (started || closed) return;
|
|
@@ -636,39 +627,33 @@ function createWhatsAppInboundMessageDebouncer(options) {
|
|
|
636
627
|
const last = orderedEntries.at(-1);
|
|
637
628
|
if (!last) return;
|
|
638
629
|
try {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
630
|
+
let message = last;
|
|
631
|
+
if (orderedEntries.length > 1) {
|
|
632
|
+
const mentioned = /* @__PURE__ */ new Set();
|
|
633
|
+
for (const entry of orderedEntries) for (const jid of entry.group?.mentions?.jids ?? []) mentioned.add(jid);
|
|
634
|
+
const combinedMentions = mentioned.size > 0 ? {
|
|
635
|
+
...last.group?.mentions,
|
|
636
|
+
jids: Array.from(mentioned)
|
|
637
|
+
} : last.group?.mentions;
|
|
638
|
+
message = {
|
|
639
|
+
...last,
|
|
640
|
+
turnAdoptionLifecycle: admissionLifecycle,
|
|
641
|
+
payload: {
|
|
642
|
+
...last.payload,
|
|
643
|
+
body: orderedEntries.map((entry) => entry.payload.body).filter(Boolean).join("\n"),
|
|
644
|
+
commandBody: orderedEntries.map((entry) => entry.payload.commandBody ?? entry.payload.body).filter(Boolean).join("\n")
|
|
645
|
+
},
|
|
646
|
+
group: last.group || combinedMentions ? {
|
|
647
|
+
...last.group,
|
|
648
|
+
mentions: combinedMentions
|
|
649
|
+
} : void 0,
|
|
650
|
+
event: {
|
|
651
|
+
...last.event,
|
|
652
|
+
isBatched: true
|
|
653
|
+
}
|
|
654
|
+
};
|
|
644
655
|
}
|
|
645
|
-
|
|
646
|
-
for (const entry of orderedEntries) for (const jid of entry.group?.mentions?.jids ?? []) mentioned.add(jid);
|
|
647
|
-
const combinedBody = orderedEntries.map((entry) => entry.payload.body).filter(Boolean).join("\n");
|
|
648
|
-
const combinedCommandBody = orderedEntries.map((entry) => entry.payload.commandBody ?? entry.payload.body).filter(Boolean).join("\n");
|
|
649
|
-
const combinedMentions = mentioned.size > 0 ? {
|
|
650
|
-
...last.group?.mentions,
|
|
651
|
-
jids: Array.from(mentioned)
|
|
652
|
-
} : last.group?.mentions;
|
|
653
|
-
const combinedGroup = last.group || combinedMentions ? {
|
|
654
|
-
...last.group,
|
|
655
|
-
mentions: combinedMentions
|
|
656
|
-
} : void 0;
|
|
657
|
-
const combinedMessage = attachWhatsAppIngressLifecycle({
|
|
658
|
-
...last,
|
|
659
|
-
turnAdoptionLifecycle: admissionLifecycle,
|
|
660
|
-
payload: {
|
|
661
|
-
...last.payload,
|
|
662
|
-
body: combinedBody,
|
|
663
|
-
commandBody: combinedCommandBody
|
|
664
|
-
},
|
|
665
|
-
group: combinedGroup,
|
|
666
|
-
event: {
|
|
667
|
-
...last.event,
|
|
668
|
-
isBatched: true
|
|
669
|
-
}
|
|
670
|
-
}, admissionLifecycle);
|
|
671
|
-
await options.onMessage(combinedMessage);
|
|
656
|
+
await options.onMessage(attachWhatsAppIngressLifecycle(message, admissionLifecycle));
|
|
672
657
|
await settle();
|
|
673
658
|
await Promise.all(orderedEntries.map((entry) => options.markRead(entry.readReceipt)));
|
|
674
659
|
} catch (error) {
|
|
@@ -827,15 +812,17 @@ async function enrichWhatsAppInboundMessage(params) {
|
|
|
827
812
|
kind: mediaKind
|
|
828
813
|
} : void 0;
|
|
829
814
|
let mediaFileName;
|
|
815
|
+
let savedContentType;
|
|
830
816
|
const maxBytes = (typeof params.mediaMaxMb === "number" && params.mediaMaxMb > 0 ? params.mediaMaxMb : 50) * 1024 * 1024;
|
|
831
|
-
const saveInboundMedia =
|
|
817
|
+
const saveInboundMedia = (inboundMedia) => {
|
|
832
818
|
if (!inboundMedia) return;
|
|
833
819
|
mediaPath = inboundMedia.saved.path;
|
|
834
820
|
mediaType = inboundMedia.mimetype;
|
|
835
821
|
mediaFileName = inboundMedia.fileName;
|
|
822
|
+
savedContentType = inboundMedia.saved.contentType;
|
|
836
823
|
};
|
|
837
824
|
try {
|
|
838
|
-
|
|
825
|
+
saveInboundMedia(await downloadInboundMedia(msg, sock, maxBytes, messageProjection[0]));
|
|
839
826
|
} catch (error) {
|
|
840
827
|
logMediaMaterializationFailure({
|
|
841
828
|
messageId: msg.key?.id,
|
|
@@ -851,7 +838,7 @@ async function enrichWhatsAppInboundMessage(params) {
|
|
|
851
838
|
});
|
|
852
839
|
}
|
|
853
840
|
if (!mediaPath && !mediaKind && replyContext?.media) try {
|
|
854
|
-
|
|
841
|
+
saveInboundMedia(await downloadQuotedInboundMedia(msg, sock, maxBytes));
|
|
855
842
|
mediaKind = replyContext.media.kind ?? void 0;
|
|
856
843
|
mediaType = mediaType ?? replyContext.media.contentType ?? void 0;
|
|
857
844
|
} catch (error) {
|
|
@@ -868,6 +855,7 @@ async function enrichWhatsAppInboundMessage(params) {
|
|
|
868
855
|
notice: "[whatsapp quoted attachment unavailable]"
|
|
869
856
|
});
|
|
870
857
|
}
|
|
858
|
+
if (mediaKind === "document" && savedContentType?.startsWith("image/")) mediaKind = "image";
|
|
871
859
|
return {
|
|
872
860
|
body,
|
|
873
861
|
commandBody,
|
|
@@ -1416,10 +1404,7 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1416
1404
|
}) : void 0;
|
|
1417
1405
|
let resolvePrepared;
|
|
1418
1406
|
if (durableId && !preparedInboundByDurableId.has(durableId)) {
|
|
1419
|
-
|
|
1420
|
-
const oldest = preparedInboundByDurableId.keys().next().value;
|
|
1421
|
-
if (oldest !== void 0) preparedInboundByDurableId.delete(oldest);
|
|
1422
|
-
}
|
|
1407
|
+
pruneMapToMaxSize(preparedInboundByDurableId, 999);
|
|
1423
1408
|
const prepared = createDeferred();
|
|
1424
1409
|
resolvePrepared = prepared.resolve;
|
|
1425
1410
|
preparedInboundByDurableId.set(durableId, prepared.promise);
|
|
@@ -1599,13 +1584,17 @@ async function createWhatsAppAttachedSocketSession(options) {
|
|
|
1599
1584
|
rememberOutboundMessage(jid, result);
|
|
1600
1585
|
}, () => {});
|
|
1601
1586
|
};
|
|
1587
|
+
const currentSocketOperations = (currentSock) => createWhatsAppSocketOperationTimeoutAdapter(currentSock, sendOperationTimeoutMs, {
|
|
1588
|
+
assertCurrent: () => {
|
|
1589
|
+
if (getCurrentSock() !== currentSock) throw new Error(RECONNECT_IN_PROGRESS_ERROR);
|
|
1590
|
+
},
|
|
1591
|
+
onSendMessageTimeout: ({ jid, promise }) => trackLateAcceptedSend(jid, promise)
|
|
1592
|
+
});
|
|
1602
1593
|
let reachoutTimeLock;
|
|
1603
1594
|
let reachoutTimeLockFetch;
|
|
1604
|
-
let reachoutTimeLockVersion = 0;
|
|
1605
1595
|
let verifiedSendReady;
|
|
1606
1596
|
const rememberReachoutTimeLock = (state) => {
|
|
1607
1597
|
reachoutTimeLock = state;
|
|
1608
|
-
reachoutTimeLockVersion += 1;
|
|
1609
1598
|
verifiedSendReady = void 0;
|
|
1610
1599
|
};
|
|
1611
1600
|
const fetchReachoutTimeLock = async (currentSock) => {
|
|
@@ -1620,28 +1609,22 @@ async function createWhatsAppAttachedSocketSession(options) {
|
|
|
1620
1609
|
});
|
|
1621
1610
|
return await reachoutTimeLockFetch;
|
|
1622
1611
|
};
|
|
1623
|
-
const rememberVerifiedSendReady = (jid, currentSock) => {
|
|
1624
|
-
verifiedSendReady = {
|
|
1625
|
-
jid,
|
|
1626
|
-
sock: currentSock,
|
|
1627
|
-
reachoutTimeLockVersion
|
|
1628
|
-
};
|
|
1629
|
-
};
|
|
1630
|
-
const consumeVerifiedSendReady = (jid, currentSock) => {
|
|
1631
|
-
if (verifiedSendReady?.jid !== jid || verifiedSendReady.sock !== currentSock || verifiedSendReady.reachoutTimeLockVersion !== reachoutTimeLockVersion) return false;
|
|
1632
|
-
verifiedSendReady = void 0;
|
|
1633
|
-
return true;
|
|
1634
|
-
};
|
|
1635
1612
|
const assertCanSendToJid = async (jid, currentSock, readinessOptions) => {
|
|
1636
1613
|
if (!isDirectUserJid(jid)) return;
|
|
1637
|
-
if (readinessOptions?.useVerifiedReady &&
|
|
1614
|
+
if (readinessOptions?.useVerifiedReady && verifiedSendReady?.jid === jid && verifiedSendReady.sock === currentSock) {
|
|
1615
|
+
verifiedSendReady = void 0;
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1638
1618
|
const state = getActiveReachoutTimelock(reachoutTimeLock) ?? await fetchReachoutTimeLock(currentSock);
|
|
1639
1619
|
const activeState = getActiveReachoutTimelock(state);
|
|
1640
1620
|
if (activeState) {
|
|
1641
1621
|
const error = new Error(formatReachoutTimelockError(activeState));
|
|
1642
1622
|
throw readinessOptions?.rememberReady ? new PlatformMessageNotDispatchedError(error.message, { cause: error }) : error;
|
|
1643
1623
|
}
|
|
1644
|
-
if (readinessOptions?.rememberReady && state)
|
|
1624
|
+
if (readinessOptions?.rememberReady && state) verifiedSendReady = {
|
|
1625
|
+
jid,
|
|
1626
|
+
sock: currentSock
|
|
1627
|
+
};
|
|
1645
1628
|
};
|
|
1646
1629
|
const assertSendReady = async (to) => {
|
|
1647
1630
|
const currentSock = getCurrentSock();
|
|
@@ -1655,9 +1638,7 @@ async function createWhatsAppAttachedSocketSession(options) {
|
|
|
1655
1638
|
const currentSock = getCurrentSock();
|
|
1656
1639
|
if (currentSock) try {
|
|
1657
1640
|
await assertCanSendToJid(jid, currentSock, { useVerifiedReady: true });
|
|
1658
|
-
const result = await
|
|
1659
|
-
trackLateAcceptedSend(timedOutJid, promise);
|
|
1660
|
-
} }).sendMessage(jid, content, sendOptions);
|
|
1641
|
+
const result = await currentSocketOperations(currentSock).sendMessage(jid, content, sendOptions);
|
|
1661
1642
|
rememberOutboundMessage(jid, result);
|
|
1662
1643
|
return result;
|
|
1663
1644
|
} catch (error) {
|
|
@@ -1681,7 +1662,7 @@ async function createWhatsAppAttachedSocketSession(options) {
|
|
|
1681
1662
|
sendPresenceUpdate: async (presenceLocal, jid) => {
|
|
1682
1663
|
const currentSock = getCurrentSock();
|
|
1683
1664
|
if (!currentSock) throw new Error(RECONNECT_IN_PROGRESS_ERROR);
|
|
1684
|
-
return await
|
|
1665
|
+
return await currentSocketOperations(currentSock).sendPresenceUpdate(presenceLocal, jid);
|
|
1685
1666
|
}
|
|
1686
1667
|
};
|
|
1687
1668
|
const markRead = async (target) => {
|
|
@@ -1921,9 +1902,10 @@ function createWebChannelStatusController(statusSink) {
|
|
|
1921
1902
|
}
|
|
1922
1903
|
emit();
|
|
1923
1904
|
},
|
|
1924
|
-
noteTransportActivity(at
|
|
1925
|
-
if (status.lastTransportActivityAt === at) return;
|
|
1905
|
+
noteTransportActivity(at, authAgeMs) {
|
|
1906
|
+
if (status.lastTransportActivityAt === at && status.authAgeMs === authAgeMs) return;
|
|
1926
1907
|
Object.assign(status, createTransportActivityStatusPatch(at));
|
|
1908
|
+
status.authAgeMs = authAgeMs;
|
|
1927
1909
|
emit();
|
|
1928
1910
|
},
|
|
1929
1911
|
noteBusy(busy, at = Date.now()) {
|
|
@@ -2167,7 +2149,7 @@ function hasWhatsAppAudioBody(msg) {
|
|
|
2167
2149
|
return (msg.payload.media?.kind === "audio" || msg.payload.media?.type?.startsWith("audio/") === true) && !msg.payload.body.trim();
|
|
2168
2150
|
}
|
|
2169
2151
|
async function transcribeWhatsAppAudioMessage(cfg, msg, accountId) {
|
|
2170
|
-
const { transcribeFirstAudio } = await import("./audio-preflight.runtime-
|
|
2152
|
+
const { transcribeFirstAudio } = await import("./audio-preflight.runtime-Dg8oZgre.mjs");
|
|
2171
2153
|
const media = msg.payload.media;
|
|
2172
2154
|
const conversationId = msg.admission.conversation.id;
|
|
2173
2155
|
return await transcribeFirstAudio({
|
|
@@ -2495,10 +2477,10 @@ function resolvePeerId(msg) {
|
|
|
2495
2477
|
const admission = requireWhatsAppInboundAdmission(msg);
|
|
2496
2478
|
if (admission.conversation.kind === "group") return admission.conversation.id;
|
|
2497
2479
|
const sender = getSenderIdentity(msg);
|
|
2498
|
-
if (sender.e164) return
|
|
2480
|
+
if (sender.e164) return sender.e164;
|
|
2499
2481
|
const conversationId = admission.conversation.id;
|
|
2500
2482
|
if (conversationId.includes("@")) return jidToE164(conversationId) ?? conversationId;
|
|
2501
|
-
return normalizeE164(conversationId)
|
|
2483
|
+
return normalizeE164(conversationId);
|
|
2502
2484
|
}
|
|
2503
2485
|
//#endregion
|
|
2504
2486
|
//#region extensions/whatsapp/src/system-prompt.ts
|
|
@@ -2629,24 +2611,17 @@ function resolveWhatsAppReceiptKind(results) {
|
|
|
2629
2611
|
function createWhatsAppReplyDeliveryReceipt(results) {
|
|
2630
2612
|
const receiptResultsById = /* @__PURE__ */ new Map();
|
|
2631
2613
|
for (const result of results) {
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
providerAccepted: result.providerAccepted
|
|
2642
|
-
}
|
|
2643
|
-
});
|
|
2644
|
-
continue;
|
|
2645
|
-
}
|
|
2646
|
-
for (const messageId of listWhatsAppSendResultMessageIds(result)) receiptResultsById.set(messageId, {
|
|
2647
|
-
channel: "whatsapp",
|
|
2648
|
-
messageId,
|
|
2614
|
+
const parts = result.receipt?.parts.length ? result.receipt.parts : listWhatsAppSendResultMessageIds(result).map((platformMessageId) => ({
|
|
2615
|
+
platformMessageId,
|
|
2616
|
+
raw: void 0
|
|
2617
|
+
}));
|
|
2618
|
+
for (const part of parts) receiptResultsById.set(part.platformMessageId, {
|
|
2619
|
+
...part.raw ?? {
|
|
2620
|
+
channel: "whatsapp",
|
|
2621
|
+
messageId: part.platformMessageId
|
|
2622
|
+
},
|
|
2649
2623
|
meta: {
|
|
2624
|
+
...part.raw?.meta,
|
|
2650
2625
|
kind: result.kind,
|
|
2651
2626
|
providerAccepted: result.providerAccepted
|
|
2652
2627
|
}
|
|
@@ -2744,12 +2719,15 @@ async function deliverWebReplyInActivityScope(params) {
|
|
|
2744
2719
|
throw error;
|
|
2745
2720
|
}
|
|
2746
2721
|
};
|
|
2722
|
+
const sendText = async (chunk, label, quote = getQuote) => {
|
|
2723
|
+
rememberSendResult(await sendWithRetry(() => transport.reply(chunk, quote()), label, "text"));
|
|
2724
|
+
};
|
|
2747
2725
|
if (mediaList.length === 0 && textChunks.length) {
|
|
2748
2726
|
const totalChunks = textChunks.length;
|
|
2749
2727
|
for (const [index, chunk] of textChunks.entries()) {
|
|
2750
2728
|
const chunkStarted = Date.now();
|
|
2751
2729
|
const quote = getQuote();
|
|
2752
|
-
|
|
2730
|
+
await sendText(chunk, "text", () => quote);
|
|
2753
2731
|
if (!skipLog) {
|
|
2754
2732
|
const durationMs = Date.now() - chunkStarted;
|
|
2755
2733
|
whatsappOutboundLog.debug(`Sent chunk ${index + 1}/${totalChunks} to ${conversationId} (${durationMs.toFixed(0)}ms)`);
|
|
@@ -2804,7 +2782,7 @@ async function deliverWebReplyInActivityScope(params) {
|
|
|
2804
2782
|
...mediaContent,
|
|
2805
2783
|
mimetype: media.mimetype
|
|
2806
2784
|
}, quote), `media:${media.kind}`, "media", mediaUrl), mediaUrl);
|
|
2807
|
-
if (media.kind === "audio" && caption)
|
|
2785
|
+
if (media.kind === "audio" && caption) await sendText(caption, "media:audio-text", () => quote);
|
|
2808
2786
|
whatsappOutboundLog.info(`Sent media reply to ${conversationId} (${(media.buffer.length / 1048576).toFixed(2)}MB)`);
|
|
2809
2787
|
replyLogger.info({
|
|
2810
2788
|
correlationId: transport.correlationId ?? newConnectionId(),
|
|
@@ -2825,48 +2803,41 @@ async function deliverWebReplyInActivityScope(params) {
|
|
|
2825
2803
|
err: error,
|
|
2826
2804
|
mediaUrl
|
|
2827
2805
|
}, "failed to send web media reply");
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
return;
|
|
2832
|
-
}
|
|
2833
|
-
const fallbackText = [caption ?? "", "⚠️ Media failed."].filter(Boolean).join("\n");
|
|
2834
|
-
whatsappOutboundLog.warn(`Media skipped; sent text-only to ${conversationId}`);
|
|
2835
|
-
rememberSendResult(await sendWithRetry(() => transport.reply(fallbackText, getQuote()), "media:fallback-text", "text"));
|
|
2806
|
+
const fallbackText = isFirst ? [caption ?? "", "⚠️ Media failed."].filter(Boolean).join("\n") : "⚠️ Media unavailable.";
|
|
2807
|
+
whatsappOutboundLog.warn(isFirst ? `Media skipped; sent text-only to ${conversationId}` : `Trailing media failed; sent warning to ${conversationId}`);
|
|
2808
|
+
await sendText(fallbackText, isFirst ? "media:fallback-text" : "media:fallback-unavailable");
|
|
2836
2809
|
}
|
|
2837
2810
|
});
|
|
2838
|
-
for (const chunk of remainingText)
|
|
2811
|
+
for (const chunk of remainingText) await sendText(chunk, "media:text");
|
|
2839
2812
|
return finishDelivery();
|
|
2840
2813
|
}
|
|
2841
2814
|
//#endregion
|
|
2842
2815
|
//#region extensions/whatsapp/src/auto-reply/monitor/inbound-context.ts
|
|
2843
|
-
function
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2816
|
+
function isWhatsAppContextSenderAllowed(params, isGroup, sender) {
|
|
2817
|
+
return resolveInboundSupplementalSenderAllowed({
|
|
2818
|
+
isGroup,
|
|
2819
|
+
groupPolicy: params.groupPolicy,
|
|
2820
|
+
allowFrom: params.groupAllowFrom,
|
|
2821
|
+
isSenderAllowed: (allowFrom) => {
|
|
2822
|
+
if (allowFrom.includes("*")) return true;
|
|
2823
|
+
const senderValues = new Set(getComparableIdentityValues(resolveComparableIdentity(sender, params.authDir)));
|
|
2824
|
+
if (senderValues.size === 0) return false;
|
|
2825
|
+
for (const entry of allowFrom) {
|
|
2826
|
+
const rawEntry = entry.trim();
|
|
2827
|
+
if (!rawEntry) continue;
|
|
2828
|
+
const normalizedEntry = normalizeE164(rawEntry);
|
|
2829
|
+
if (normalizedEntry && senderValues.has(normalizedEntry) || senderValues.has(rawEntry)) return true;
|
|
2830
|
+
}
|
|
2831
|
+
return false;
|
|
2832
|
+
}
|
|
2833
|
+
});
|
|
2854
2834
|
}
|
|
2855
2835
|
function resolveVisibleWhatsAppGroupHistory(params) {
|
|
2856
2836
|
return filterSupplementalContextItems({
|
|
2857
2837
|
items: params.history,
|
|
2858
2838
|
mode: params.mode,
|
|
2859
2839
|
kind: "history",
|
|
2860
|
-
isSenderAllowed: (entry) =>
|
|
2861
|
-
isGroup: true,
|
|
2862
|
-
groupPolicy: params.groupPolicy,
|
|
2863
|
-
allowFrom: params.groupAllowFrom,
|
|
2864
|
-
isSenderAllowed: (allowFrom) => isWhatsAppSupplementalSenderAllowed({
|
|
2865
|
-
allowFrom,
|
|
2866
|
-
authDir: params.authDir,
|
|
2867
|
-
sender: entry.senderJid ? { jid: entry.senderJid } : null
|
|
2868
|
-
})
|
|
2869
|
-
})
|
|
2840
|
+
isSenderAllowed: (entry) => isWhatsAppContextSenderAllowed(params, true, entry.senderJid ? { jid: entry.senderJid } : null)
|
|
2870
2841
|
}).items;
|
|
2871
2842
|
}
|
|
2872
2843
|
function resolveVisibleWhatsAppReplyContext(params) {
|
|
@@ -2874,16 +2845,7 @@ function resolveVisibleWhatsAppReplyContext(params) {
|
|
|
2874
2845
|
if (!replyTo) return null;
|
|
2875
2846
|
const admission = requireWhatsAppInboundAdmission(params.msg);
|
|
2876
2847
|
const previewBody = [replyTo.body, formatMediaPlaceholderText(replyTo.media ? [replyTo.media] : [])].filter(Boolean).join("\n");
|
|
2877
|
-
const senderAllowed =
|
|
2878
|
-
isGroup: admission.conversation.kind === "group",
|
|
2879
|
-
groupPolicy: params.groupPolicy,
|
|
2880
|
-
allowFrom: params.groupAllowFrom,
|
|
2881
|
-
isSenderAllowed: (allowFrom) => isWhatsAppSupplementalSenderAllowed({
|
|
2882
|
-
allowFrom,
|
|
2883
|
-
authDir: params.authDir,
|
|
2884
|
-
sender: replyTo.sender
|
|
2885
|
-
})
|
|
2886
|
-
});
|
|
2848
|
+
const senderAllowed = isWhatsAppContextSenderAllowed(params, admission.conversation.kind === "group", replyTo.sender);
|
|
2887
2849
|
const visible = filterChannelInboundQuoteContext(params.mode, {
|
|
2888
2850
|
id: replyTo.id,
|
|
2889
2851
|
body: previewBody,
|
|
@@ -2896,65 +2858,6 @@ function resolveVisibleWhatsAppReplyContext(params) {
|
|
|
2896
2858
|
} : null;
|
|
2897
2859
|
}
|
|
2898
2860
|
//#endregion
|
|
2899
|
-
//#region extensions/whatsapp/src/auto-reply/monitor/prepared-inbound.ts
|
|
2900
|
-
function resolvePreparedCommandFacts(command) {
|
|
2901
|
-
if (!command) return;
|
|
2902
|
-
const { authorization, ...facts } = command;
|
|
2903
|
-
return {
|
|
2904
|
-
...facts,
|
|
2905
|
-
...authorization.kind === "not_checked" ? {} : { authorized: authorization.kind === "authorized" }
|
|
2906
|
-
};
|
|
2907
|
-
}
|
|
2908
|
-
function projectPreparedChannelInbound(params) {
|
|
2909
|
-
const { inbound, control } = params;
|
|
2910
|
-
const command = resolvePreparedCommandFacts(inbound.command);
|
|
2911
|
-
const commandAuthorization = inbound.command?.authorization;
|
|
2912
|
-
const commandAccess = commandAuthorization && commandAuthorization.kind !== "not_checked" ? { authorized: commandAuthorization.kind === "authorized" } : void 0;
|
|
2913
|
-
return {
|
|
2914
|
-
input: {
|
|
2915
|
-
id: inbound.event.id,
|
|
2916
|
-
timestamp: inbound.event.timestamp,
|
|
2917
|
-
rawText: inbound.message.rawBody,
|
|
2918
|
-
textForAgent: inbound.message.bodyForAgent,
|
|
2919
|
-
textForCommands: inbound.message.commandBody,
|
|
2920
|
-
raw: inbound
|
|
2921
|
-
},
|
|
2922
|
-
context: params.buildContext({
|
|
2923
|
-
...inbound,
|
|
2924
|
-
messageId: inbound.event.id,
|
|
2925
|
-
messageIdFull: inbound.event.fullId,
|
|
2926
|
-
timestamp: inbound.event.timestamp,
|
|
2927
|
-
command,
|
|
2928
|
-
access: inbound.mentions || commandAccess ? {
|
|
2929
|
-
mentions: inbound.mentions,
|
|
2930
|
-
commands: commandAccess
|
|
2931
|
-
} : void 0,
|
|
2932
|
-
extra: {
|
|
2933
|
-
Transcript: inbound.context?.transcript,
|
|
2934
|
-
...inbound.context && "groupSubject" in inbound.context ? { GroupSubject: inbound.context.groupSubject ?? void 0 } : {},
|
|
2935
|
-
GroupMembers: inbound.context?.groupMembers,
|
|
2936
|
-
SenderE164: inbound.context?.senderE164,
|
|
2937
|
-
ReplyThreading: inbound.context?.replyThreading,
|
|
2938
|
-
SuppressMessageReceivedHooks: control.messageReceivedHooks === "channel",
|
|
2939
|
-
...inbound.context?.location ? toLocationContext(inbound.context.location) : {}
|
|
2940
|
-
}
|
|
2941
|
-
})
|
|
2942
|
-
};
|
|
2943
|
-
}
|
|
2944
|
-
/** Keeps WhatsApp reply-policy mapping beside the transport that applies it. */
|
|
2945
|
-
function resolveWhatsAppInboundReplyPolicy(params) {
|
|
2946
|
-
const sourceReplyDeliveryMode = params.ctx.ChatType === "group" || params.ctx.ChatType === "channel" ? resolveChannelMessageSourceReplyDeliveryMode({
|
|
2947
|
-
cfg: params.cfg,
|
|
2948
|
-
ctx: params.ctx
|
|
2949
|
-
}) : void 0;
|
|
2950
|
-
const sourceRepliesAreToolOnly = sourceReplyDeliveryMode === "message_tool_only";
|
|
2951
|
-
return {
|
|
2952
|
-
sourceReplyDeliveryMode,
|
|
2953
|
-
disableBlockStreaming: sourceRepliesAreToolOnly ? true : typeof params.blockStreamingEnabled === "boolean" ? !params.blockStreamingEnabled : void 0,
|
|
2954
|
-
suppressTyping: sourceRepliesAreToolOnly && params.ctx.ChatType === "group" && params.ctx.WasMentioned !== true
|
|
2955
|
-
};
|
|
2956
|
-
}
|
|
2957
|
-
//#endregion
|
|
2958
2861
|
//#region extensions/whatsapp/src/auto-reply/monitor/inbound-dispatch.ts
|
|
2959
2862
|
function normalizeErrForLog(err) {
|
|
2960
2863
|
if (err instanceof Error) return {
|
|
@@ -2965,35 +2868,14 @@ function normalizeErrForLog(err) {
|
|
|
2965
2868
|
};
|
|
2966
2869
|
return err;
|
|
2967
2870
|
}
|
|
2968
|
-
function createWhatsAppChannelDeliveryResult(params) {
|
|
2969
|
-
const messageIds = listMessageReceiptPlatformIds(params.delivery.receipt);
|
|
2970
|
-
return {
|
|
2971
|
-
receipt: params.delivery.receipt,
|
|
2972
|
-
...messageIds.length > 0 ? { messageIds } : {},
|
|
2973
|
-
content: params.content,
|
|
2974
|
-
visibleReplySent: params.delivery.providerAccepted
|
|
2975
|
-
};
|
|
2976
|
-
}
|
|
2977
2871
|
function isWhatsAppVisibleDeliveryError(error) {
|
|
2978
2872
|
return isRecord(error) && error.visibleReplySent === true || isChannelPartialDeliveryError(error) && error.deliveryResult.visibleReplySent;
|
|
2979
2873
|
}
|
|
2980
|
-
function markWhatsAppReplyDeliveryErrorVisibleAfterFlush(error,
|
|
2981
|
-
if (
|
|
2874
|
+
function markWhatsAppReplyDeliveryErrorVisibleAfterFlush(error, delivered) {
|
|
2875
|
+
if (delivered === 0) return error;
|
|
2982
2876
|
if (isWhatsAppVisibleDeliveryError(error)) return error;
|
|
2983
2877
|
return markWhatsAppVisibleDeliveryError(new Error("deferred WhatsApp media delivery failed after an earlier visible send", { cause: error }));
|
|
2984
2878
|
}
|
|
2985
|
-
function logWhatsAppReplyDeliveryError(params) {
|
|
2986
|
-
params.replyLogger.error({
|
|
2987
|
-
err: normalizeErrForLog(params.err),
|
|
2988
|
-
replyKind: params.info.kind,
|
|
2989
|
-
correlationId: params.transport.correlationId ?? null,
|
|
2990
|
-
connectionId: params.connectionId,
|
|
2991
|
-
conversationId: params.transport.conversationId,
|
|
2992
|
-
chatId: params.transport.chatJid,
|
|
2993
|
-
to: params.transport.conversationId,
|
|
2994
|
-
from: params.transport.recipientJid
|
|
2995
|
-
}, "auto-reply delivery failed");
|
|
2996
|
-
}
|
|
2997
2879
|
function resolveWhatsAppDurableReplyToId(params) {
|
|
2998
2880
|
if (params.payload.replyToId === null) return null;
|
|
2999
2881
|
const explicitPayloadReplyToId = normalizeOptionalString(params.payload.replyToId);
|
|
@@ -3025,10 +2907,7 @@ function shouldDeferWhatsAppMediaOnlyPayload(params) {
|
|
|
3025
2907
|
function createWhatsAppMediaOnlyReplyCoalescer(params) {
|
|
3026
2908
|
const pendingMediaOnlyPayloads = [];
|
|
3027
2909
|
const flushWhere = async (shouldFlush) => {
|
|
3028
|
-
|
|
3029
|
-
delivered: 0,
|
|
3030
|
-
droppedDuplicateMedia: 0
|
|
3031
|
-
};
|
|
2910
|
+
let delivered = 0;
|
|
3032
2911
|
const candidates = [];
|
|
3033
2912
|
const retained = [];
|
|
3034
2913
|
for (const pending of pendingMediaOnlyPayloads.splice(0)) if (shouldFlush(pending)) candidates.push(pending);
|
|
@@ -3037,14 +2916,14 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
|
|
|
3037
2916
|
for (const [index, candidate] of candidates.entries()) try {
|
|
3038
2917
|
const delivery = await params.deliver(candidate);
|
|
3039
2918
|
candidate.resolveFinalization(delivery);
|
|
3040
|
-
if (delivery.visibleReplySent)
|
|
2919
|
+
if (delivery.visibleReplySent) delivered += 1;
|
|
3041
2920
|
} catch (error) {
|
|
3042
|
-
const visibleError = markWhatsAppReplyDeliveryErrorVisibleAfterFlush(error,
|
|
2921
|
+
const visibleError = markWhatsAppReplyDeliveryErrorVisibleAfterFlush(error, delivered);
|
|
3043
2922
|
candidate.rejectFinalization(error);
|
|
3044
2923
|
for (const remaining of candidates.slice(index + 1)) remaining.rejectFinalization(new Error("deferred WhatsApp media delivery was not attempted", { cause: error }));
|
|
3045
2924
|
throw visibleError;
|
|
3046
2925
|
}
|
|
3047
|
-
return
|
|
2926
|
+
return delivered;
|
|
3048
2927
|
};
|
|
3049
2928
|
return {
|
|
3050
2929
|
defer(pending) {
|
|
@@ -3058,14 +2937,11 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
|
|
|
3058
2937
|
},
|
|
3059
2938
|
flushNonDuplicateMedia: (mediaUrls) => flushWhere((pending) => !hasWhatsAppMediaUrlOverlap(pending.mediaUrls, mediaUrls)),
|
|
3060
2939
|
supersedeMedia(mediaUrl) {
|
|
3061
|
-
|
|
3062
|
-
delivered: 0,
|
|
3063
|
-
droppedDuplicateMedia: 0
|
|
3064
|
-
};
|
|
2940
|
+
let droppedDuplicateMedia = 0;
|
|
3065
2941
|
const retained = [];
|
|
3066
2942
|
for (const pending of pendingMediaOnlyPayloads.splice(0)) {
|
|
3067
2943
|
if (pending.mediaUrls.delete(mediaUrl)) {
|
|
3068
|
-
|
|
2944
|
+
droppedDuplicateMedia += 1;
|
|
3069
2945
|
const mediaUrls = [...pending.mediaUrls];
|
|
3070
2946
|
pending.payload = {
|
|
3071
2947
|
...pending.payload,
|
|
@@ -3080,15 +2956,15 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
|
|
|
3080
2956
|
retained.push(pending);
|
|
3081
2957
|
}
|
|
3082
2958
|
pendingMediaOnlyPayloads.push(...retained);
|
|
3083
|
-
return
|
|
2959
|
+
return droppedDuplicateMedia;
|
|
3084
2960
|
},
|
|
3085
2961
|
flushAll: () => flushWhere(() => true)
|
|
3086
2962
|
};
|
|
3087
2963
|
}
|
|
3088
|
-
function logWhatsAppMediaOnlyFlushResult(
|
|
2964
|
+
function logWhatsAppMediaOnlyFlushResult(delivered, droppedDuplicateMedia = 0) {
|
|
3089
2965
|
if (!shouldLogVerbose$1()) return;
|
|
3090
|
-
if (
|
|
3091
|
-
if (
|
|
2966
|
+
if (droppedDuplicateMedia > 0) logVerbose$1(`Superseded ${droppedDuplicateMedia} deferred WhatsApp attachment(s) with accepted replacement media`);
|
|
2967
|
+
if (delivered > 0) logVerbose$1(`Flushed ${delivered} deferred media-only WhatsApp reply payload(s)`);
|
|
3092
2968
|
}
|
|
3093
2969
|
function resolveWhatsAppResponsePrefix(params) {
|
|
3094
2970
|
const configuredResponsePrefix = params.cfg.messages?.responsePrefix;
|
|
@@ -3128,7 +3004,12 @@ async function prepareWhatsAppInboundContext(params) {
|
|
|
3128
3004
|
contentType: params.msg.payload.media?.type,
|
|
3129
3005
|
kind: params.msg.payload.media?.kind
|
|
3130
3006
|
}] : void 0, { transcribed: (_entry, index) => params.mediaTranscribedIndexes?.includes(index) === true });
|
|
3131
|
-
const
|
|
3007
|
+
const mentions = wasMentioned !== void 0 ? {
|
|
3008
|
+
canDetectMention: conversationKind === "group",
|
|
3009
|
+
wasMentioned,
|
|
3010
|
+
requireMention: params.msg.groupMention?.requireMention
|
|
3011
|
+
} : void 0;
|
|
3012
|
+
const commands = params.command?.authorized !== void 0 ? { authorized: params.command.authorized } : void 0;
|
|
3132
3013
|
const inbound = {
|
|
3133
3014
|
channelIngress,
|
|
3134
3015
|
channel: "whatsapp",
|
|
@@ -3142,10 +3023,8 @@ async function prepareWhatsAppInboundContext(params) {
|
|
|
3142
3023
|
channelStructuredContext: params.msg.payload.channelStructuredContext
|
|
3143
3024
|
},
|
|
3144
3025
|
media,
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
timestamp: params.msg.event.timestamp
|
|
3148
|
-
},
|
|
3026
|
+
messageId: eventId,
|
|
3027
|
+
timestamp: params.msg.event.timestamp,
|
|
3149
3028
|
from: conversationId,
|
|
3150
3029
|
sender: {
|
|
3151
3030
|
id: params.sender.id ?? params.sender.e164,
|
|
@@ -3176,35 +3055,36 @@ async function prepareWhatsAppInboundContext(params) {
|
|
|
3176
3055
|
commandBody: params.command?.body ?? params.msg.payload.body
|
|
3177
3056
|
},
|
|
3178
3057
|
sessionTranscript: { historyLimit: conversationKind === "group" ? params.groupHistoryLimit ?? params.groupHistory?.length ?? 0 : 0 },
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
requireMention: params.msg.groupMention?.requireMention
|
|
3058
|
+
access: mentions || commands ? {
|
|
3059
|
+
mentions,
|
|
3060
|
+
commands
|
|
3183
3061
|
} : void 0,
|
|
3184
3062
|
command: params.command,
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3063
|
+
extra: {
|
|
3064
|
+
Transcript: params.transcript,
|
|
3065
|
+
GroupSubject: params.msg.group?.subject ?? void 0,
|
|
3066
|
+
GroupMembers: formatGroupMembers({
|
|
3189
3067
|
participants: params.msg.group?.participants,
|
|
3190
3068
|
roster: params.groupMemberRoster,
|
|
3191
3069
|
fallbackE164: params.sender.e164
|
|
3192
3070
|
}),
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3071
|
+
SenderE164: params.sender.e164,
|
|
3072
|
+
ReplyThreading: params.replyThreading,
|
|
3073
|
+
SuppressMessageReceivedHooks: Boolean(params.suppressMessageReceivedHooks),
|
|
3074
|
+
...params.msg.payload.location ? toLocationContext(params.msg.payload.location) : {}
|
|
3196
3075
|
}
|
|
3197
3076
|
};
|
|
3198
|
-
const projected = projectPreparedChannelInbound({
|
|
3199
|
-
inbound,
|
|
3200
|
-
control,
|
|
3201
|
-
buildContext: params.buildContext ?? buildChannelInboundEventContext
|
|
3202
|
-
});
|
|
3203
3077
|
return {
|
|
3204
3078
|
inbound,
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3079
|
+
turnInput: {
|
|
3080
|
+
id: eventId,
|
|
3081
|
+
timestamp: inbound.timestamp,
|
|
3082
|
+
rawText: inbound.message.rawBody,
|
|
3083
|
+
textForAgent: inbound.message.bodyForAgent,
|
|
3084
|
+
textForCommands: inbound.message.commandBody,
|
|
3085
|
+
raw: inbound
|
|
3086
|
+
},
|
|
3087
|
+
ctxPayload: (params.buildContext ?? buildChannelInboundEventContext)(inbound)
|
|
3208
3088
|
};
|
|
3209
3089
|
}
|
|
3210
3090
|
function resolveWhatsAppDmRouteTarget(params) {
|
|
@@ -3221,7 +3101,8 @@ function updateWhatsAppMainLastRoute(params) {
|
|
|
3221
3101
|
route: params.route,
|
|
3222
3102
|
sessionKey: params.route.sessionKey
|
|
3223
3103
|
});
|
|
3224
|
-
if (params.dmRouteTarget
|
|
3104
|
+
if (!params.dmRouteTarget || inboundLastRouteSessionKey !== params.route.mainSessionKey) return;
|
|
3105
|
+
if (shouldUpdateMainLastRoute) {
|
|
3225
3106
|
params.updateLastRoute({
|
|
3226
3107
|
cfg: params.cfg,
|
|
3227
3108
|
backgroundTasks: params.backgroundTasks,
|
|
@@ -3235,12 +3116,12 @@ function updateWhatsAppMainLastRoute(params) {
|
|
|
3235
3116
|
});
|
|
3236
3117
|
return;
|
|
3237
3118
|
}
|
|
3238
|
-
if (params.
|
|
3119
|
+
if (params.pinnedMainDmRecipient) logVerbose$1(`Skipping main-session last route update for ${params.dmRouteTarget} (pinned owner ${params.pinnedMainDmRecipient})`);
|
|
3239
3120
|
}
|
|
3240
3121
|
function createWhatsAppReplyPlan(params) {
|
|
3241
|
-
const conversationId = params.
|
|
3122
|
+
const conversationId = params.conversationId;
|
|
3242
3123
|
const statusReactionController = params.statusReactionController ?? null;
|
|
3243
|
-
const textLimit =
|
|
3124
|
+
const textLimit = resolveTextChunkLimit(params.cfg, "whatsapp");
|
|
3244
3125
|
const chunkMode = resolveChunkMode(params.cfg, "whatsapp", params.route.accountId);
|
|
3245
3126
|
const tableMode = resolveMarkdownTableMode$1({
|
|
3246
3127
|
cfg: params.cfg,
|
|
@@ -3248,11 +3129,12 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3248
3129
|
accountId: params.route.accountId
|
|
3249
3130
|
});
|
|
3250
3131
|
const mediaLocalRoots = getAgentScopedMediaLocalRoots(params.cfg, params.route.agentId);
|
|
3251
|
-
const
|
|
3132
|
+
const sourceReplyDeliveryMode = params.context.ChatType === "group" || params.context.ChatType === "channel" ? resolveChannelMessageSourceReplyDeliveryMode({
|
|
3252
3133
|
cfg: params.cfg,
|
|
3253
|
-
ctx: params.context
|
|
3254
|
-
|
|
3255
|
-
|
|
3134
|
+
ctx: params.context
|
|
3135
|
+
}) : void 0;
|
|
3136
|
+
const sourceRepliesAreToolOnly = sourceReplyDeliveryMode === "message_tool_only";
|
|
3137
|
+
const blockStreamingEnabled = resolveChannelStreamingBlockEnabled(params.cfg.channels?.whatsapp);
|
|
3256
3138
|
let didSendReply = false;
|
|
3257
3139
|
let didLogHeartbeatStrip = false;
|
|
3258
3140
|
const recordDeliveredPayload = (payload) => {
|
|
@@ -3289,10 +3171,13 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3289
3171
|
});
|
|
3290
3172
|
throw error;
|
|
3291
3173
|
}
|
|
3292
|
-
const
|
|
3174
|
+
const messageIds = listMessageReceiptPlatformIds(delivery.receipt);
|
|
3175
|
+
const result = {
|
|
3176
|
+
receipt: delivery.receipt,
|
|
3177
|
+
...messageIds.length > 0 ? { messageIds } : {},
|
|
3293
3178
|
content: reply.text,
|
|
3294
|
-
delivery
|
|
3295
|
-
}
|
|
3179
|
+
visibleReplySent: delivery.providerAccepted
|
|
3180
|
+
};
|
|
3296
3181
|
if (!result.visibleReplySent) {
|
|
3297
3182
|
params.replyLogger.warn({
|
|
3298
3183
|
correlationId: params.transport.correlationId ?? null,
|
|
@@ -3324,9 +3209,9 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3324
3209
|
}
|
|
3325
3210
|
},
|
|
3326
3211
|
onSettled: async () => {
|
|
3327
|
-
const
|
|
3328
|
-
logWhatsAppMediaOnlyFlushResult(
|
|
3329
|
-
return { visibleReplySent: didSendReply ||
|
|
3212
|
+
const delivered = await mediaOnlyCoalescer.flushAll();
|
|
3213
|
+
logWhatsAppMediaOnlyFlushResult(delivered);
|
|
3214
|
+
return { visibleReplySent: didSendReply || delivered > 0 };
|
|
3330
3215
|
},
|
|
3331
3216
|
onReplyStart: params.transport.sendComposing
|
|
3332
3217
|
},
|
|
@@ -3347,10 +3232,7 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3347
3232
|
info,
|
|
3348
3233
|
mediaUrls,
|
|
3349
3234
|
reply
|
|
3350
|
-
}) ?
|
|
3351
|
-
delivered: 0,
|
|
3352
|
-
droppedDuplicateMedia: 0
|
|
3353
|
-
} : await mediaOnlyCoalescer.flushNonDuplicateMedia(mediaUrls) : await mediaOnlyCoalescer.flushAll());
|
|
3235
|
+
}) ? 0 : await mediaOnlyCoalescer.flushNonDuplicateMedia(mediaUrls) : await mediaOnlyCoalescer.flushAll());
|
|
3354
3236
|
return normalizedDeliveryPayload;
|
|
3355
3237
|
},
|
|
3356
3238
|
durable: (payload, info) => {
|
|
@@ -3391,7 +3273,7 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3391
3273
|
};
|
|
3392
3274
|
return await deliverNormalizedPayload(normalizedDeliveryPayload, info, { onMediaAccepted: (mediaUrl) => {
|
|
3393
3275
|
didSendReply = true;
|
|
3394
|
-
logWhatsAppMediaOnlyFlushResult(mediaOnlyCoalescer.supersedeMedia(mediaUrl));
|
|
3276
|
+
logWhatsAppMediaOnlyFlushResult(0, mediaOnlyCoalescer.supersedeMedia(mediaUrl));
|
|
3395
3277
|
} });
|
|
3396
3278
|
},
|
|
3397
3279
|
onDelivered: (payload, _info, result) => {
|
|
@@ -3399,20 +3281,23 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3399
3281
|
},
|
|
3400
3282
|
onError: (err, info) => {
|
|
3401
3283
|
if (didSendReply) markWhatsAppVisibleDeliveryError(err);
|
|
3402
|
-
|
|
3403
|
-
err,
|
|
3404
|
-
info,
|
|
3284
|
+
params.replyLogger.error({
|
|
3285
|
+
err: normalizeErrForLog(err),
|
|
3286
|
+
replyKind: info.kind,
|
|
3287
|
+
correlationId: params.transport.correlationId ?? null,
|
|
3405
3288
|
connectionId: params.connectionId,
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3289
|
+
conversationId: params.transport.conversationId,
|
|
3290
|
+
chatId: params.transport.chatJid,
|
|
3291
|
+
to: params.transport.conversationId,
|
|
3292
|
+
from: params.transport.recipientJid
|
|
3293
|
+
}, "auto-reply delivery failed");
|
|
3409
3294
|
}
|
|
3410
3295
|
},
|
|
3411
3296
|
replyOptions: {
|
|
3412
3297
|
...params.turnAdoptionLifecycle ? { turnAdoptionLifecycle: params.turnAdoptionLifecycle } : {},
|
|
3413
|
-
suppressTyping:
|
|
3414
|
-
disableBlockStreaming:
|
|
3415
|
-
...
|
|
3298
|
+
suppressTyping: sourceRepliesAreToolOnly && params.context.ChatType === "group" && params.context.WasMentioned !== true,
|
|
3299
|
+
disableBlockStreaming: sourceRepliesAreToolOnly ? true : typeof blockStreamingEnabled === "boolean" ? !blockStreamingEnabled : void 0,
|
|
3300
|
+
...sourceReplyDeliveryMode ? { sourceReplyDeliveryMode } : {},
|
|
3416
3301
|
onModelSelected: params.onModelSelected,
|
|
3417
3302
|
...statusReactionController ? {
|
|
3418
3303
|
onToolStart: async (payload) => {
|
|
@@ -3482,7 +3367,6 @@ function buildInboundLine(params) {
|
|
|
3482
3367
|
//#endregion
|
|
3483
3368
|
//#region extensions/whatsapp/src/auto-reply/monitor/status-reaction.ts
|
|
3484
3369
|
async function createWhatsAppStatusReactionController(params) {
|
|
3485
|
-
if (!params.msg.event.id) return null;
|
|
3486
3370
|
if ((params.cfg.messages?.statusReactions)?.enabled !== true) return null;
|
|
3487
3371
|
const eligibility = await resolveWhatsAppReactionEligibility(params);
|
|
3488
3372
|
if (eligibility.status === "disabled") return null;
|
|
@@ -3490,12 +3374,8 @@ async function createWhatsAppStatusReactionController(params) {
|
|
|
3490
3374
|
return createStatusReactionController({
|
|
3491
3375
|
enabled: true,
|
|
3492
3376
|
adapter: {
|
|
3493
|
-
setReaction:
|
|
3494
|
-
|
|
3495
|
-
},
|
|
3496
|
-
clearReaction: async () => {
|
|
3497
|
-
await sendReactionWhatsApp(chatId, messageId, "", reactionOptions);
|
|
3498
|
-
}
|
|
3377
|
+
setReaction: (emoji) => sendReactionWhatsApp(chatId, messageId, emoji, reactionOptions),
|
|
3378
|
+
clearReaction: () => sendReactionWhatsApp(chatId, messageId, "", reactionOptions)
|
|
3499
3379
|
},
|
|
3500
3380
|
initialEmoji,
|
|
3501
3381
|
emojis: void 0,
|
|
@@ -3559,7 +3439,7 @@ async function processMessage(params) {
|
|
|
3559
3439
|
channel: "whatsapp",
|
|
3560
3440
|
accountId: account.accountId
|
|
3561
3441
|
});
|
|
3562
|
-
const { storePath, envelopeOptions, previousTimestamp } =
|
|
3442
|
+
const { storePath, envelopeOptions, previousTimestamp } = await resolveInboundSessionEnvelopeContextAsync({
|
|
3563
3443
|
cfg: params.cfg,
|
|
3564
3444
|
agentId: params.route.agentId,
|
|
3565
3445
|
sessionKey: params.route.sessionKey
|
|
@@ -3681,14 +3561,13 @@ async function processMessage(params) {
|
|
|
3681
3561
|
accountConfig: account,
|
|
3682
3562
|
peerId: dmRouteTarget ?? conversationId
|
|
3683
3563
|
});
|
|
3684
|
-
const commandAuthorization = commandAuthorized === void 0 ? { kind: "not_checked" } : commandAuthorized ? { kind: "authorized" } : { kind: "denied" };
|
|
3685
3564
|
const { inbound, turnInput, ctxPayload } = await prepareWhatsAppInboundContext({
|
|
3686
3565
|
bodyForAgent: msgForAgent.payload.body,
|
|
3687
3566
|
combinedBody,
|
|
3688
3567
|
command: {
|
|
3689
3568
|
kind: isTextCommand ? "text-slash" : "normal",
|
|
3690
3569
|
body: commandBody,
|
|
3691
|
-
|
|
3570
|
+
...commandAuthorized !== void 0 ? { authorized: commandAuthorized } : {}
|
|
3692
3571
|
},
|
|
3693
3572
|
groupHistory: visibleGroupHistory,
|
|
3694
3573
|
groupHistoryLimit: params.groupHistoryLimit,
|
|
@@ -3754,8 +3633,7 @@ async function processMessage(params) {
|
|
|
3754
3633
|
context: ctxPayload,
|
|
3755
3634
|
deliverReply: deliverWebReply,
|
|
3756
3635
|
maxMediaBytes: params.maxMediaBytes,
|
|
3757
|
-
|
|
3758
|
-
inbound,
|
|
3636
|
+
conversationId,
|
|
3759
3637
|
onModelSelected,
|
|
3760
3638
|
replyLogger: params.replyLogger,
|
|
3761
3639
|
replyPipeline: {
|
|
@@ -4034,7 +3912,6 @@ function createWebOnMessageHandler(params) {
|
|
|
4034
3912
|
function isNonRetryableWebCloseStatus(statusCode) {
|
|
4035
3913
|
return statusCode === 440;
|
|
4036
3914
|
}
|
|
4037
|
-
const loadReplyResolverRuntime = createLazyRuntimeModule(() => import("./reply-resolver.runtime-Ded8D58Y.mjs"));
|
|
4038
3915
|
function resolveWebMonitorConfigSnapshot(params) {
|
|
4039
3916
|
const account = resolveWhatsAppAccount({
|
|
4040
3917
|
cfg: params.cfg,
|
|
@@ -4073,7 +3950,7 @@ function isRetryableAuthUnstableError(error) {
|
|
|
4073
3950
|
const DEFAULT_TRANSPORT_TIMEOUT_MS = 3e5;
|
|
4074
3951
|
const WHATSAPP_RECONNECT_CATCH_UP_MAX_MS = 12e5;
|
|
4075
3952
|
async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSocket, keepAlive = true, replyResolver, runtime = defaultRuntime, abortSignal, tuning = {}) {
|
|
4076
|
-
const activeReplyResolver = replyResolver ?? (await
|
|
3953
|
+
const activeReplyResolver = replyResolver ?? (await import("./reply-resolver.runtime-Ded8D58Y.mjs")).getReplyFromConfig;
|
|
4077
3954
|
const runId = newConnectionId();
|
|
4078
3955
|
const replyLogger = getChildLogger$1({
|
|
4079
3956
|
module: "web-auto-reply",
|
|
@@ -4220,7 +4097,7 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
|
|
|
4220
4097
|
uptimeMs: snapshot.uptimeMs,
|
|
4221
4098
|
...minutesSinceLastMessage !== null && minutesSinceLastMessage > 30 ? { minutesSinceLastMessage } : {}
|
|
4222
4099
|
};
|
|
4223
|
-
statusController.noteTransportActivity(snapshot.lastTransportActivityAt);
|
|
4100
|
+
statusController.noteTransportActivity(snapshot.lastTransportActivityAt, authAgeMs);
|
|
4224
4101
|
if (minutesSinceLastMessage && minutesSinceLastMessage > 30) heartbeatLogger.warn(logData, "⚠️ web gateway heartbeat - no messages in 30+ minutes");
|
|
4225
4102
|
else heartbeatLogger.info(logData, "web gateway heartbeat");
|
|
4226
4103
|
},
|
|
@@ -4250,67 +4127,41 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
|
|
|
4250
4127
|
await controller.shutdown();
|
|
4251
4128
|
break;
|
|
4252
4129
|
}
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
reconnectAttempts: setupDecision.reconnectAttempts,
|
|
4259
|
-
healthState: setupDecision.healthState
|
|
4260
|
-
});
|
|
4261
|
-
if (setupDecision.action === "stop") {
|
|
4262
|
-
reconnectLogger.warn({
|
|
4263
|
-
connectionId,
|
|
4264
|
-
status: setupDecision.normalized.statusLabel,
|
|
4265
|
-
reconnectAttempts: setupDecision.reconnectAttempts,
|
|
4266
|
-
maxAttempts: reconnectPolicy.maxAttempts
|
|
4267
|
-
}, "web reconnect: setup status error; max attempts reached");
|
|
4268
|
-
if (setupDecision.healthState === "logged-out") runtime.error(`WhatsApp session logged out during setup. Run \`${formatCliCommand("openclaw channels login --channel whatsapp")}\` to relink.`);
|
|
4269
|
-
else if (setupDecision.healthState === "conflict") runtime.error(`WhatsApp Web connection closed during setup (status ${setupDecision.normalized.statusLabel}: session conflict). Resolve conflicting WhatsApp Web sessions, then restart the channel. To force a fresh QR, run \`${formatCliCommand("openclaw channels logout --channel whatsapp")}\` before \`${formatCliCommand("openclaw channels login --channel whatsapp")}\`. Stopping web monitoring.`);
|
|
4270
|
-
else runtime.error(`WhatsApp Web connection closed during setup (status ${setupDecision.normalized.statusLabel}) after ${setupDecision.reconnectAttempts}/${reconnectPolicy.maxAttempts} attempts. Relink with \`${formatCliCommand("openclaw channels login --channel whatsapp")}\` if the issue persists.`);
|
|
4271
|
-
await controller.shutdown();
|
|
4272
|
-
break;
|
|
4273
|
-
}
|
|
4274
|
-
reconnectLogger.info({
|
|
4275
|
-
connectionId,
|
|
4276
|
-
status: setupDecision.normalized.statusLabel,
|
|
4277
|
-
reconnectAttempts: setupDecision.reconnectAttempts,
|
|
4278
|
-
delayMs: setupDecision.delayMs
|
|
4279
|
-
}, "web reconnect: setup status error; retrying");
|
|
4280
|
-
runtime.error(`WhatsApp Web connection closed during setup (status ${setupDecision.normalized.statusLabel}). Retry ${setupDecision.reconnectAttempts}/${reconnectPolicy.maxAttempts || "∞"} in ${formatDurationPrecise(setupDecision.delayMs ?? 0)}.`);
|
|
4281
|
-
try {
|
|
4282
|
-
await controller.waitBeforeRetry(setupDecision.delayMs ?? 0);
|
|
4283
|
-
} catch {
|
|
4284
|
-
break;
|
|
4285
|
-
}
|
|
4286
|
-
continue;
|
|
4287
|
-
}
|
|
4288
|
-
if (!isRetryableAuthUnstableError(error)) throw error;
|
|
4289
|
-
const retryDecision = controller.consumeReconnectAttempt();
|
|
4290
|
-
statusController.noteReconnectAttempts(retryDecision.reconnectAttempts);
|
|
4130
|
+
const authError = !setupDecision && isRetryableAuthUnstableError(error) ? error : void 0;
|
|
4131
|
+
if (!setupDecision && !authError) throw error;
|
|
4132
|
+
const decision = setupDecision ?? controller.consumeReconnectAttempt();
|
|
4133
|
+
const normalized = setupDecision?.normalized;
|
|
4134
|
+
statusController.noteReconnectAttempts(decision.reconnectAttempts);
|
|
4291
4135
|
statusController.noteClose({
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4136
|
+
...normalized ? { statusCode: normalized.statusCode } : {},
|
|
4137
|
+
error: setupDecision ? formatError(error) : authError?.message,
|
|
4138
|
+
reconnectAttempts: decision.reconnectAttempts,
|
|
4139
|
+
healthState: decision.healthState
|
|
4295
4140
|
});
|
|
4296
|
-
|
|
4141
|
+
const logData = {
|
|
4142
|
+
connectionId,
|
|
4143
|
+
...normalized ? { status: normalized.statusLabel } : {},
|
|
4144
|
+
reconnectAttempts: decision.reconnectAttempts
|
|
4145
|
+
};
|
|
4146
|
+
if (decision.action === "stop") {
|
|
4297
4147
|
reconnectLogger.warn({
|
|
4298
|
-
|
|
4299
|
-
reconnectAttempts: retryDecision.reconnectAttempts,
|
|
4148
|
+
...logData,
|
|
4300
4149
|
maxAttempts: reconnectPolicy.maxAttempts
|
|
4301
|
-
}, "web reconnect: auth state stayed unstable; max attempts reached");
|
|
4302
|
-
runtime.error(`WhatsApp auth state is still stabilizing after ${
|
|
4150
|
+
}, normalized ? "web reconnect: setup status error; max attempts reached" : "web reconnect: auth state stayed unstable; max attempts reached");
|
|
4151
|
+
if (!normalized) runtime.error(`WhatsApp auth state is still stabilizing after ${decision.reconnectAttempts}/${reconnectPolicy.maxAttempts} attempts. Stopping web monitoring.`);
|
|
4152
|
+
else if (decision.healthState === "logged-out") runtime.error(`WhatsApp session logged out during setup. Run \`${formatCliCommand("openclaw channels login --channel whatsapp")}\` to relink.`);
|
|
4153
|
+
else if (decision.healthState === "conflict") runtime.error(`WhatsApp Web connection closed during setup (status ${normalized.statusLabel}: session conflict). Resolve conflicting WhatsApp Web sessions, then restart the channel. To force a fresh QR, run \`${formatCliCommand("openclaw channels logout --channel whatsapp")}\` before \`${formatCliCommand("openclaw channels login --channel whatsapp")}\`. Stopping web monitoring.`);
|
|
4154
|
+
else runtime.error(`WhatsApp Web connection closed during setup (status ${normalized.statusLabel}) after ${decision.reconnectAttempts}/${reconnectPolicy.maxAttempts} attempts. Relink with \`${formatCliCommand("openclaw channels login --channel whatsapp")}\` if the issue persists.`);
|
|
4303
4155
|
await controller.shutdown();
|
|
4304
4156
|
break;
|
|
4305
4157
|
}
|
|
4306
4158
|
reconnectLogger.info({
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
}
|
|
4311
|
-
runtime.error(`WhatsApp auth state is still stabilizing. Retry ${retryDecision.reconnectAttempts}/${reconnectPolicy.maxAttempts || "∞"} for inbox attach in ${formatDurationPrecise(retryDecision.delayMs ?? 0)}.`);
|
|
4159
|
+
...logData,
|
|
4160
|
+
delayMs: decision.delayMs
|
|
4161
|
+
}, normalized ? "web reconnect: setup status error; retrying" : "web reconnect: auth state still stabilizing during inbox attach; retrying");
|
|
4162
|
+
runtime.error(normalized ? `WhatsApp Web connection closed during setup (status ${normalized.statusLabel}). Retry ${decision.reconnectAttempts}/${reconnectPolicy.maxAttempts || "∞"} in ${formatDurationPrecise(decision.delayMs ?? 0)}.` : `WhatsApp auth state is still stabilizing. Retry ${decision.reconnectAttempts}/${reconnectPolicy.maxAttempts || "∞"} for inbox attach in ${formatDurationPrecise(decision.delayMs ?? 0)}.`);
|
|
4312
4163
|
try {
|
|
4313
|
-
await controller.waitBeforeRetry(
|
|
4164
|
+
await controller.waitBeforeRetry(decision.delayMs ?? 0);
|
|
4314
4165
|
} catch {
|
|
4315
4166
|
break;
|
|
4316
4167
|
}
|