@openclaw/whatsapp 2026.9.5 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{accounts-D_NGDjCx.mjs → accounts-CtRPAQCL.mjs} +3 -9
- package/dist/.setup/{action-runtime-DZZFamfl.mjs → action-runtime-DeVk5V7r.mjs} +2 -2
- package/dist/.setup/{agent-tools-login-B6MAs75N.mjs → agent-tools-login-CL5C1rA2.mjs} +5 -1
- package/dist/.setup/{approval-handler.runtime-C0hzmMSj.mjs → approval-handler.runtime-CjqMlPOX.mjs} +6 -26
- package/dist/.setup/{approval-reactions-BnXw-UZI.mjs → approval-reactions-DiOFvb1s.mjs} +8 -14
- package/dist/.setup/{auth-store-Dh8a3cba.mjs → auth-store-BBonwKks.mjs} +9 -33
- package/dist/.setup/{channel-CSclZYjU.mjs → channel-CJFE0kD_.mjs} +82 -154
- package/dist/.setup/{channel-react-action-1iBiEnq7.mjs → channel-react-action-2r_hjLZV.mjs} +4 -8
- package/dist/.setup/{channel.runtime-ddGY37w8.mjs → channel.runtime-C94goLw9.mjs} +4 -4
- package/dist/.setup/{channel.setup-CqUl8COe.mjs → channel.setup-CfN1UfdY.mjs} +1 -1
- package/dist/.setup/{connection-controller-C60mU7j7.mjs → connection-controller-CHo1oRJA.mjs} +13 -63
- package/dist/.setup/{creds-files-Drg3usj1.mjs → creds-files-CDATZWWM.mjs} +5 -11
- package/dist/.setup/{directory-config-BHPoBklt.mjs → directory-config-DUiJ5d8I.mjs} +13 -14
- package/dist/.setup/doctor-iMwg0Vhr.mjs +222 -0
- package/dist/.setup/group-config-path-DZr3ucUO.mjs +40 -0
- package/dist/.setup/{group-session-key-D22hYMdE.mjs → group-session-key-2-mja4OF.mjs} +3 -9
- package/dist/.setup/{login-2dmd1TfE.mjs → login-BFlvSh9h.mjs} +9 -11
- package/dist/.setup/{login-qr-CgKtO_ef.mjs → login-qr-Ayb8i25J.mjs} +29 -77
- package/dist/.setup/{monitor-BblvzLpX.mjs → monitor-CGpV2VNN.mjs} +391 -509
- package/dist/.setup/{question-reactions-D3Zq9Gbn.mjs → question-reactions-CPyyi5AY.mjs} +2 -2
- package/dist/.setup/rolldown-runtime-BBjsoOtd.mjs +27 -0
- package/dist/.setup/{send-C6jDmcL9.mjs → send-BGdvf5cC.mjs} +31 -80
- package/dist/.setup/{send-api-B4DOt2RJ.mjs → send-api-H4AkQJjT.mjs} +45 -109
- package/dist/.setup/{session-errors-JuazczrA.mjs → session-errors-B8UcAnZN.mjs} +1 -4
- package/dist/.setup/{session.runtime-DcJuO42v.mjs → session.runtime-st1konFI.mjs} +1 -1
- package/dist/.setup/{setup-finalize-BYEgU0hb.mjs → setup-finalize-DmPX4EaW.mjs} +32 -70
- package/dist/.setup/setup-plugin-api-vJlxKzca.mjs +3 -0
- package/dist/.setup/{setup-surface-Cd3wN5HD.mjs → setup-surface-43fj197P.mjs} +3 -3
- package/dist/.setup/{shared-C9OEtKgc.mjs → shared-DgOG5Iqr.mjs} +26 -37
- package/dist/.setup/{socket-close-CCVSFufF.mjs → socket-close-CT__V2fz.mjs} +80 -92
- package/dist/.setup/{targets-runtime-RBjx3pg_.mjs → targets-runtime-DmiqXIXO.mjs} +2 -7
- package/dist/action-runtime-api.js +1 -1
- package/dist/action-runtime.runtime.js +1 -1
- package/dist/agent-tools-api.js +6 -13
- package/dist/api.js +10 -10
- package/dist/auth-presence.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/contract-api.js +2 -2
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +9 -10
- package/dist/light-runtime-api.js +3 -3
- package/dist/login-qr-runtime.js +1 -1
- package/dist/runtime-api.js +10 -10
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/node_modules/audio-decode/LICENSE +9 -10
- package/node_modules/audio-decode/README.md +16 -0
- package/node_modules/audio-decode/audio-decode.d.ts +2 -14
- package/node_modules/audio-decode/audio-decode.js +4 -92
- package/node_modules/audio-decode/meta.js +1 -0
- package/node_modules/audio-decode/node_modules/{audio-buffer → @audio/decode}/LICENSE +1 -1
- package/node_modules/audio-decode/node_modules/@audio/decode/audio-decode.d.ts +52 -0
- package/node_modules/audio-decode/node_modules/@audio/decode/audio-decode.js +242 -0
- package/node_modules/audio-decode/node_modules/@audio/decode/meta.js +14 -0
- package/node_modules/audio-decode/node_modules/@audio/decode/package.json +114 -0
- package/node_modules/audio-decode/node_modules/@audio/decode/readme.md +191 -0
- package/node_modules/audio-decode/node_modules/@audio/decode/stream.d.ts +12 -0
- package/node_modules/audio-decode/node_modules/@audio/decode/stream.js +1 -0
- package/node_modules/audio-decode/node_modules/@audio/decode/test.html +52 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/LICENSE +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/README.md +80 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/alac.js +326 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/decode-aac.d.ts +24 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/decode-aac.js +452 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/meta.js +81 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/package.json +63 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aac/src/aac.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/LICENSE +12 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/LICENSE.liba52 +340 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/README.md +41 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/audio.js +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/decode-ac3.d.ts +20 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/decode-ac3.js +131 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/package.json +64 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-ac3/src/ac3.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aiff/LICENSE +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aiff/README.md +46 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aiff/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aiff/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aiff/decode-aiff.d.ts +16 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aiff/decode-aiff.js +583 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-aiff/package.json +52 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-amr/LICENSE +191 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-amr/README.md +65 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-amr/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-amr/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-amr/decode-amr.d.ts +16 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-amr/decode-amr.js +150 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-amr/package.json +58 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-amr/src/amr.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-avi/LICENSE +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-avi/README.md +53 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-avi/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-avi/audio.js +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-avi/decode-avi.d.ts +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-avi/decode-avi.js +241 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-avi/package.json +66 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/LICENSE +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/README.md +48 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/decode-caf.d.ts +16 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/decode-caf.js +238 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-caf/package.json +53 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dsd/LICENSE +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dsd/README.md +73 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dsd/audio.d.ts +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dsd/audio.js +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dsd/decode-dsd.d.ts +29 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dsd/decode-dsd.js +423 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dsd/meta.js +40 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dsd/package.json +64 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/LICENSE +12 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/LICENSE.libdca +339 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/README.md +41 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/audio.js +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/decode-dts.d.ts +20 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/decode-dts.js +139 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/package.json +64 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-dts/src/dts.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/LICENSE +12 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/LICENSE.ffmpeg +502 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/README.md +45 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/audio.js +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/decode-eac3.d.ts +20 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/decode-eac3.js +124 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/package.json +68 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-eac3/src/eac3.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/LICENSE +25 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/README.md +23 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/decode-flac.d.ts +18 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/decode-flac.js +3172 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/meta.js +115 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-flac/package.json +60 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/LICENSE +23 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/LICENSE.libopenmpt +25 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/README.md +86 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/audio.d.ts +20 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/audio.js +12 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/decode-mod.d.ts +58 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/decode-mod.js +148 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/package.json +68 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mod/src/mod.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp3/LICENSE +25 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp3/README.md +20 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp3/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp3/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp3/decode-mp3.d.ts +16 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp3/decode-mp3.js +793 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp3/meta.js +143 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp3/package.json +60 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/LICENSE +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/README.md +58 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/audio.js +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/decode-mp4.d.ts +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/decode-mp4.js +455 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mp4/package.json +74 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/LICENSE +31 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/LICENSE.libmpcdec +31 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/README.md +60 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/audio.js +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/decode-mpc.d.ts +20 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/decode-mpc.js +158 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/package.json +64 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-mpc/src/mpc.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/LICENSE +25 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/LICENSE.libopus +44 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/README.md +32 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/core.d.ts +33 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/core.js +147 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/decode-opus.d.ts +18 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/decode-opus.js +1 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/meta.js +103 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/package.json +68 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/src/decode-opus.js +2 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-opus/src/opus.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/LICENSE +25 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/README.md +19 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/decode-qoa.d.ts +16 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/decode-qoa.js +275 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-qoa/package.json +56 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-tta/LICENSE +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-tta/LICENSE.ttadec +39 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-tta/README.md +58 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-tta/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-tta/audio.js +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-tta/decode-tta.d.ts +17 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-tta/decode-tta.js +302 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-tta/package.json +58 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/LICENSE +25 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/README.md +33 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/decode-vorbis.d.ts +18 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/decode-vorbis.js +2984 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/meta.js +102 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/package.json +60 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/LICENSE +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/README.md +23 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/decode-wav.d.ts +8 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/decode-wav.js +256 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/meta.js +114 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wav/package.json +52 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/LICENSE +29 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/LICENSE.wavpack +25 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/README.md +41 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/audio.js +9 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/decode-wavpack.d.ts +18 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/decode-wavpack.js +140 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/package.json +62 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/src/wavpack.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/LICENSE +21 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/LICENSE.libopus +44 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/README.md +59 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/decode-webm.d.ts +18 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/decode-webm.js +141 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/package.json +76 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-webm/src/opus.wasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/LICENSE +12 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/README.md +74 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/audio.d.ts +15 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/audio.js +10 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/decode-wma.d.ts +33 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/decode-wma.js +516 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/package.json +57 -0
- package/node_modules/audio-decode/node_modules/@audio/decode-wma/src/wma.wasm.js +0 -0
- package/node_modules/audio-decode/package.json +37 -39
- package/node_modules/audio-decode/stream.d.ts +2 -0
- package/node_modules/audio-decode/stream.js +2 -0
- package/node_modules/baileys/lib/Utils/messages-media.js +1 -1
- package/node_modules/baileys/node_modules/file-type/package.json +3 -2
- package/node_modules/baileys/node_modules/file-type/readme.md +5 -0
- package/node_modules/baileys/node_modules/file-type/source/detectors/zip.js +9 -4
- package/node_modules/baileys/node_modules/file-type/source/index.js +28 -1
- package/node_modules/baileys/node_modules/file-type/source/supported.js +2 -0
- package/node_modules/baileys/node_modules/p-timeout/index.js +3 -0
- package/node_modules/baileys/node_modules/p-timeout/package.json +1 -1
- package/node_modules/baileys/package.json +1 -1
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/package.json +6 -6
- package/dist/.setup/doctor-BPb-SjdE.mjs +0 -65
- package/dist/.setup/group-config-path-BGyzT9Lg.mjs +0 -54
- package/dist/.setup/normalize-DdsROMMa.mjs +0 -2
- package/dist/.setup/rolldown-runtime-D7D4PA-g.mjs +0 -13
- package/dist/.setup/runtime-group-policy-DeSRFXEV.mjs +0 -11
- package/dist/.setup/setup-plugin-api-CXfU-7vN.mjs +0 -3
- package/dist/.setup/text-runtime-CHl0iPYe.mjs +0 -4
- package/node_modules/audio-decode/.eslintrc.json +0 -43
- package/node_modules/audio-decode/.github/workflows/test.js.yml +0 -31
- package/node_modules/audio-decode/.travis.yml +0 -13
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/README.md +0 -293
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/dist/opus-ml-decoder.min.js +0 -11646
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/dist/opus-ml-decoder.min.js.map +0 -1
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/index.js +0 -8
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/package.json +0 -58
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/EmscriptenWasm.js +0 -0
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/OpusMLDecoder.js +0 -253
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/OpusMLDecoderWebWorker.js +0 -17
- package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/types.d.ts +0 -77
- package/node_modules/audio-decode/node_modules/audio-buffer/.eslintrc.json +0 -44
- package/node_modules/audio-decode/node_modules/audio-buffer/.github/workflows/node.js.yml +0 -31
- package/node_modules/audio-decode/node_modules/audio-buffer/.travis.yml +0 -7
- package/node_modules/audio-decode/node_modules/audio-buffer/index.js +0 -76
- package/node_modules/audio-decode/node_modules/audio-buffer/package.json +0 -37
- package/node_modules/audio-decode/node_modules/audio-buffer/readme.md +0 -56
- package/node_modules/audio-decode/node_modules/node-wav/README.md +0 -35
- package/node_modules/audio-decode/node_modules/node-wav/file.wav +0 -0
- package/node_modules/audio-decode/node_modules/node-wav/index.js +0 -291
- package/node_modules/audio-decode/node_modules/node-wav/package.json +0 -29
- package/node_modules/audio-decode/node_modules/node-wav/tests/file1.wav +0 -0
- package/node_modules/audio-decode/node_modules/node-wav/tests/test.js +0 -66
- package/node_modules/audio-decode/node_modules/node-wav/x.js +0 -12
- package/node_modules/audio-decode/node_modules/node-wav/x.json +0 -86702
- package/node_modules/audio-decode/node_modules/node-wav/x.js~ +0 -13
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/README.md +0 -320
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.min.js +0 -232
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.min.js.map +0 -1
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.opus-ml.min.js +0 -0
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.opus-ml.min.js.map +0 -1
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/index.js +0 -8
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/package.json +0 -74
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/src/OggOpusDecoder.js +0 -226
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/src/OggOpusDecoderWebWorker.js +0 -17
- package/node_modules/audio-decode/node_modules/ogg-opus-decoder/types.d.ts +0 -37
- package/node_modules/audio-decode/node_modules/opus-decoder/README.md +0 -265
- package/node_modules/audio-decode/node_modules/opus-decoder/dist/opus-decoder.min.js +0 -232
- package/node_modules/audio-decode/node_modules/opus-decoder/dist/opus-decoder.min.js.map +0 -1
- package/node_modules/audio-decode/node_modules/opus-decoder/index.js +0 -8
- package/node_modules/audio-decode/node_modules/opus-decoder/package.json +0 -56
- package/node_modules/audio-decode/node_modules/opus-decoder/src/EmscriptenWasm.js +0 -0
- package/node_modules/audio-decode/node_modules/opus-decoder/src/OpusDecoder.js +0 -239
- package/node_modules/audio-decode/node_modules/opus-decoder/src/OpusDecoderWebWorker.js +0 -17
- package/node_modules/audio-decode/node_modules/opus-decoder/types.d.ts +0 -74
- package/node_modules/audio-decode/readme.md +0 -49
- package/node_modules/audio-decode/tea.yaml +0 -6
- package/node_modules/audio-decode/test-case.js +0 -11
- package/node_modules/audio-decode/test.html +0 -15
- package/node_modules/audio-decode/test.js +0 -107
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { n as __reExport, t as __exportAll } from "./rolldown-runtime-BBjsoOtd.mjs";
|
|
2
|
+
import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-CtRPAQCL.mjs";
|
|
3
|
+
import { c as normalizeWhatsAppPayloadTextPreservingIndentation, d as listWhatsAppSendResultMessageIds, f as mergeWhatsAppAcceptedSendError, g as withWhatsAppLogicalDeliveryActivity, h as rememberWhatsAppPartialSend, l as prepareWhatsAppOutboundMedia, m as rememberWhatsAppAcceptedSend, o as normalizeWhatsAppOutboundPayload, p as normalizeWhatsAppSendResult, r as sendReactionWhatsApp, v as resolveWhatsAppReactionLevel } from "./send-BGdvf5cC.mjs";
|
|
3
4
|
import { i as getWhatsAppRuntime } from "./runtime-BLlToOi6.mjs";
|
|
4
5
|
import { r as getWhatsAppConnectionController } from "./connection-controller-runtime-context-hgLJoRc8.mjs";
|
|
5
|
-
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-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { t as
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-BnXw-UZI.mjs";
|
|
17
|
-
import { t as maybeResolveWhatsAppQuestionReaction } from "./question-reactions-D3Zq9Gbn.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-DmiqXIXO.mjs";
|
|
7
|
+
import { a as cacheInboundMessageMeta, i as buildQuotedMessageOptions, n as resolveWhatsAppGroupSessionRoute, o as lookupInboundMessageMeta, r as resolveWhatsAppLegacyGroupSessionKey } from "./group-session-key-2-mja4OF.mjs";
|
|
8
|
+
import { C as getMentionIdentities, D as getSenderIdentity, E as getSelfIdentity, O as identitiesOverlap, S as getComparableIdentityValues, T as getReplyContext, g as readWebSelfId, k as resolveComparableIdentity, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, v as readWebSelfIdentityForDecision, w as getPrimaryIdentityId } from "./auth-store-BBonwKks.mjs";
|
|
9
|
+
import { n as resolveWhatsAppGroupsConfigPath } from "./group-config-path-DZr3ucUO.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 } from "./socket-close-CT__V2fz.mjs";
|
|
11
|
+
import { n as getStatusCode, t as formatError } from "./session-errors-B8UcAnZN.mjs";
|
|
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-H4AkQJjT.mjs";
|
|
14
|
+
import { n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController } from "./connection-controller-CHo1oRJA.mjs";
|
|
15
|
+
import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-DiOFvb1s.mjs";
|
|
16
|
+
import { t as maybeResolveWhatsAppQuestionReaction } from "./question-reactions-CPyyi5AY.mjs";
|
|
18
17
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
19
18
|
import { createAckReactionHandle, createStatusReactionController, logAckFailure, removeAckReactionHandleAfterReply, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
20
19
|
import { bindIngressLifecycleToReplyOptions, createChannelIngressMonitor, createChannelMessageReplyPipeline, createMessageReceiptFromOutboundResults, listMessageReceiptPlatformIds, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
|
|
@@ -28,36 +27,37 @@ import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runt
|
|
|
28
27
|
import { buildChannelInboundEventContext, createChannelPartialDeliveryError, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundEnvelope as formatInboundEnvelope$1, formatInboundMediaUnavailableText, formatLocationText, formatMediaPlaceholderText, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, readAgentRunTerminalOutcome, resolveGroupThreadConfig, resolveInboundSessionEnvelopeContext, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, runGroupThread, shouldDebounceTextInbound, toInboundMediaFactsWithMetadata, toLocationContext } from "openclaw/plugin-sdk/channel-inbound";
|
|
29
28
|
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
|
|
30
29
|
import { isReasoningReplyPayload, resolveSendableOutboundReplyParts, resolveTextChunksWithFallback, sendMediaWithLeadingCaption } from "openclaw/plugin-sdk/reply-payload";
|
|
31
|
-
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
30
|
+
import { normalizeE164, normalizeE164 as normalizeE164$1, normalizeE164 as normalizeE164$2, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
32
31
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
33
32
|
import { DisconnectReason, downloadMediaMessage, isHostedLidUser, isHostedPnUser, isJidGroup, isJidGroup as isJidGroup$1, jidDecode, jidEncode, jidNormalizedUser, normalizeMessageContent as normalizeMessageContent$1 } from "baileys";
|
|
34
33
|
import { DEFAULT_ACCOUNT_ID, DEFAULT_MAIN_KEY, buildAgentMainSessionKey, buildAgentSessionKey, buildGroupHistoryKey, deriveLastRoutePolicy, normalizeAccountId, resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
35
|
-
import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
34
|
+
import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolvePromptHistoryLimit } from "openclaw/plugin-sdk/number-runtime";
|
|
36
35
|
import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
|
|
37
36
|
import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
|
|
38
37
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
38
|
+
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
39
39
|
import { createHash } from "node:crypto";
|
|
40
|
-
import { resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
40
|
+
import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
41
41
|
import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
|
|
42
42
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
|
|
43
43
|
import { drainPendingDeliveries } from "openclaw/plugin-sdk/delivery-queue-runtime";
|
|
44
|
-
import { DEFAULT_GROUP_HISTORY_LIMIT, buildHistoryContextFromEntries, buildInboundHistoryFromEntries, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
45
44
|
import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
|
|
46
|
-
import { fanInChannelIngressLifecycles, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
47
45
|
import { getSessionEntry, patchSessionEntry, resolveGroupSessionKey, resolveStorePath, resolveStorePath as resolveStorePath$1, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
|
|
46
|
+
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
48
47
|
import { createInboundDebouncer, resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound-debounce";
|
|
48
|
+
import { fanInChannelIngressLifecycles } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
49
49
|
import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
|
|
50
50
|
import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
|
51
51
|
import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
|
|
52
52
|
import { getRuntimeConfig as getRuntimeConfig$1 } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
|
53
53
|
import { resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
|
|
54
|
-
import { buildMentionRegexes, implicitMentionKindWhen, normalizeMentionText, resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-mention-gating";
|
|
55
54
|
import { channelReadyPatch, channelStoppedPatch, createTransportActivityStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
56
55
|
import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute } from "openclaw/plugin-sdk/conversation-binding-runtime";
|
|
57
56
|
import { resolveAgentIdentity, resolveIdentityNamePrefix } from "openclaw/plugin-sdk/agent-runtime";
|
|
58
57
|
import { normalizeGroupActivation, parseActivationCommand } from "openclaw/plugin-sdk/group-activation";
|
|
59
58
|
import { formatAudioTranscriptForAgent } from "openclaw/plugin-sdk/media-understanding-runtime";
|
|
60
59
|
import { hasControlCommand, isControlCommandMessage, shouldComputeCommandAuthorized } from "openclaw/plugin-sdk/command-detection";
|
|
60
|
+
import { buildHistoryContextFromEntries, buildInboundHistoryFromEntries, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
61
61
|
import { createInternalHookEvent, deriveInboundMessageHookContext, fireAndForgetBoundedHook, toInternalMessageReceivedContext, toPluginMessageContext, toPluginMessageReceivedEvent, triggerInternalHook } from "openclaw/plugin-sdk/hook-runtime";
|
|
62
62
|
import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
|
|
63
63
|
import { resolveBatchedReplyThreadingPolicy } from "openclaw/plugin-sdk/reply-reference";
|
|
@@ -142,12 +142,6 @@ function normalizeWhatsAppIngressPhone(value) {
|
|
|
142
142
|
if (!trimmed) return null;
|
|
143
143
|
return normalizeE164(trimmed);
|
|
144
144
|
}
|
|
145
|
-
function buildResolvedWhatsAppGroupConfig(params) {
|
|
146
|
-
return { channels: { whatsapp: {
|
|
147
|
-
groupPolicy: params.groupPolicy,
|
|
148
|
-
groups: params.groups
|
|
149
|
-
} } };
|
|
150
|
-
}
|
|
151
145
|
function resolveWhatsAppInboundPolicy(params) {
|
|
152
146
|
const account = resolveWhatsAppAccount({
|
|
153
147
|
cfg: params.cfg,
|
|
@@ -158,15 +152,15 @@ function resolveWhatsAppInboundPolicy(params) {
|
|
|
158
152
|
const dmAllowFrom = configuredAllowFrom.length > 0 ? configuredAllowFrom : params.selfE164 ? [params.selfE164] : [];
|
|
159
153
|
const groupAllowFrom = (Array.isArray(account.groupAllowFrom) && account.groupAllowFrom.length > 0 ? account.groupAllowFrom : void 0) ?? (configuredAllowFrom.length > 0 ? configuredAllowFrom : void 0) ?? [];
|
|
160
154
|
const defaultGroupPolicy = resolveDefaultGroupPolicy(params.cfg);
|
|
161
|
-
const { groupPolicy, providerMissingFallbackApplied } =
|
|
155
|
+
const { groupPolicy, providerMissingFallbackApplied } = resolveOpenProviderRuntimeGroupPolicy({
|
|
162
156
|
providerConfigPresent: params.cfg.channels?.whatsapp !== void 0,
|
|
163
157
|
groupPolicy: account.groupPolicy,
|
|
164
158
|
defaultGroupPolicy
|
|
165
159
|
});
|
|
166
|
-
const resolvedGroupCfg =
|
|
160
|
+
const resolvedGroupCfg = { channels: { whatsapp: {
|
|
167
161
|
groupPolicy,
|
|
168
162
|
groups: account.groups
|
|
169
|
-
}
|
|
163
|
+
} } };
|
|
170
164
|
const isSamePhone = (value) => typeof value === "string" && typeof params.selfE164 === "string" && value === params.selfE164;
|
|
171
165
|
return {
|
|
172
166
|
account,
|
|
@@ -192,7 +186,7 @@ function resolveWhatsAppInboundPolicy(params) {
|
|
|
192
186
|
};
|
|
193
187
|
}
|
|
194
188
|
async function resolveWhatsAppIngressAccess(params) {
|
|
195
|
-
return await
|
|
189
|
+
return await getWhatsAppRuntime().channel.inbound.ingress.resolveStable({
|
|
196
190
|
channelId: "whatsapp",
|
|
197
191
|
accountId: params.policy.account.accountId,
|
|
198
192
|
identity: {
|
|
@@ -251,11 +245,7 @@ function rememberWhatsAppBaileysCacheEntry(cache, key, value, ttlMs) {
|
|
|
251
245
|
expiresAt: Date.now() + ttlMs,
|
|
252
246
|
value
|
|
253
247
|
});
|
|
254
|
-
|
|
255
|
-
const oldest = cache.keys().next();
|
|
256
|
-
if (oldest.done) break;
|
|
257
|
-
cache.delete(oldest.value);
|
|
258
|
-
}
|
|
248
|
+
pruneMapToMaxSize(cache, WHATSAPP_BAILEYS_CACHE_MAX_ENTRIES);
|
|
259
249
|
}
|
|
260
250
|
function readWhatsAppBaileysCacheEntry(cache, key) {
|
|
261
251
|
const entry = cache.get(key);
|
|
@@ -269,116 +259,6 @@ function readWhatsAppBaileysCacheEntry(cache, key) {
|
|
|
269
259
|
return entry.value;
|
|
270
260
|
}
|
|
271
261
|
//#endregion
|
|
272
|
-
//#region extensions/whatsapp/src/inbound/durable-payload.ts
|
|
273
|
-
var WhatsAppIngressPermanentError = class extends Error {
|
|
274
|
-
constructor(reason, message, options) {
|
|
275
|
-
super(message, options);
|
|
276
|
-
this.reason = reason;
|
|
277
|
-
this.name = "WhatsAppIngressPermanentError";
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
function serializeWhatsAppDurableInboundMessage(message) {
|
|
281
|
-
const timestamp = message.messageTimestamp;
|
|
282
|
-
let serializedMessage = message;
|
|
283
|
-
if (timestamp != null && typeof timestamp === "object") try {
|
|
284
|
-
const numericTimestamp = Number(timestamp);
|
|
285
|
-
if (Number.isFinite(numericTimestamp)) serializedMessage = {
|
|
286
|
-
...message,
|
|
287
|
-
messageTimestamp: numericTimestamp
|
|
288
|
-
};
|
|
289
|
-
} catch {}
|
|
290
|
-
return JSON.parse(JSON.stringify(serializedMessage, BufferJSON.replacer));
|
|
291
|
-
}
|
|
292
|
-
function deserializeWhatsAppDurableInboundMessage(message) {
|
|
293
|
-
try {
|
|
294
|
-
return JSON.parse(JSON.stringify(message), BufferJSON.reviver);
|
|
295
|
-
} catch (error) {
|
|
296
|
-
throw new WhatsAppIngressPermanentError("invalid-payload", "WhatsApp ingress row contains an invalid serialized message", { cause: error });
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
//#endregion
|
|
300
|
-
//#region extensions/whatsapp/src/inbound/durable-receive.ts
|
|
301
|
-
const WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION = 1;
|
|
302
|
-
function hashNamespacePart(value) {
|
|
303
|
-
return createHash("sha256").update(value).digest("hex").slice(0, 24);
|
|
304
|
-
}
|
|
305
|
-
function createWhatsAppDurableInboundMessageId(params) {
|
|
306
|
-
return createHash("sha256").update(`${params.remoteJid}\n${params.id}`).digest("hex");
|
|
307
|
-
}
|
|
308
|
-
function inspectWhatsAppIngressMessage(message) {
|
|
309
|
-
const remoteJid = message.key?.remoteJid?.trim();
|
|
310
|
-
const id = message.key?.id?.trim();
|
|
311
|
-
if (!remoteJid || !id) throw new WhatsAppIngressPermanentError("missing-message-key", "WhatsApp ingress message is missing key.remoteJid or key.id");
|
|
312
|
-
return {
|
|
313
|
-
eventId: createWhatsAppDurableInboundMessageId({
|
|
314
|
-
remoteJid,
|
|
315
|
-
id
|
|
316
|
-
}),
|
|
317
|
-
laneKey: remoteJid
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
/** Account-scoped queue shared with the pre-drain WhatsApp receive journal. */
|
|
321
|
-
function createWhatsAppDurableInboundQueue(accountId) {
|
|
322
|
-
return getWhatsAppRuntime().state.openChannelIngressQueue({
|
|
323
|
-
accountId: hashNamespacePart(accountId),
|
|
324
|
-
stateDir: getWhatsAppRuntime().state.resolveStateDir()
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
function resolveWhatsAppIngressNonRetryableFailure(error) {
|
|
328
|
-
return error instanceof WhatsAppIngressPermanentError ? {
|
|
329
|
-
reason: error.reason,
|
|
330
|
-
message: error.message
|
|
331
|
-
} : null;
|
|
332
|
-
}
|
|
333
|
-
/** Shared monitor with per-conversation lanes and completion at reply-lane adoption. */
|
|
334
|
-
function createWhatsAppIngressMonitor(params) {
|
|
335
|
-
return createChannelIngressMonitor({
|
|
336
|
-
queue: params.queue,
|
|
337
|
-
inspect: (admission) => inspectWhatsAppIngressMessage(admission.message),
|
|
338
|
-
payload: {
|
|
339
|
-
version: WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION,
|
|
340
|
-
serialize: (admission, { receivedAt }) => ({
|
|
341
|
-
...admission,
|
|
342
|
-
message: serializeWhatsAppDurableInboundMessage(admission.message),
|
|
343
|
-
receivedAt
|
|
344
|
-
}),
|
|
345
|
-
deserialize: (payload) => ({
|
|
346
|
-
...payload,
|
|
347
|
-
message: deserializeWhatsAppDurableInboundMessage(payload.message)
|
|
348
|
-
}),
|
|
349
|
-
encode: ({ body }) => body,
|
|
350
|
-
decode: (payload) => ({
|
|
351
|
-
version: WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION,
|
|
352
|
-
body: payload
|
|
353
|
-
}),
|
|
354
|
-
createClaimError: (kind) => new WhatsAppIngressPermanentError(kind === "invalid-version" ? "invalid-payload" : "event-id-mismatch", kind === "invalid-version" ? "WhatsApp ingress row has an invalid payload version" : "WhatsApp ingress row identity does not match its transport message key")
|
|
355
|
-
},
|
|
356
|
-
deliver: (admission, lifecycle) => params.dispatch(admission, lifecycle),
|
|
357
|
-
pollIntervalMs: params.pollIntervalMs,
|
|
358
|
-
retention: {
|
|
359
|
-
completedTtlMs: 6048e5,
|
|
360
|
-
completedMaxEntries: 5e3,
|
|
361
|
-
failedMaxEntries: 450
|
|
362
|
-
},
|
|
363
|
-
drain: {
|
|
364
|
-
resolveNonRetryableFailure: resolveWhatsAppIngressNonRetryableFailure,
|
|
365
|
-
deriveLaneKey: (record) => {
|
|
366
|
-
try {
|
|
367
|
-
return inspectWhatsAppIngressMessage(deserializeWhatsAppDurableInboundMessage(record.payload.message)).laneKey;
|
|
368
|
-
} catch {
|
|
369
|
-
return record.id;
|
|
370
|
-
}
|
|
371
|
-
},
|
|
372
|
-
...params.onLog ? { onLog: params.onLog } : {}
|
|
373
|
-
},
|
|
374
|
-
...params.abortSignal ? { abortSignal: params.abortSignal } : {},
|
|
375
|
-
admissionMode: "while-running",
|
|
376
|
-
createStoppedError: () => /* @__PURE__ */ new Error("WhatsApp ingress monitor is stopped."),
|
|
377
|
-
...params.onError ? { onError: params.onError } : {},
|
|
378
|
-
...params.onActivityChange ? { onActivityChange: params.onActivityChange } : {}
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
//#endregion
|
|
382
262
|
//#region extensions/whatsapp/src/inbound/group-metadata-cache.ts
|
|
383
263
|
const GROUP_META_TTL_MS = 3e5;
|
|
384
264
|
const WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES = 500;
|
|
@@ -393,11 +273,7 @@ function rememberGroupMetadataCacheEntry(cache, jid, entry) {
|
|
|
393
273
|
}
|
|
394
274
|
if (cache.has(jid)) cache.delete(jid);
|
|
395
275
|
cache.set(jid, entry);
|
|
396
|
-
|
|
397
|
-
const oldest = cache.keys().next();
|
|
398
|
-
if (oldest.done) break;
|
|
399
|
-
cache.delete(oldest.value);
|
|
400
|
-
}
|
|
276
|
+
pruneMapToMaxSize(cache, WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES);
|
|
401
277
|
}
|
|
402
278
|
function readGroupMetadataCacheEntry(cache, jid) {
|
|
403
279
|
const entry = cache.get(jid);
|
|
@@ -587,6 +463,117 @@ function closeInboundMonitorSocket(sock) {
|
|
|
587
463
|
sock.ws?.close?.();
|
|
588
464
|
}
|
|
589
465
|
//#endregion
|
|
466
|
+
//#region extensions/whatsapp/src/inbound/durable-payload.ts
|
|
467
|
+
var WhatsAppIngressPermanentError = class extends Error {
|
|
468
|
+
constructor(reason, message, options) {
|
|
469
|
+
super(message, options);
|
|
470
|
+
this.reason = reason;
|
|
471
|
+
this.name = "WhatsAppIngressPermanentError";
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
function serializeWhatsAppDurableInboundMessage(message) {
|
|
475
|
+
const timestamp = message.messageTimestamp;
|
|
476
|
+
let serializedMessage = message;
|
|
477
|
+
if (timestamp != null && typeof timestamp === "object") try {
|
|
478
|
+
const numericTimestamp = Number(timestamp);
|
|
479
|
+
if (Number.isFinite(numericTimestamp)) serializedMessage = {
|
|
480
|
+
...message,
|
|
481
|
+
messageTimestamp: numericTimestamp
|
|
482
|
+
};
|
|
483
|
+
} catch {}
|
|
484
|
+
return JSON.parse(JSON.stringify(serializedMessage, BufferJSON.replacer));
|
|
485
|
+
}
|
|
486
|
+
function deserializeWhatsAppDurableInboundMessage(message) {
|
|
487
|
+
try {
|
|
488
|
+
return JSON.parse(JSON.stringify(message), BufferJSON.reviver);
|
|
489
|
+
} catch (error) {
|
|
490
|
+
throw new WhatsAppIngressPermanentError("invalid-payload", "WhatsApp ingress row contains an invalid serialized message", { cause: error });
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
//#endregion
|
|
494
|
+
//#region extensions/whatsapp/src/inbound/durable-receive.ts
|
|
495
|
+
const WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION = 1;
|
|
496
|
+
function hashNamespacePart(value) {
|
|
497
|
+
return createHash("sha256").update(value).digest("hex").slice(0, 24);
|
|
498
|
+
}
|
|
499
|
+
function createWhatsAppDurableInboundMessageId(params) {
|
|
500
|
+
return createHash("sha256").update(`${params.remoteJid}\n${params.id}`).digest("hex");
|
|
501
|
+
}
|
|
502
|
+
function inspectWhatsAppIngressMessage(message) {
|
|
503
|
+
const remoteJid = message.key?.remoteJid?.trim();
|
|
504
|
+
const id = message.key?.id?.trim();
|
|
505
|
+
if (!remoteJid || !id) throw new WhatsAppIngressPermanentError("missing-message-key", "WhatsApp ingress message is missing key.remoteJid or key.id");
|
|
506
|
+
return {
|
|
507
|
+
eventId: createWhatsAppDurableInboundMessageId({
|
|
508
|
+
remoteJid,
|
|
509
|
+
id
|
|
510
|
+
}),
|
|
511
|
+
laneKey: remoteJid
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
/** Account-scoped queue shared with the pre-drain WhatsApp receive journal. */
|
|
515
|
+
function createWhatsAppDurableInboundQueue(accountId) {
|
|
516
|
+
return getWhatsAppRuntime().state.openChannelIngressQueue({
|
|
517
|
+
accountId: hashNamespacePart(accountId),
|
|
518
|
+
stateDir: getWhatsAppRuntime().state.resolveStateDir()
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
function resolveWhatsAppIngressNonRetryableFailure(error) {
|
|
522
|
+
return error instanceof WhatsAppIngressPermanentError ? {
|
|
523
|
+
reason: error.reason,
|
|
524
|
+
message: error.message
|
|
525
|
+
} : null;
|
|
526
|
+
}
|
|
527
|
+
/** Shared monitor with per-conversation lanes and completion at reply-lane adoption. */
|
|
528
|
+
function createWhatsAppIngressMonitor(params) {
|
|
529
|
+
return createChannelIngressMonitor({
|
|
530
|
+
queue: params.queue,
|
|
531
|
+
inspect: (admission) => inspectWhatsAppIngressMessage(admission.message),
|
|
532
|
+
payload: {
|
|
533
|
+
version: WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION,
|
|
534
|
+
serialize: (admission, { receivedAt }) => ({
|
|
535
|
+
...admission,
|
|
536
|
+
message: serializeWhatsAppDurableInboundMessage(admission.message),
|
|
537
|
+
receivedAt
|
|
538
|
+
}),
|
|
539
|
+
deserialize: (payload) => ({
|
|
540
|
+
...payload,
|
|
541
|
+
message: deserializeWhatsAppDurableInboundMessage(payload.message)
|
|
542
|
+
}),
|
|
543
|
+
encode: ({ body }) => body,
|
|
544
|
+
decode: (payload) => ({
|
|
545
|
+
version: WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION,
|
|
546
|
+
body: payload
|
|
547
|
+
}),
|
|
548
|
+
createClaimError: (kind) => new WhatsAppIngressPermanentError(kind === "invalid-version" ? "invalid-payload" : "event-id-mismatch", kind === "invalid-version" ? "WhatsApp ingress row has an invalid payload version" : "WhatsApp ingress row identity does not match its transport message key")
|
|
549
|
+
},
|
|
550
|
+
deliver: (admission, lifecycle) => params.dispatch(admission, lifecycle),
|
|
551
|
+
pollIntervalMs: params.pollIntervalMs,
|
|
552
|
+
retention: {
|
|
553
|
+
completedTtlMs: 6048e5,
|
|
554
|
+
completedMaxEntries: 5e3,
|
|
555
|
+
failedMaxEntries: 450
|
|
556
|
+
},
|
|
557
|
+
drain: {
|
|
558
|
+
deferredLaneOccupancy: "release",
|
|
559
|
+
resolveNonRetryableFailure: resolveWhatsAppIngressNonRetryableFailure,
|
|
560
|
+
deriveLaneKey: (record) => {
|
|
561
|
+
try {
|
|
562
|
+
return inspectWhatsAppIngressMessage(deserializeWhatsAppDurableInboundMessage(record.payload.message)).laneKey;
|
|
563
|
+
} catch {
|
|
564
|
+
return record.id;
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
...params.onLog ? { onLog: params.onLog } : {}
|
|
568
|
+
},
|
|
569
|
+
...params.abortSignal ? { abortSignal: params.abortSignal } : {},
|
|
570
|
+
admissionMode: "while-running",
|
|
571
|
+
createStoppedError: () => /* @__PURE__ */ new Error("WhatsApp ingress monitor is stopped."),
|
|
572
|
+
...params.onError ? { onError: params.onError } : {},
|
|
573
|
+
...params.onActivityChange ? { onActivityChange: params.onActivityChange } : {}
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
//#endregion
|
|
590
577
|
//#region extensions/whatsapp/src/inbound/ingress-lifecycle.ts
|
|
591
578
|
const ingressLifecycleKey = Symbol("whatsappIngressLifecycle");
|
|
592
579
|
function attachWhatsAppIngressLifecycle(message, lifecycle) {
|
|
@@ -608,19 +595,25 @@ function createWhatsAppInboundMessageDebouncer(options) {
|
|
|
608
595
|
for (const resolve of waiters) resolve();
|
|
609
596
|
};
|
|
610
597
|
const buildKey = (msg) => {
|
|
598
|
+
const admission = requireWhatsAppInboundAdmission(msg);
|
|
599
|
+
return `${admission.accountId}:${admission.conversation.id}`;
|
|
600
|
+
};
|
|
601
|
+
const resolveSenderKey = (msg) => {
|
|
611
602
|
const admission = requireWhatsAppInboundAdmission(msg);
|
|
612
603
|
const sender = msg.platform.sender;
|
|
613
|
-
|
|
614
|
-
return senderKey ? `${admission.accountId}:${admission.conversation.id}:${senderKey}` : null;
|
|
604
|
+
return admission.conversation.kind === "group" ? getPrimaryIdentityId(sender ?? null) ?? msg.platform.senderJid ?? msg.platform.senderE164 ?? msg.platform.senderName ?? admission.sender.id : admission.conversation.id;
|
|
615
605
|
};
|
|
616
606
|
const shouldDebounce = (msg) => options.shouldDebounce?.(msg) ?? true;
|
|
617
|
-
const trackKey = (key) => {
|
|
618
|
-
pendingKeys.set(key,
|
|
607
|
+
const trackKey = (key, senderKey) => {
|
|
608
|
+
pendingKeys.set(key, {
|
|
609
|
+
count: (pendingKeys.get(key)?.count ?? 0) + 1,
|
|
610
|
+
senderKey
|
|
611
|
+
});
|
|
619
612
|
};
|
|
620
613
|
const releaseKey = (entry) => {
|
|
621
614
|
if (!entry.debounceKey || entry.debounceKeyTracked !== true) return;
|
|
622
|
-
const
|
|
623
|
-
if (
|
|
615
|
+
const pending = pendingKeys.get(entry.debounceKey);
|
|
616
|
+
if (pending && pending.count > 1) pending.count -= 1;
|
|
624
617
|
else pendingKeys.delete(entry.debounceKey);
|
|
625
618
|
};
|
|
626
619
|
const orderEntries = (entries) => entries.toSorted((a, b) => {
|
|
@@ -701,14 +694,15 @@ function createWhatsAppInboundMessageDebouncer(options) {
|
|
|
701
694
|
debounceMs: options.resolveDebounceMs()
|
|
702
695
|
};
|
|
703
696
|
const key = buildKey(message);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
697
|
+
message.debounceKey = key;
|
|
698
|
+
const senderKey = resolveSenderKey(message);
|
|
699
|
+
const pending = pendingKeys.get(key);
|
|
700
|
+
if (pending && pending.senderKey !== senderKey) await debouncer.flushKey(key);
|
|
701
|
+
if (message.debounceMs > 0 && shouldDebounce(message)) {
|
|
702
|
+
message.debounceKeyTracked = true;
|
|
703
|
+
trackKey(key, senderKey);
|
|
704
|
+
options.onPendingWorkChanged();
|
|
705
|
+
notifyWork();
|
|
712
706
|
}
|
|
713
707
|
await debouncer.enqueue(message);
|
|
714
708
|
};
|
|
@@ -743,11 +737,8 @@ function createWhatsAppInboundMessageDebouncer(options) {
|
|
|
743
737
|
}
|
|
744
738
|
//#endregion
|
|
745
739
|
//#region extensions/whatsapp/src/inbound/media.ts
|
|
746
|
-
function unwrapMessage(message) {
|
|
747
|
-
return normalizeMessageContent$1(message);
|
|
748
|
-
}
|
|
749
740
|
async function downloadInboundMedia(msg, sock, maxBytes = 52428800, normalizedMessage) {
|
|
750
|
-
const message = normalizedMessage ??
|
|
741
|
+
const message = normalizedMessage ?? normalizeMessageContent$1(msg.message);
|
|
751
742
|
if (!message) return;
|
|
752
743
|
const mimetype = resolveInboundMediaMimetype(message);
|
|
753
744
|
const fileName = message.documentMessage?.fileName ?? void 0;
|
|
@@ -763,7 +754,7 @@ async function downloadInboundMedia(msg, sock, maxBytes = 52428800, normalizedMe
|
|
|
763
754
|
};
|
|
764
755
|
}
|
|
765
756
|
async function downloadQuotedInboundMedia(msg, sock, maxBytes = 52428800) {
|
|
766
|
-
const message =
|
|
757
|
+
const message = normalizeMessageContent$1(msg.message);
|
|
767
758
|
const contextInfo = extractContextInfo(message);
|
|
768
759
|
if (!contextInfo?.quotedMessage) return;
|
|
769
760
|
const quotedMessage = contextInfo.quotedMessage;
|
|
@@ -1170,12 +1161,9 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1170
1161
|
logWhatsAppVerbose$1(options.verbose, `Failed to mark message ${id} read: ${String(err)}`);
|
|
1171
1162
|
}
|
|
1172
1163
|
};
|
|
1173
|
-
const maybeLogSkippedSelfChatReadReceipt = (inbound, target) => {
|
|
1174
|
-
if (target?.id && inbound.access.isSelfChat && options.verbose) logWhatsAppVerbose$1(options.verbose, `Self-chat mode: skipping read receipt for ${target.id}`);
|
|
1175
|
-
};
|
|
1176
1164
|
const maybeMarkNonSelfChatReadReceipt = async (inbound, target) => {
|
|
1177
1165
|
if (inbound.access.isSelfChat) {
|
|
1178
|
-
|
|
1166
|
+
if (target?.id) logWhatsAppVerbose$1(options.verbose, `Self-chat mode: skipping read receipt for ${target.id}`);
|
|
1179
1167
|
return;
|
|
1180
1168
|
}
|
|
1181
1169
|
await maybeMarkInboundAsRead(target);
|
|
@@ -1251,25 +1239,27 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1251
1239
|
mentions: groupMentions
|
|
1252
1240
|
} : void 0;
|
|
1253
1241
|
const channelStructuredContext = [
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1242
|
+
[
|
|
1243
|
+
"WhatsApp media",
|
|
1244
|
+
"media",
|
|
1245
|
+
enriched.nativeMedia
|
|
1246
|
+
],
|
|
1247
|
+
[
|
|
1248
|
+
"WhatsApp contact",
|
|
1249
|
+
enriched.contactContext?.kind,
|
|
1250
|
+
enriched.contactContext
|
|
1251
|
+
],
|
|
1252
|
+
[
|
|
1253
|
+
"WhatsApp external ad reply",
|
|
1254
|
+
"external_ad_reply",
|
|
1255
|
+
enriched.externalAdReplyContext
|
|
1256
|
+
]
|
|
1257
|
+
].flatMap(([label, type, payload]) => payload ? [{
|
|
1258
|
+
label,
|
|
1259
|
+
source: "whatsapp",
|
|
1260
|
+
type,
|
|
1261
|
+
payload
|
|
1262
|
+
}] : []);
|
|
1273
1263
|
const inboundMessage = {
|
|
1274
1264
|
admission: inbound.access.admission,
|
|
1275
1265
|
event: {
|
|
@@ -1332,25 +1322,29 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1332
1322
|
}
|
|
1333
1323
|
await messageDebouncer.enqueue(inboundMessage);
|
|
1334
1324
|
};
|
|
1325
|
+
const resolveApprovalReaction = (msg) => maybeResolveWhatsAppApprovalReaction({
|
|
1326
|
+
cfg: options.loadConfig?.() ?? options.cfg,
|
|
1327
|
+
accountId: options.accountId,
|
|
1328
|
+
msg,
|
|
1329
|
+
selfJid: self.jid,
|
|
1330
|
+
selfLid: self.lid,
|
|
1331
|
+
resolveInboundJid,
|
|
1332
|
+
resolveReactionTargetJids,
|
|
1333
|
+
logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
|
|
1334
|
+
});
|
|
1335
1335
|
const processDurableInboundMessage = async (admission, lifecycle) => {
|
|
1336
1336
|
const { message: msg, ...context } = admission;
|
|
1337
1337
|
rememberBaileysMessage(msg.key?.remoteJid, msg.key?.id, msg.message);
|
|
1338
1338
|
const remoteJid = msg.key?.remoteJid;
|
|
1339
1339
|
const id = msg.key?.id;
|
|
1340
|
-
const durableId = remoteJid && id ?
|
|
1340
|
+
const durableId = remoteJid && id ? createWhatsAppDurableInboundMessageId({
|
|
1341
|
+
remoteJid,
|
|
1342
|
+
id
|
|
1343
|
+
}) : void 0;
|
|
1341
1344
|
const preparation = durableId ? preparedInboundByDurableId.get(durableId) : void 0;
|
|
1342
1345
|
if (durableId) preparedInboundByDurableId.delete(durableId);
|
|
1343
1346
|
if (context.skipRecentOutboundEcho === true) return "completed";
|
|
1344
|
-
if (await
|
|
1345
|
-
cfg: options.loadConfig?.() ?? options.cfg,
|
|
1346
|
-
accountId: options.accountId,
|
|
1347
|
-
msg,
|
|
1348
|
-
selfJid: self.jid,
|
|
1349
|
-
selfLid: self.lid,
|
|
1350
|
-
resolveInboundJid,
|
|
1351
|
-
resolveReactionTargetJids,
|
|
1352
|
-
logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
|
|
1353
|
-
})) return "completed";
|
|
1347
|
+
if (await resolveApprovalReaction(msg)) return "completed";
|
|
1354
1348
|
const prepared = await preparation;
|
|
1355
1349
|
if (prepared === null) return "completed";
|
|
1356
1350
|
const inbound = prepared ?? await normalizeInboundMessage(msg);
|
|
@@ -1405,16 +1399,7 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1405
1399
|
const receiveOrder = nextReceiveOrder++;
|
|
1406
1400
|
let approvalReactionResolved = false;
|
|
1407
1401
|
try {
|
|
1408
|
-
approvalReactionResolved = await
|
|
1409
|
-
cfg: options.loadConfig?.() ?? options.cfg,
|
|
1410
|
-
accountId: options.accountId,
|
|
1411
|
-
msg,
|
|
1412
|
-
selfJid: self.jid,
|
|
1413
|
-
selfLid: self.lid,
|
|
1414
|
-
resolveInboundJid,
|
|
1415
|
-
resolveReactionTargetJids,
|
|
1416
|
-
logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
|
|
1417
|
-
});
|
|
1402
|
+
approvalReactionResolved = await resolveApprovalReaction(msg);
|
|
1418
1403
|
} catch (error) {
|
|
1419
1404
|
inboundLogger.warn({ error: formatError(error) }, "whatsapp approval reaction resolution failed; admitting reaction for durable replay");
|
|
1420
1405
|
}
|
|
@@ -1424,16 +1409,19 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1424
1409
|
const skipRecentOutboundEcho = shouldSkipRecentOutboundEcho(msg);
|
|
1425
1410
|
const remoteJid = msg.key?.remoteJid;
|
|
1426
1411
|
const id = msg.key?.id;
|
|
1427
|
-
const durableId = remoteJid && id ?
|
|
1412
|
+
const durableId = remoteJid && id ? createWhatsAppDurableInboundMessageId({
|
|
1413
|
+
remoteJid,
|
|
1414
|
+
id
|
|
1415
|
+
}) : void 0;
|
|
1428
1416
|
let resolvePrepared;
|
|
1429
1417
|
if (durableId && !preparedInboundByDurableId.has(durableId)) {
|
|
1430
1418
|
if (preparedInboundByDurableId.size >= 1e3) {
|
|
1431
1419
|
const oldest = preparedInboundByDurableId.keys().next().value;
|
|
1432
1420
|
if (oldest !== void 0) preparedInboundByDurableId.delete(oldest);
|
|
1433
1421
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1422
|
+
const prepared = createDeferred();
|
|
1423
|
+
resolvePrepared = prepared.resolve;
|
|
1424
|
+
preparedInboundByDurableId.set(durableId, prepared.promise);
|
|
1437
1425
|
}
|
|
1438
1426
|
const finishPreparation = (inbound, keepForDrain = false) => {
|
|
1439
1427
|
resolvePrepared?.(inbound);
|
|
@@ -1483,22 +1471,19 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
|
|
|
1483
1471
|
publishPendingWorkState();
|
|
1484
1472
|
});
|
|
1485
1473
|
};
|
|
1486
|
-
const drainDebouncedInboundMessages = async () => {
|
|
1487
|
-
await messageDebouncer.drain();
|
|
1488
|
-
};
|
|
1489
1474
|
const drainInboundBeforeSocketClose = async () => {
|
|
1490
1475
|
for (;;) {
|
|
1491
|
-
await
|
|
1476
|
+
await messageDebouncer.drain();
|
|
1492
1477
|
if (pendingMessageHandlers.size === 0) break;
|
|
1493
1478
|
const handlers = Array.from(pendingMessageHandlers);
|
|
1494
1479
|
await Promise.race([Promise.allSettled(handlers), messageDebouncer.waitForWorkOrIdle(handlers, pendingMessageHandlers.size === 0)]);
|
|
1495
1480
|
if (pendingMessageHandlers.size === 0 && !messageDebouncer.hasPendingWork()) break;
|
|
1496
1481
|
}
|
|
1497
|
-
await
|
|
1482
|
+
await messageDebouncer.drain();
|
|
1498
1483
|
for (;;) {
|
|
1499
1484
|
await durableInboundMonitor.waitForIdle();
|
|
1500
1485
|
if (!messageDebouncer.hasPendingWork()) break;
|
|
1501
|
-
await
|
|
1486
|
+
await messageDebouncer.drain();
|
|
1502
1487
|
}
|
|
1503
1488
|
await durableInboundMonitor.stop();
|
|
1504
1489
|
};
|
|
@@ -1564,16 +1549,7 @@ async function createWhatsAppAttachedSocketSession(options) {
|
|
|
1564
1549
|
const disconnectRetryPolicy = options.disconnectRetryPolicy ?? DEFAULT_RECONNECT_POLICY;
|
|
1565
1550
|
const sendRetryMaxAttempts = disconnectRetryPolicy.maxAttempts > 0 ? disconnectRetryPolicy.maxAttempts : DEFAULT_RECONNECT_POLICY.maxAttempts;
|
|
1566
1551
|
const sendOperationTimeoutMs = resolveWhatsAppSocketOperationTimeoutMs(options.socketTiming.defaultQueryTimeoutMs);
|
|
1567
|
-
|
|
1568
|
-
const onClose = new Promise((resolve) => {
|
|
1569
|
-
onCloseResolve = resolve;
|
|
1570
|
-
});
|
|
1571
|
-
const resolveClose = (reason) => {
|
|
1572
|
-
if (!onCloseResolve) return;
|
|
1573
|
-
const resolver = onCloseResolve;
|
|
1574
|
-
onCloseResolve = null;
|
|
1575
|
-
resolver(reason);
|
|
1576
|
-
};
|
|
1552
|
+
const { promise: onClose, resolve: resolveClose } = createDeferred();
|
|
1577
1553
|
const presence = options.selfChatMode ? "unavailable" : "available";
|
|
1578
1554
|
try {
|
|
1579
1555
|
await createWhatsAppSocketOperationTimeoutAdapter(sock, sendOperationTimeoutMs).sendPresenceUpdate(presence);
|
|
@@ -1608,14 +1584,14 @@ async function createWhatsAppAttachedSocketSession(options) {
|
|
|
1608
1584
|
rememberWhatsAppBaileysCacheEntry(options.recentMessageKeys, `${remoteJid}:${messageId}`, message, BAILEYS_MESSAGE_TTL_MS);
|
|
1609
1585
|
};
|
|
1610
1586
|
const rememberOutboundMessage = (remoteJid, result) => {
|
|
1611
|
-
const messageId =
|
|
1587
|
+
const messageId = result?.key?.id;
|
|
1612
1588
|
if (!messageId) return;
|
|
1613
1589
|
rememberRecentOutboundMessage({
|
|
1614
1590
|
accountId: options.accountId,
|
|
1615
1591
|
remoteJid,
|
|
1616
1592
|
messageId
|
|
1617
1593
|
});
|
|
1618
|
-
const message =
|
|
1594
|
+
const message = result?.message;
|
|
1619
1595
|
rememberBaileysMessage(remoteJid, messageId, message);
|
|
1620
1596
|
cacheInboundMessageMeta(options.accountId, remoteJid, messageId, {
|
|
1621
1597
|
fromMe: true,
|
|
@@ -1705,7 +1681,7 @@ async function createWhatsAppAttachedSocketSession(options) {
|
|
|
1705
1681
|
}
|
|
1706
1682
|
};
|
|
1707
1683
|
const socketOperations = {
|
|
1708
|
-
sendMessage:
|
|
1684
|
+
sendMessage: sendTrackedMessage,
|
|
1709
1685
|
sendPresenceUpdate: async (presenceLocal, jid) => {
|
|
1710
1686
|
const currentSock = getCurrentSock();
|
|
1711
1687
|
if (!currentSock) throw new Error(RECONNECT_IN_PROGRESS_ERROR);
|
|
@@ -1836,7 +1812,7 @@ async function attachWebInboxToSocket(options) {
|
|
|
1836
1812
|
appendReplyWindow: options.appendReplyWindow,
|
|
1837
1813
|
shouldDebounce: options.shouldDebounce,
|
|
1838
1814
|
onPendingWorkChanged: options.onPendingWorkChanged,
|
|
1839
|
-
durableInboundQueue: options.durableInboundQueue
|
|
1815
|
+
durableInboundQueue: options.durableInboundQueue
|
|
1840
1816
|
});
|
|
1841
1817
|
const sendApi = createWebSendApi({
|
|
1842
1818
|
sock: socketSession.socketOperations,
|
|
@@ -1903,64 +1879,6 @@ const whatsappInboundLog = whatsappLog.child("inbound");
|
|
|
1903
1879
|
const whatsappOutboundLog = whatsappLog.child("outbound");
|
|
1904
1880
|
const whatsappHeartbeatLog = whatsappLog.child("heartbeat");
|
|
1905
1881
|
//#endregion
|
|
1906
|
-
//#region extensions/whatsapp/src/auto-reply/mentions.ts
|
|
1907
|
-
function buildMentionConfig(cfg, agentId, options) {
|
|
1908
|
-
return {
|
|
1909
|
-
mentionRegexes: buildMentionRegexes(cfg, agentId, options),
|
|
1910
|
-
allowFrom: cfg.channels?.whatsapp?.allowFrom
|
|
1911
|
-
};
|
|
1912
|
-
}
|
|
1913
|
-
function resolveMentionTargets(msg, authDir) {
|
|
1914
|
-
return {
|
|
1915
|
-
normalizedMentions: getMentionIdentities(msg, authDir),
|
|
1916
|
-
self: getSelfIdentity(msg, authDir)
|
|
1917
|
-
};
|
|
1918
|
-
}
|
|
1919
|
-
function isBotMentionedFromTargets(msg, mentionCfg, targets) {
|
|
1920
|
-
const clean = (text) => normalizeMentionText(text);
|
|
1921
|
-
const explicitSelfChatOverride = typeof mentionCfg.isSelfChat === "boolean";
|
|
1922
|
-
const isGroupConversation = requireWhatsAppInboundAdmission(msg).conversation.kind === "group";
|
|
1923
|
-
const isSelfChat = explicitSelfChatOverride ? Boolean(mentionCfg.isSelfChat) : isSelfChatMode(targets.self.e164, mentionCfg.allowFrom) && !isGroupConversation;
|
|
1924
|
-
const hasMentions = targets.normalizedMentions.length > 0;
|
|
1925
|
-
const hasNativeMentionsOutsideSelfChat = hasMentions && !isSelfChat;
|
|
1926
|
-
if (hasNativeMentionsOutsideSelfChat) {
|
|
1927
|
-
for (const mention of targets.normalizedMentions) if (identitiesOverlap(targets.self, mention)) return true;
|
|
1928
|
-
} else if (hasMentions && isSelfChat) {}
|
|
1929
|
-
const bodyClean = clean(msg.payload.body);
|
|
1930
|
-
if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean))) return true;
|
|
1931
|
-
if (hasNativeMentionsOutsideSelfChat) return false;
|
|
1932
|
-
if (targets.self.e164) {
|
|
1933
|
-
const selfDigits = targets.self.e164.replace(/\D/g, "");
|
|
1934
|
-
if (selfDigits) {
|
|
1935
|
-
if (bodyClean.replace(/[^\d]/g, "").includes(selfDigits)) return true;
|
|
1936
|
-
const bodyNoSpace = msg.payload.body.replace(/[\s-]/g, "");
|
|
1937
|
-
if (new RegExp(`\\+?${selfDigits}`, "i").test(bodyNoSpace)) return true;
|
|
1938
|
-
}
|
|
1939
|
-
}
|
|
1940
|
-
return false;
|
|
1941
|
-
}
|
|
1942
|
-
function debugMention(msg, mentionCfg, authDir) {
|
|
1943
|
-
const mentionTargets = resolveMentionTargets(msg, authDir);
|
|
1944
|
-
return {
|
|
1945
|
-
wasMentioned: isBotMentionedFromTargets(msg, mentionCfg, mentionTargets),
|
|
1946
|
-
details: {
|
|
1947
|
-
from: requireWhatsAppInboundAdmission(msg).conversation.id,
|
|
1948
|
-
body: msg.payload.body,
|
|
1949
|
-
bodyClean: normalizeMentionText(msg.payload.body),
|
|
1950
|
-
mentionedJids: msg.group?.mentions?.jids ?? null,
|
|
1951
|
-
normalizedMentionedJids: mentionTargets.normalizedMentions.length ? mentionTargets.normalizedMentions.map((identity) => getComparableIdentityValues(identity)) : null,
|
|
1952
|
-
selfJid: msg.platform.self?.jid ?? msg.platform.selfJid ?? null,
|
|
1953
|
-
selfLid: msg.platform.self?.lid ?? msg.platform.selfLid ?? null,
|
|
1954
|
-
selfE164: msg.platform.self?.e164 ?? msg.platform.selfE164 ?? null,
|
|
1955
|
-
resolvedSelf: mentionTargets.self
|
|
1956
|
-
}
|
|
1957
|
-
};
|
|
1958
|
-
}
|
|
1959
|
-
function resolveOwnerList(mentionCfg, selfE164) {
|
|
1960
|
-
const allowFrom = mentionCfg.allowFrom;
|
|
1961
|
-
return (Array.isArray(allowFrom) && allowFrom.length > 0 ? allowFrom : selfE164 ? [selfE164] : []).filter((entry) => Boolean(entry && entry !== "*")).map((entry) => normalizeE164(entry)).filter((entry) => Boolean(entry));
|
|
1962
|
-
}
|
|
1963
|
-
//#endregion
|
|
1964
1882
|
//#region extensions/whatsapp/src/auto-reply/monitor-state.ts
|
|
1965
1883
|
const LIFECYCLE_BY_HEALTH_STATE = {
|
|
1966
1884
|
starting: "starting",
|
|
@@ -2102,6 +2020,76 @@ function formatWhatsAppInboundListeningLog(account) {
|
|
|
2102
2020
|
return `Listening for WhatsApp inbound messages (DM + ${explicitGroupCount} configured ${explicitGroupCount === 1 ? "group" : "groups"}).`;
|
|
2103
2021
|
}
|
|
2104
2022
|
//#endregion
|
|
2023
|
+
//#region src/channels/mention-gating.ts
|
|
2024
|
+
function resolveBotThreadMentionPolicy(params) {
|
|
2025
|
+
if (!params.isBotOwnedThread || params.requireMentionInBotThreads === void 0) return {
|
|
2026
|
+
requireMention: params.requireMention,
|
|
2027
|
+
implicitMentionKinds: params.implicitMentionKinds
|
|
2028
|
+
};
|
|
2029
|
+
return {
|
|
2030
|
+
requireMention: params.requireMentionInBotThreads,
|
|
2031
|
+
implicitMentionKinds: params.requireMentionInBotThreads ? params.implicitMentionKinds?.filter((kind) => kind === "native") : params.implicitMentionKinds
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
2034
|
+
//#endregion
|
|
2035
|
+
//#region \0openclaw:bundled-sdk:openclaw/plugin-sdk/channel-mention-gating
|
|
2036
|
+
var channel_mention_gating_exports = /* @__PURE__ */ __exportAll({ resolveBotThreadMentionPolicy: () => resolveBotThreadMentionPolicy });
|
|
2037
|
+
import * as import_openclaw_plugin_sdk_channel_mention_gating from "openclaw/plugin-sdk/channel-mention-gating";
|
|
2038
|
+
__reExport(channel_mention_gating_exports, import_openclaw_plugin_sdk_channel_mention_gating);
|
|
2039
|
+
//#endregion
|
|
2040
|
+
//#region extensions/whatsapp/src/auto-reply/mentions.ts
|
|
2041
|
+
function buildMentionConfig(cfg, agentId, options) {
|
|
2042
|
+
return {
|
|
2043
|
+
mentionRegexes: (0, channel_mention_gating_exports.buildMentionRegexes)(cfg, agentId, options),
|
|
2044
|
+
allowFrom: cfg.channels?.whatsapp?.allowFrom
|
|
2045
|
+
};
|
|
2046
|
+
}
|
|
2047
|
+
function isBotMentionedFromTargets(msg, mentionCfg, targets) {
|
|
2048
|
+
const explicitSelfChatOverride = typeof mentionCfg.isSelfChat === "boolean";
|
|
2049
|
+
const isGroupConversation = requireWhatsAppInboundAdmission(msg).conversation.kind === "group";
|
|
2050
|
+
const isSelfChat = explicitSelfChatOverride ? Boolean(mentionCfg.isSelfChat) : isSelfChatMode(targets.self.e164, mentionCfg.allowFrom) && !isGroupConversation;
|
|
2051
|
+
const hasNativeMentionsOutsideSelfChat = targets.normalizedMentions.length > 0 && !isSelfChat;
|
|
2052
|
+
if (hasNativeMentionsOutsideSelfChat) {
|
|
2053
|
+
for (const mention of targets.normalizedMentions) if (identitiesOverlap(targets.self, mention)) return true;
|
|
2054
|
+
}
|
|
2055
|
+
const bodyClean = (0, channel_mention_gating_exports.normalizeMentionText)(msg.payload.body);
|
|
2056
|
+
if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean))) return true;
|
|
2057
|
+
if (hasNativeMentionsOutsideSelfChat) return false;
|
|
2058
|
+
if (targets.self.e164) {
|
|
2059
|
+
const selfDigits = targets.self.e164.replace(/\D/g, "");
|
|
2060
|
+
if (selfDigits) {
|
|
2061
|
+
if (bodyClean.replace(/[^\d]/g, "").includes(selfDigits)) return true;
|
|
2062
|
+
const bodyNoSpace = msg.payload.body.replace(/[\s-]/g, "");
|
|
2063
|
+
if (new RegExp(`\\+?${selfDigits}`, "i").test(bodyNoSpace)) return true;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
return false;
|
|
2067
|
+
}
|
|
2068
|
+
function debugMention(msg, mentionCfg, authDir) {
|
|
2069
|
+
const mentionTargets = {
|
|
2070
|
+
normalizedMentions: getMentionIdentities(msg, authDir),
|
|
2071
|
+
self: getSelfIdentity(msg, authDir)
|
|
2072
|
+
};
|
|
2073
|
+
return {
|
|
2074
|
+
wasMentioned: isBotMentionedFromTargets(msg, mentionCfg, mentionTargets),
|
|
2075
|
+
details: {
|
|
2076
|
+
from: requireWhatsAppInboundAdmission(msg).conversation.id,
|
|
2077
|
+
body: msg.payload.body,
|
|
2078
|
+
bodyClean: (0, channel_mention_gating_exports.normalizeMentionText)(msg.payload.body),
|
|
2079
|
+
mentionedJids: msg.group?.mentions?.jids ?? null,
|
|
2080
|
+
normalizedMentionedJids: mentionTargets.normalizedMentions.length ? mentionTargets.normalizedMentions.map((identity) => getComparableIdentityValues(identity)) : null,
|
|
2081
|
+
selfJid: msg.platform.self?.jid ?? msg.platform.selfJid ?? null,
|
|
2082
|
+
selfLid: msg.platform.self?.lid ?? msg.platform.selfLid ?? null,
|
|
2083
|
+
selfE164: msg.platform.self?.e164 ?? msg.platform.selfE164 ?? null,
|
|
2084
|
+
resolvedSelf: mentionTargets.self
|
|
2085
|
+
}
|
|
2086
|
+
};
|
|
2087
|
+
}
|
|
2088
|
+
function resolveOwnerList(mentionCfg, selfE164) {
|
|
2089
|
+
const allowFrom = mentionCfg.allowFrom;
|
|
2090
|
+
return (Array.isArray(allowFrom) && allowFrom.length > 0 ? allowFrom : selfE164 ? [selfE164] : []).filter((entry) => Boolean(entry && entry !== "*")).map((entry) => normalizeE164(entry)).filter((entry) => Boolean(entry));
|
|
2091
|
+
}
|
|
2092
|
+
//#endregion
|
|
2105
2093
|
//#region extensions/whatsapp/src/auto-reply/monitor/ack-emoji.ts
|
|
2106
2094
|
const DEFAULT_WHATSAPP_ACK_REACTION = "👀";
|
|
2107
2095
|
function resolveWhatsAppAckEmoji(params) {
|
|
@@ -2218,13 +2206,7 @@ async function resolveWhatsAppReactionEligibility(params) {
|
|
|
2218
2206
|
//#endregion
|
|
2219
2207
|
//#region extensions/whatsapp/src/auto-reply/monitor/ack-reaction.ts
|
|
2220
2208
|
async function maybeSendAckReaction(params) {
|
|
2221
|
-
const eligibility = await resolveWhatsAppReactionEligibility(
|
|
2222
|
-
cfg: params.cfg,
|
|
2223
|
-
msg: params.msg,
|
|
2224
|
-
agentId: params.agentId,
|
|
2225
|
-
sessionKey: params.sessionKey,
|
|
2226
|
-
verbose: params.verbose
|
|
2227
|
-
});
|
|
2209
|
+
const eligibility = await resolveWhatsAppReactionEligibility(params);
|
|
2228
2210
|
if (eligibility.status === "disabled") return null;
|
|
2229
2211
|
const { chatId, messageId, emoji, reactionOptions } = eligibility;
|
|
2230
2212
|
params.info({
|
|
@@ -2247,6 +2229,33 @@ async function maybeSendAckReaction(params) {
|
|
|
2247
2229
|
});
|
|
2248
2230
|
}
|
|
2249
2231
|
//#endregion
|
|
2232
|
+
//#region extensions/whatsapp/src/auto-reply/monitor/audio-preflight.ts
|
|
2233
|
+
function hasWhatsAppAudioBody(msg) {
|
|
2234
|
+
return (msg.payload.media?.kind === "audio" || msg.payload.media?.type?.startsWith("audio/") === true) && !msg.payload.body.trim();
|
|
2235
|
+
}
|
|
2236
|
+
async function transcribeWhatsAppAudioMessage(cfg, msg, accountId) {
|
|
2237
|
+
const { transcribeFirstAudio } = await import("./audio-preflight.runtime-C_glQhZY.mjs");
|
|
2238
|
+
const media = msg.payload.media;
|
|
2239
|
+
const conversationId = msg.admission.conversation.id;
|
|
2240
|
+
return await transcribeFirstAudio({
|
|
2241
|
+
ctx: {
|
|
2242
|
+
media: [{
|
|
2243
|
+
path: media?.path,
|
|
2244
|
+
contentType: media?.type,
|
|
2245
|
+
kind: media?.kind ?? void 0
|
|
2246
|
+
}],
|
|
2247
|
+
From: conversationId,
|
|
2248
|
+
To: msg.platform.recipientJid,
|
|
2249
|
+
Provider: "whatsapp",
|
|
2250
|
+
Surface: "whatsapp",
|
|
2251
|
+
OriginatingChannel: "whatsapp",
|
|
2252
|
+
OriginatingTo: conversationId,
|
|
2253
|
+
AccountId: accountId
|
|
2254
|
+
},
|
|
2255
|
+
cfg
|
|
2256
|
+
});
|
|
2257
|
+
}
|
|
2258
|
+
//#endregion
|
|
2250
2259
|
//#region extensions/whatsapp/src/auto-reply/monitor/broadcast.ts
|
|
2251
2260
|
function buildBroadcastRouteKeys(params) {
|
|
2252
2261
|
const admission = requireWhatsAppInboundAdmission(params.msg);
|
|
@@ -2378,11 +2387,8 @@ const groupDropWarned = createDedupeCache({
|
|
|
2378
2387
|
ttlMs: 0,
|
|
2379
2388
|
maxSize: 100
|
|
2380
2389
|
});
|
|
2381
|
-
function shouldWarnForGroupDrop(warnKey) {
|
|
2382
|
-
return !groupDropWarned.check(warnKey);
|
|
2383
|
-
}
|
|
2384
2390
|
function isOwnerSender(baseMentionConfig, msg, authDir) {
|
|
2385
|
-
const sender = normalizeE164(getSenderIdentity(msg, authDir).e164 ?? "");
|
|
2391
|
+
const sender = normalizeE164$2(getSenderIdentity(msg, authDir).e164 ?? "");
|
|
2386
2392
|
if (!sender) return false;
|
|
2387
2393
|
return resolveOwnerList(baseMentionConfig, getSelfIdentity(msg, authDir).e164 ?? void 0).includes(sender);
|
|
2388
2394
|
}
|
|
@@ -2431,11 +2437,12 @@ async function applyGroupGating(params) {
|
|
|
2431
2437
|
const conversationGroupPolicy = inboundPolicy.resolveConversationGroupPolicy(conversationId);
|
|
2432
2438
|
if (conversationGroupPolicy.allowlistEnabled && !conversationGroupPolicy.allowed) {
|
|
2433
2439
|
const accountId = inboundPolicy.account.accountId;
|
|
2434
|
-
|
|
2440
|
+
const warnKey = JSON.stringify([
|
|
2435
2441
|
accountId,
|
|
2436
2442
|
conversationId,
|
|
2437
2443
|
"group registry"
|
|
2438
|
-
])
|
|
2444
|
+
]);
|
|
2445
|
+
if (!groupDropWarned.check(warnKey)) {
|
|
2439
2446
|
const groupsPath = resolveWhatsAppGroupsConfigPath({
|
|
2440
2447
|
cfg: params.cfg,
|
|
2441
2448
|
accountId
|
|
@@ -2462,17 +2469,11 @@ async function applyGroupGating(params) {
|
|
|
2462
2469
|
}),
|
|
2463
2470
|
allowFrom: inboundPolicy.configuredAllowFrom
|
|
2464
2471
|
};
|
|
2465
|
-
const mentionMsg =
|
|
2466
|
-
...params.msg,
|
|
2467
|
-
payload: {
|
|
2468
|
-
...params.msg.payload,
|
|
2469
|
-
body: params.mentionText
|
|
2470
|
-
}
|
|
2471
|
-
} : {
|
|
2472
|
+
const mentionMsg = {
|
|
2472
2473
|
...params.msg,
|
|
2473
2474
|
payload: {
|
|
2474
2475
|
...params.msg.payload,
|
|
2475
|
-
body: params.msg.payload.commandBody ?? params.msg.payload.body
|
|
2476
|
+
body: params.mentionText ?? params.msg.payload.commandBody ?? params.msg.payload.body
|
|
2476
2477
|
}
|
|
2477
2478
|
};
|
|
2478
2479
|
const commandBody = stripMentionsForCommand(mentionMsg.payload.body, mentionConfig.mentionRegexes, self.e164);
|
|
@@ -2496,8 +2497,8 @@ async function applyGroupGating(params) {
|
|
|
2496
2497
|
}) !== "always";
|
|
2497
2498
|
const replyContext = getReplyContext(params.msg, params.authDir);
|
|
2498
2499
|
const implicitReplyToSelf = params.selfChatMode === true && identitiesOverlap(self, sender);
|
|
2499
|
-
const implicitMentionKinds = implicitMentionKindWhen("quoted_bot", !implicitReplyToSelf && identitiesOverlap(self, replyContext?.sender));
|
|
2500
|
-
const mentionDecision = resolveInboundMentionDecision({
|
|
2500
|
+
const implicitMentionKinds = (0, channel_mention_gating_exports.implicitMentionKindWhen)("quoted_bot", !implicitReplyToSelf && identitiesOverlap(self, replyContext?.sender));
|
|
2501
|
+
const mentionDecision = (0, channel_mention_gating_exports.resolveInboundMentionDecision)({
|
|
2501
2502
|
facts: {
|
|
2502
2503
|
canDetectMention: true,
|
|
2503
2504
|
wasMentioned,
|
|
@@ -2525,7 +2526,7 @@ async function applyGroupGating(params) {
|
|
|
2525
2526
|
};
|
|
2526
2527
|
}
|
|
2527
2528
|
const accountId = inboundPolicy.account.accountId;
|
|
2528
|
-
if (
|
|
2529
|
+
if (!groupDropWarned.check(JSON.stringify([
|
|
2529
2530
|
accountId,
|
|
2530
2531
|
conversationId,
|
|
2531
2532
|
"no mention"
|
|
@@ -2682,15 +2683,12 @@ function isLikelyWhatsAppCryptoError(reason) {
|
|
|
2682
2683
|
} catch {
|
|
2683
2684
|
return Object.prototype.toString.call(value);
|
|
2684
2685
|
}
|
|
2685
|
-
if (typeof value === "number") return String(value);
|
|
2686
|
-
if (typeof value === "boolean") return String(value);
|
|
2687
|
-
if (typeof value === "bigint") return String(value);
|
|
2686
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
|
|
2688
2687
|
if (typeof value === "symbol") return value.description ?? value.toString();
|
|
2689
2688
|
if (typeof value === "function") return value.name ? `[function ${value.name}]` : "[function]";
|
|
2690
2689
|
return Object.prototype.toString.call(value);
|
|
2691
2690
|
};
|
|
2692
|
-
const
|
|
2693
|
-
const haystack = normalizeLowercaseStringOrEmpty(raw);
|
|
2691
|
+
const haystack = normalizeLowercaseStringOrEmpty(formatReason(reason));
|
|
2694
2692
|
if (!(haystack.includes("unsupported state or unable to authenticate data") || haystack.includes("bad mac"))) return false;
|
|
2695
2693
|
return haystack.includes("baileys") || haystack.includes("noise-handler") || haystack.includes("aesdecryptgcm");
|
|
2696
2694
|
}
|
|
@@ -2920,7 +2918,6 @@ async function deliverWebReplyInActivityScope(params) {
|
|
|
2920
2918
|
return;
|
|
2921
2919
|
}
|
|
2922
2920
|
const fallbackText = [caption ?? "", "⚠️ Media failed."].filter(Boolean).join("\n");
|
|
2923
|
-
if (!fallbackText) return;
|
|
2924
2921
|
whatsappOutboundLog.warn(`Media skipped; sent text-only to ${conversationId}`);
|
|
2925
2922
|
rememberSendResult(await sendWithRetry(() => transport.reply(fallbackText, getQuote()), "media:fallback-text", "text"));
|
|
2926
2923
|
}
|
|
@@ -3055,9 +3052,6 @@ function normalizeErrForLog(err) {
|
|
|
3055
3052
|
};
|
|
3056
3053
|
return err;
|
|
3057
3054
|
}
|
|
3058
|
-
function whatsAppReplyDeliveryVisibility(visibleReplySent) {
|
|
3059
|
-
return { visibleReplySent };
|
|
3060
|
-
}
|
|
3061
3055
|
function createWhatsAppChannelDeliveryResult(params) {
|
|
3062
3056
|
const messageIds = listMessageReceiptPlatformIds(params.delivery.receipt);
|
|
3063
3057
|
return {
|
|
@@ -3144,18 +3138,13 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
|
|
|
3144
3138
|
};
|
|
3145
3139
|
return {
|
|
3146
3140
|
defer(pending) {
|
|
3147
|
-
|
|
3148
|
-
let rejectFinalization;
|
|
3149
|
-
const finalization = new Promise((resolve, reject) => {
|
|
3150
|
-
resolveFinalization = resolve;
|
|
3151
|
-
rejectFinalization = reject;
|
|
3152
|
-
});
|
|
3141
|
+
const finalization = createDeferred();
|
|
3153
3142
|
pendingMediaOnlyPayloads.push({
|
|
3154
3143
|
...pending,
|
|
3155
|
-
resolveFinalization,
|
|
3156
|
-
rejectFinalization
|
|
3144
|
+
resolveFinalization: finalization.resolve,
|
|
3145
|
+
rejectFinalization: finalization.reject
|
|
3157
3146
|
});
|
|
3158
|
-
return finalization;
|
|
3147
|
+
return finalization.promise;
|
|
3159
3148
|
},
|
|
3160
3149
|
flushNonDuplicateMedia: (mediaUrls) => flushWhere((pending) => !hasWhatsAppMediaUrlOverlap(pending.mediaUrls, mediaUrls)),
|
|
3161
3150
|
supersedeMedia(mediaUrl) {
|
|
@@ -3175,7 +3164,7 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
|
|
|
3175
3164
|
};
|
|
3176
3165
|
}
|
|
3177
3166
|
if (pending.mediaUrls.size === 0) {
|
|
3178
|
-
pending.resolveFinalization(
|
|
3167
|
+
pending.resolveFinalization({ visibleReplySent: false });
|
|
3179
3168
|
continue;
|
|
3180
3169
|
}
|
|
3181
3170
|
retained.push(pending);
|
|
@@ -3366,7 +3355,7 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3366
3355
|
};
|
|
3367
3356
|
const deliverNormalizedPayload = async (normalizedDeliveryPayload, info, options) => {
|
|
3368
3357
|
const reply = resolveSendableOutboundReplyParts(normalizedDeliveryPayload);
|
|
3369
|
-
if (!reply.hasMedia && !reply.text.trim()) return
|
|
3358
|
+
if (!reply.hasMedia && !reply.text.trim()) return { visibleReplySent: false };
|
|
3370
3359
|
let delivery;
|
|
3371
3360
|
try {
|
|
3372
3361
|
delivery = await params.deliverReply({
|
|
@@ -3427,7 +3416,7 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3427
3416
|
onSettled: async () => {
|
|
3428
3417
|
const flushResult = await mediaOnlyCoalescer.flushAll();
|
|
3429
3418
|
logWhatsAppMediaOnlyFlushResult(flushResult);
|
|
3430
|
-
return
|
|
3419
|
+
return { visibleReplySent: didSendReply || flushResult.delivered > 0 };
|
|
3431
3420
|
},
|
|
3432
3421
|
onReplyStart: params.transport.sendComposing
|
|
3433
3422
|
},
|
|
@@ -3475,7 +3464,7 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3475
3464
|
deliver: async (payload, info) => {
|
|
3476
3465
|
const normalizedDeliveryPayload = payload;
|
|
3477
3466
|
const reply = resolveSendableOutboundReplyParts(normalizedDeliveryPayload);
|
|
3478
|
-
if (!reply.hasMedia && !reply.text.trim()) return
|
|
3467
|
+
if (!reply.hasMedia && !reply.text.trim()) return { visibleReplySent: false };
|
|
3479
3468
|
if (!reply.hasMedia) return await deliverNormalizedPayload(normalizedDeliveryPayload, info, { recordDelivery: false });
|
|
3480
3469
|
const mediaUrls = new Set(normalizedDeliveryPayload.mediaUrls);
|
|
3481
3470
|
if (shouldDeferWhatsAppMediaOnlyPayload({
|
|
@@ -3536,20 +3525,11 @@ function createWhatsAppReplyPlan(params) {
|
|
|
3536
3525
|
finalize: (dispatchResult) => {
|
|
3537
3526
|
const didQueueVisibleReply = hasVisibleInboundReplyDispatch(dispatchResult);
|
|
3538
3527
|
const didDeliverVisibleReply = didSendReply || dispatchResult.observedReplyDelivery === true;
|
|
3539
|
-
if (!didQueueVisibleReply && !didDeliverVisibleReply) {
|
|
3540
|
-
if (statusReactionController) finalizeWhatsAppStatusReaction({
|
|
3541
|
-
controller: statusReactionController,
|
|
3542
|
-
outcome: "error"
|
|
3543
|
-
});
|
|
3544
|
-
if (params.shouldClearGroupHistory) params.groupHistories.set(params.groupHistoryKey, []);
|
|
3545
|
-
logVerbose$1("Skipping auto-reply: silent token or no text/media returned from resolver");
|
|
3546
|
-
return false;
|
|
3547
|
-
}
|
|
3548
3528
|
if (statusReactionController) finalizeWhatsAppStatusReaction({
|
|
3549
3529
|
controller: statusReactionController,
|
|
3550
3530
|
outcome: readAgentRunTerminalOutcome(dispatchResult) === "failed" || !didDeliverVisibleReply ? "error" : "done"
|
|
3551
3531
|
});
|
|
3552
|
-
if (
|
|
3532
|
+
if (!didQueueVisibleReply && !didDeliverVisibleReply) logVerbose$1("Skipping auto-reply: silent token or no text/media returned from resolver");
|
|
3553
3533
|
return didDeliverVisibleReply;
|
|
3554
3534
|
}
|
|
3555
3535
|
};
|
|
@@ -3565,15 +3545,12 @@ function formatReplyTarget(replyTo) {
|
|
|
3565
3545
|
if (!replyTo?.body) return null;
|
|
3566
3546
|
return `[Replying to ${replyTo.sender?.label ?? replyTo.sender?.e164 ?? "unknown sender"}${replyTo.id ? ` id:${replyTo.id}` : ""}]\n${replyTo.body}\n[/Replying]`;
|
|
3567
3547
|
}
|
|
3568
|
-
function formatReplyContext(msg) {
|
|
3569
|
-
return formatReplyTarget(getReplyContext(msg));
|
|
3570
|
-
}
|
|
3571
3548
|
function buildInboundLine(params) {
|
|
3572
3549
|
const { msg, previousTimestamp, envelope } = params;
|
|
3573
3550
|
const admission = requireWhatsAppInboundAdmission(msg);
|
|
3574
3551
|
const conversationId = admission.conversation.id;
|
|
3575
3552
|
const conversationKind = admission.conversation.kind;
|
|
3576
|
-
const replyContext = params.visibleReplyTo === void 0 ?
|
|
3553
|
+
const replyContext = formatReplyTarget(params.visibleReplyTo === void 0 ? getReplyContext(msg) : params.visibleReplyTo);
|
|
3577
3554
|
const baseLine = `${msg.payload.body}${replyContext ? `\n\n${replyContext}` : ""}`;
|
|
3578
3555
|
const sender = getSenderIdentity(msg);
|
|
3579
3556
|
return formatInboundEnvelope({
|
|
@@ -3597,13 +3574,7 @@ function buildInboundLine(params) {
|
|
|
3597
3574
|
async function createWhatsAppStatusReactionController(params) {
|
|
3598
3575
|
if (!params.msg.event.id) return null;
|
|
3599
3576
|
if ((params.cfg.messages?.statusReactions)?.enabled !== true) return null;
|
|
3600
|
-
const eligibility = await resolveWhatsAppReactionEligibility(
|
|
3601
|
-
cfg: params.cfg,
|
|
3602
|
-
msg: params.msg,
|
|
3603
|
-
agentId: params.agentId,
|
|
3604
|
-
sessionKey: params.sessionKey,
|
|
3605
|
-
verbose: params.verbose
|
|
3606
|
-
});
|
|
3577
|
+
const eligibility = await resolveWhatsAppReactionEligibility(params);
|
|
3607
3578
|
if (eligibility.status === "disabled") return null;
|
|
3608
3579
|
const { chatId, messageId, emoji: initialEmoji, reactionOptions } = eligibility;
|
|
3609
3580
|
return createStatusReactionController({
|
|
@@ -3630,39 +3601,37 @@ const WHATSAPP_MESSAGE_RECEIVED_HOOK_LIMITS = {
|
|
|
3630
3601
|
maxQueue: 128,
|
|
3631
3602
|
timeoutMs: 2e3
|
|
3632
3603
|
};
|
|
3633
|
-
function
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3604
|
+
function mapWhatsAppIngressToTurnAdmission(ingress) {
|
|
3605
|
+
const reason = ingress.reasonCode;
|
|
3606
|
+
if (ingress.admission === "dispatch") return {
|
|
3607
|
+
kind: "dispatch",
|
|
3608
|
+
reason
|
|
3609
|
+
};
|
|
3610
|
+
if (ingress.admission === "observe") return {
|
|
3611
|
+
kind: "observeOnly",
|
|
3612
|
+
reason
|
|
3613
|
+
};
|
|
3614
|
+
if (ingress.admission === "skip") return {
|
|
3615
|
+
kind: "handled",
|
|
3616
|
+
reason
|
|
3617
|
+
};
|
|
3618
|
+
return {
|
|
3619
|
+
kind: "drop",
|
|
3620
|
+
reason,
|
|
3621
|
+
recordHistory: false
|
|
3622
|
+
};
|
|
3638
3623
|
}
|
|
3639
3624
|
function shouldEmitWhatsAppMessageReceivedHooks(params) {
|
|
3640
3625
|
const channelConfig = params.cfg.channels?.whatsapp;
|
|
3641
|
-
return
|
|
3626
|
+
return (params.accountId ? channelConfig?.accounts?.[params.accountId] : void 0)?.pluginHooks?.messageReceived ?? channelConfig?.pluginHooks?.messageReceived ?? false;
|
|
3642
3627
|
}
|
|
3643
|
-
function
|
|
3628
|
+
function emitWhatsAppMessageReceivedHooksIfEnabled(params) {
|
|
3629
|
+
if (!shouldEmitWhatsAppMessageReceivedHooks(params)) return;
|
|
3644
3630
|
const canonical = deriveInboundMessageHookContext(params.ctx);
|
|
3645
3631
|
const hookRunner = getGlobalHookRunner();
|
|
3646
3632
|
if (hookRunner?.hasHooks("message_received")) fireAndForgetBoundedHook(() => hookRunner.runMessageReceived(toPluginMessageReceivedEvent(canonical), toPluginMessageContext(canonical)), "whatsapp: message_received plugin hook failed", void 0, WHATSAPP_MESSAGE_RECEIVED_HOOK_LIMITS);
|
|
3647
3633
|
fireAndForgetBoundedHook(() => triggerInternalHook(createInternalHookEvent("message", "received", params.sessionKey, toInternalMessageReceivedContext(canonical))), "whatsapp: message_received internal hook failed", void 0, WHATSAPP_MESSAGE_RECEIVED_HOOK_LIMITS);
|
|
3648
3634
|
}
|
|
3649
|
-
function emitWhatsAppMessageReceivedHooksIfEnabled(params) {
|
|
3650
|
-
if (!shouldEmitWhatsAppMessageReceivedHooks({
|
|
3651
|
-
cfg: params.cfg,
|
|
3652
|
-
accountId: params.accountId
|
|
3653
|
-
})) return;
|
|
3654
|
-
emitWhatsAppMessageReceivedHooks({
|
|
3655
|
-
ctx: params.ctx,
|
|
3656
|
-
sessionKey: params.sessionKey
|
|
3657
|
-
});
|
|
3658
|
-
}
|
|
3659
|
-
function resolvePinnedMainDmRecipient(params) {
|
|
3660
|
-
return resolvePinnedMainDmOwnerFromAllowlist({
|
|
3661
|
-
dmScope: params.cfg.session?.dmScope,
|
|
3662
|
-
allowFrom: params.allowFrom,
|
|
3663
|
-
normalizeEntry: (entry) => normalizeE164(entry)
|
|
3664
|
-
});
|
|
3665
|
-
}
|
|
3666
3635
|
async function processMessage(params) {
|
|
3667
3636
|
const admission = requireWhatsAppInboundAdmission(params.msg);
|
|
3668
3637
|
if (admission.ingress.admission !== "dispatch" && admission.ingress.admission !== "observe") return false;
|
|
@@ -3686,26 +3655,8 @@ async function processMessage(params) {
|
|
|
3686
3655
|
sessionKey: params.route.sessionKey
|
|
3687
3656
|
});
|
|
3688
3657
|
let audioTranscript = params.preflightAudioTranscript ?? void 0;
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
const { transcribeFirstAudio } = await import("./audio-preflight.runtime-C_glQhZY.mjs");
|
|
3692
|
-
audioTranscript = await transcribeFirstAudio({
|
|
3693
|
-
ctx: {
|
|
3694
|
-
media: [{
|
|
3695
|
-
path: params.msg.payload.media.path,
|
|
3696
|
-
contentType: params.msg.payload.media.type,
|
|
3697
|
-
kind: params.msg.payload.media.kind ?? void 0
|
|
3698
|
-
}],
|
|
3699
|
-
From: conversationId,
|
|
3700
|
-
To: params.msg.platform.recipientJid,
|
|
3701
|
-
Provider: "whatsapp",
|
|
3702
|
-
Surface: "whatsapp",
|
|
3703
|
-
OriginatingChannel: "whatsapp",
|
|
3704
|
-
OriginatingTo: conversationId,
|
|
3705
|
-
AccountId: params.route.accountId
|
|
3706
|
-
},
|
|
3707
|
-
cfg: params.cfg
|
|
3708
|
-
});
|
|
3658
|
+
if (params.preflightAudioTranscript === void 0 && hasWhatsAppAudioBody(params.msg) && params.msg.payload.media?.path) try {
|
|
3659
|
+
audioTranscript = await transcribeWhatsAppAudioMessage(params.cfg, params.msg, params.route.accountId);
|
|
3709
3660
|
} catch {
|
|
3710
3661
|
if (shouldLogVerbose$1()) logVerbose$1("whatsapp: audio preflight transcription failed, keeping structured audio");
|
|
3711
3662
|
}
|
|
@@ -3729,7 +3680,6 @@ async function processMessage(params) {
|
|
|
3729
3680
|
envelope: envelopeOptions,
|
|
3730
3681
|
visibleReplyTo
|
|
3731
3682
|
});
|
|
3732
|
-
let shouldClearGroupHistory = false;
|
|
3733
3683
|
const visibleGroupHistory = conversationKind === "group" ? resolveVisibleWhatsAppGroupHistory({
|
|
3734
3684
|
history: params.groupHistory ?? params.groupHistories.get(params.groupHistoryKey) ?? [],
|
|
3735
3685
|
mode: contextVisibilityMode,
|
|
@@ -3763,7 +3713,6 @@ async function processMessage(params) {
|
|
|
3763
3713
|
}
|
|
3764
3714
|
});
|
|
3765
3715
|
}
|
|
3766
|
-
shouldClearGroupHistory = !(params.suppressGroupHistoryClear ?? false);
|
|
3767
3716
|
}
|
|
3768
3717
|
const statusReactionController = params.statusReactionController ?? (params.cfg.messages?.statusReactions?.enabled === true && !params.ackAlreadySent ? await createWhatsAppStatusReactionController({
|
|
3769
3718
|
cfg: params.cfg,
|
|
@@ -3793,16 +3742,15 @@ async function processMessage(params) {
|
|
|
3793
3742
|
mediaType: params.msg.payload.media?.type ?? null,
|
|
3794
3743
|
mediaPath: params.msg.payload.media?.path ?? null
|
|
3795
3744
|
}, "inbound web message");
|
|
3796
|
-
const fromDisplay = conversationId;
|
|
3797
3745
|
const kindLabel = params.msg.payload.media?.type ? `, ${params.msg.payload.media?.type}` : "";
|
|
3798
|
-
whatsappInboundLog.info(`Inbound message ${
|
|
3746
|
+
whatsappInboundLog.info(`Inbound message ${conversationId} -> ${params.msg.platform.recipientJid} (${conversationKind}${kindLabel}, ${combinedBody.length} chars)`);
|
|
3799
3747
|
if (shouldLogVerbose$1()) whatsappInboundLog.debug(`Inbound body: ${elide(combinedBody, 400)}`);
|
|
3800
3748
|
const sender = getSenderIdentity(params.msg);
|
|
3801
3749
|
const commandBody = params.msg.payload.commandBody ?? params.msg.payload.body;
|
|
3802
3750
|
const dmRouteTarget = resolveWhatsAppDmRouteTarget({
|
|
3803
3751
|
msg: params.msg,
|
|
3804
3752
|
senderE164: sender.e164 ?? void 0,
|
|
3805
|
-
normalizeE164
|
|
3753
|
+
normalizeE164: normalizeE164$1
|
|
3806
3754
|
});
|
|
3807
3755
|
const shouldCheckCommandAuth = shouldComputeCommandAuthorized(commandBody, params.cfg);
|
|
3808
3756
|
const isTextCommand = isControlCommandMessage(commandBody, params.cfg);
|
|
@@ -3860,6 +3808,8 @@ async function processMessage(params) {
|
|
|
3860
3808
|
visibleReplyTo: visibleReplyTo ?? void 0,
|
|
3861
3809
|
suppressMessageReceivedHooks: true
|
|
3862
3810
|
});
|
|
3811
|
+
const turnAdmission = mapWhatsAppIngressToTurnAdmission(inbound.channelIngress?.ingress ?? admission.ingress);
|
|
3812
|
+
const shouldClearGroupHistory = conversationKind === "group" && params.suppressGroupHistoryClear !== true;
|
|
3863
3813
|
const transport = buildWhatsAppInboundTransportContext(params.msg);
|
|
3864
3814
|
const ingressLifecycle = resolveWhatsAppIngressLifecycle(params.msg);
|
|
3865
3815
|
const turnAdoptionLifecycle = ingressLifecycle ? bindIngressLifecycleToReplyOptions(ingressLifecycle).turnAdoptionLifecycle : void 0;
|
|
@@ -3869,9 +3819,10 @@ async function processMessage(params) {
|
|
|
3869
3819
|
accountId: params.route.accountId,
|
|
3870
3820
|
sessionKey: params.route.sessionKey
|
|
3871
3821
|
});
|
|
3872
|
-
const pinnedMainDmRecipient =
|
|
3873
|
-
|
|
3874
|
-
allowFrom: inboundPolicy.configuredAllowFrom
|
|
3822
|
+
const pinnedMainDmRecipient = resolvePinnedMainDmOwnerFromAllowlist({
|
|
3823
|
+
dmScope: params.cfg.session?.dmScope,
|
|
3824
|
+
allowFrom: inboundPolicy.configuredAllowFrom,
|
|
3825
|
+
normalizeEntry: normalizeE164$1
|
|
3875
3826
|
});
|
|
3876
3827
|
updateWhatsAppMainLastRoute({
|
|
3877
3828
|
backgroundTasks: params.backgroundTasks,
|
|
@@ -3891,25 +3842,9 @@ async function processMessage(params) {
|
|
|
3891
3842
|
...turnAdoptionLifecycle ? { turnAdoptionLifecycle } : {},
|
|
3892
3843
|
adapter: {
|
|
3893
3844
|
ingest: () => turnInput,
|
|
3894
|
-
preflight: () => {
|
|
3895
|
-
|
|
3896
|
-
if (
|
|
3897
|
-
kind: "dispatch",
|
|
3898
|
-
reason
|
|
3899
|
-
} };
|
|
3900
|
-
if (admission.ingress.admission === "observe") return { admission: {
|
|
3901
|
-
kind: "observeOnly",
|
|
3902
|
-
reason
|
|
3903
|
-
} };
|
|
3904
|
-
if (admission.ingress.admission === "skip") return { admission: {
|
|
3905
|
-
kind: "handled",
|
|
3906
|
-
reason
|
|
3907
|
-
} };
|
|
3908
|
-
return { admission: {
|
|
3909
|
-
kind: "drop",
|
|
3910
|
-
reason,
|
|
3911
|
-
recordHistory: false
|
|
3912
|
-
} };
|
|
3845
|
+
preflight: () => ({ admission: turnAdmission }),
|
|
3846
|
+
onFinalize: (result) => {
|
|
3847
|
+
if (result.dispatched && turnAdmission.kind === "dispatch" && shouldClearGroupHistory) params.groupHistories.set(params.groupHistoryKey, []);
|
|
3913
3848
|
},
|
|
3914
3849
|
resolveTurn: () => {
|
|
3915
3850
|
const { finalize, ...replyPlan } = createWhatsAppReplyPlan({
|
|
@@ -3917,8 +3852,6 @@ async function processMessage(params) {
|
|
|
3917
3852
|
connectionId: params.connectionId,
|
|
3918
3853
|
context: ctxPayload,
|
|
3919
3854
|
deliverReply: deliverWebReply,
|
|
3920
|
-
groupHistories: params.groupHistories,
|
|
3921
|
-
groupHistoryKey: params.groupHistoryKey,
|
|
3922
3855
|
maxMediaBytes: params.maxMediaBytes,
|
|
3923
3856
|
maxMediaTextChunkLimit: params.maxMediaTextChunkLimit,
|
|
3924
3857
|
inbound,
|
|
@@ -3930,7 +3863,6 @@ async function processMessage(params) {
|
|
|
3930
3863
|
},
|
|
3931
3864
|
replyResolver: params.replyResolver,
|
|
3932
3865
|
route: params.route,
|
|
3933
|
-
shouldClearGroupHistory,
|
|
3934
3866
|
statusReactionController,
|
|
3935
3867
|
transport,
|
|
3936
3868
|
turnAdoptionLifecycle
|
|
@@ -3981,7 +3913,6 @@ async function processMessage(params) {
|
|
|
3981
3913
|
//#endregion
|
|
3982
3914
|
//#region extensions/whatsapp/src/auto-reply/monitor/on-message.ts
|
|
3983
3915
|
function createWebOnMessageHandler(params) {
|
|
3984
|
-
const hasExplicitlyPassedInboundAccess = (msg) => msg.admission.ingress.decision === "allow";
|
|
3985
3916
|
const withDirectSenderPeer = (msg, peerId) => {
|
|
3986
3917
|
if (requireWhatsAppInboundAdmission(msg).conversation.kind === "group" || msg.platform.sender?.e164 || msg.platform.senderE164 || !peerId.startsWith("+")) return msg;
|
|
3987
3918
|
const normalized = normalizeE164(peerId);
|
|
@@ -3999,7 +3930,7 @@ function createWebOnMessageHandler(params) {
|
|
|
3999
3930
|
};
|
|
4000
3931
|
};
|
|
4001
3932
|
const processForRoute = async (cfg, msg, route, groupHistoryKey, opts) => {
|
|
4002
|
-
|
|
3933
|
+
return processMessage({
|
|
4003
3934
|
cfg,
|
|
4004
3935
|
msg,
|
|
4005
3936
|
route,
|
|
@@ -4014,18 +3945,12 @@ function createWebOnMessageHandler(params) {
|
|
|
4014
3945
|
replyLogger: params.replyLogger,
|
|
4015
3946
|
backgroundTasks: params.backgroundTasks,
|
|
4016
3947
|
buildContext: params.buildContext,
|
|
4017
|
-
dispatchReplyFromConfig: params.dispatchReplyFromConfig
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
if (opts?.suppressGroupHistoryClear !== void 0) processParams.suppressGroupHistoryClear = opts.suppressGroupHistoryClear;
|
|
4021
|
-
if (opts?.preflightAudioTranscript !== void 0) processParams.preflightAudioTranscript = opts.preflightAudioTranscript;
|
|
4022
|
-
if (opts?.ackAlreadySent === true) processParams.ackAlreadySent = true;
|
|
4023
|
-
if (opts?.ackReaction !== void 0) processParams.ackReaction = opts.ackReaction;
|
|
4024
|
-
if (opts?.statusReactionController !== void 0) processParams.statusReactionController = opts.statusReactionController;
|
|
4025
|
-
return processMessage(processParams);
|
|
3948
|
+
dispatchReplyFromConfig: params.dispatchReplyFromConfig,
|
|
3949
|
+
...opts
|
|
3950
|
+
});
|
|
4026
3951
|
};
|
|
4027
3952
|
return async (normalizedMsg) => {
|
|
4028
|
-
const canRunDirectEarlyAudioPreflight =
|
|
3953
|
+
const canRunDirectEarlyAudioPreflight = normalizedMsg.admission.ingress.decision === "allow";
|
|
4029
3954
|
const cfg = params.loadConfig?.() ?? params.cfg;
|
|
4030
3955
|
const peerId = resolvePeerId(normalizedMsg);
|
|
4031
3956
|
const msg = withDirectSenderPeer(normalizedMsg, peerId);
|
|
@@ -4065,7 +3990,7 @@ function createWebOnMessageHandler(params) {
|
|
|
4065
3990
|
peerId
|
|
4066
3991
|
}) : route.sessionKey;
|
|
4067
3992
|
let preflightAudioTranscript;
|
|
4068
|
-
const hasAudioBody = (msg
|
|
3993
|
+
const hasAudioBody = hasWhatsAppAudioBody(msg);
|
|
4069
3994
|
const canRunEarlyAudioPreflight = conversationKind === "group" || canRunDirectEarlyAudioPreflight;
|
|
4070
3995
|
let ackAlreadySent = false;
|
|
4071
3996
|
let ackReaction = null;
|
|
@@ -4088,24 +4013,7 @@ function createWebOnMessageHandler(params) {
|
|
|
4088
4013
|
const transcribeAudioOnce = async () => {
|
|
4089
4014
|
if (preflightAudioTranscript !== void 0 || !hasAudioBody || !msg.payload.media?.path) return;
|
|
4090
4015
|
try {
|
|
4091
|
-
|
|
4092
|
-
preflightAudioTranscript = await transcribeFirstAudio({
|
|
4093
|
-
ctx: {
|
|
4094
|
-
media: [{
|
|
4095
|
-
path: msg.payload.media.path,
|
|
4096
|
-
contentType: msg.payload.media.type,
|
|
4097
|
-
kind: msg.payload.media.kind ?? void 0
|
|
4098
|
-
}],
|
|
4099
|
-
From: conversationId,
|
|
4100
|
-
To: msg.platform.recipientJid,
|
|
4101
|
-
Provider: "whatsapp",
|
|
4102
|
-
Surface: "whatsapp",
|
|
4103
|
-
OriginatingChannel: "whatsapp",
|
|
4104
|
-
OriginatingTo: conversationId,
|
|
4105
|
-
AccountId: route.accountId
|
|
4106
|
-
},
|
|
4107
|
-
cfg
|
|
4108
|
-
}) ?? null;
|
|
4016
|
+
preflightAudioTranscript = await transcribeWhatsAppAudioMessage(cfg, msg, route.accountId) ?? null;
|
|
4109
4017
|
} catch {
|
|
4110
4018
|
preflightAudioTranscript = null;
|
|
4111
4019
|
}
|
|
@@ -4165,10 +4073,9 @@ function createWebOnMessageHandler(params) {
|
|
|
4165
4073
|
warn: params.replyLogger.warn.bind(params.replyLogger)
|
|
4166
4074
|
});
|
|
4167
4075
|
recordAcceptedConfiguredGroupRoute = recordGroupRoute;
|
|
4168
|
-
|
|
4076
|
+
const gatingParams = {
|
|
4169
4077
|
cfg,
|
|
4170
4078
|
msg,
|
|
4171
|
-
deferMissingMention: hasAudioBody && Boolean(msg.payload.media?.path),
|
|
4172
4079
|
groupHistoryKey,
|
|
4173
4080
|
agentId: route.agentId,
|
|
4174
4081
|
sessionKey: route.sessionKey,
|
|
@@ -4181,25 +4088,16 @@ function createWebOnMessageHandler(params) {
|
|
|
4181
4088
|
groupMemberNames: params.groupMemberNames,
|
|
4182
4089
|
logVerbose,
|
|
4183
4090
|
replyLogger: params.replyLogger
|
|
4091
|
+
};
|
|
4092
|
+
let gating = await applyGroupGating({
|
|
4093
|
+
...gatingParams,
|
|
4094
|
+
deferMissingMention: hasAudioBody && Boolean(msg.payload.media?.path)
|
|
4184
4095
|
});
|
|
4185
4096
|
if (!gating.shouldProcess && "needsMentionText" in gating && gating.needsMentionText === true) {
|
|
4186
4097
|
await runAudioPreflightOnce();
|
|
4187
4098
|
gating = await applyGroupGating({
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
...typeof preflightAudioTranscript === "string" ? { mentionText: preflightAudioTranscript } : {},
|
|
4191
|
-
groupHistoryKey,
|
|
4192
|
-
agentId: route.agentId,
|
|
4193
|
-
sessionKey: route.sessionKey,
|
|
4194
|
-
baseMentionConfig,
|
|
4195
|
-
providerMentionPatterns: account.mentionPatterns,
|
|
4196
|
-
authDir: account.authDir,
|
|
4197
|
-
selfChatMode: account.selfChatMode,
|
|
4198
|
-
groupHistories: params.groupHistories,
|
|
4199
|
-
groupHistoryLimit: params.groupHistoryLimit,
|
|
4200
|
-
groupMemberNames: params.groupMemberNames,
|
|
4201
|
-
logVerbose,
|
|
4202
|
-
replyLogger: params.replyLogger
|
|
4099
|
+
...gatingParams,
|
|
4100
|
+
...typeof preflightAudioTranscript === "string" ? { mentionText: preflightAudioTranscript } : {}
|
|
4203
4101
|
});
|
|
4204
4102
|
}
|
|
4205
4103
|
if (!gating.shouldProcess) {
|
|
@@ -4322,8 +4220,7 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
|
|
|
4322
4220
|
const heartbeatSeconds = resolveHeartbeatSeconds(cfg, tuning.heartbeatSeconds);
|
|
4323
4221
|
const reconnectPolicy = resolveReconnectPolicy(cfg, tuning.reconnect);
|
|
4324
4222
|
const socketTiming = resolveWhatsAppSocketTiming(tuning.socketTiming);
|
|
4325
|
-
const
|
|
4326
|
-
const groupHistoryLimit = account.historyLimit ?? cfg.channels?.whatsapp?.historyLimit ?? cfg.messages?.groupChat?.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT;
|
|
4223
|
+
const groupHistoryLimit = resolvePromptHistoryLimit(account.historyLimit ?? cfg.channels?.whatsapp?.historyLimit ?? cfg.messages?.groupChat?.historyLimit);
|
|
4327
4224
|
const groupHistories = /* @__PURE__ */ new Map();
|
|
4328
4225
|
const groupMemberNames = /* @__PURE__ */ new Map();
|
|
4329
4226
|
const groupMetadataCache = /* @__PURE__ */ new Map();
|
|
@@ -4392,8 +4289,6 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
|
|
|
4392
4289
|
backgroundTasks: connectionLocal.backgroundTasks,
|
|
4393
4290
|
replyResolver: activeReplyResolver,
|
|
4394
4291
|
replyLogger,
|
|
4395
|
-
baseMentionConfig,
|
|
4396
|
-
account,
|
|
4397
4292
|
buildContext: pluginChannelRuntime?.inbound.buildContext,
|
|
4398
4293
|
dispatchReplyFromConfig: pluginChannelRuntime?.reply?.dispatchReplyFromConfig
|
|
4399
4294
|
});
|
|
@@ -4573,38 +4468,25 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
|
|
|
4573
4468
|
});
|
|
4574
4469
|
enqueueSystemEvent(`WhatsApp gateway connected${selfE164 ? ` as ${selfE164}` : ""}.`, { sessionKey: connectRoute.sessionKey });
|
|
4575
4470
|
const normalizedAccountId = normalizeReconnectAccountId(account.accountId);
|
|
4576
|
-
|
|
4577
|
-
drainKey: `whatsapp:${normalizedAccountId}`,
|
|
4578
|
-
logLabel: "WhatsApp reconnect drain",
|
|
4579
|
-
cfg,
|
|
4580
|
-
log: reconnectLogger,
|
|
4581
|
-
selectEntry: (entry) => ({
|
|
4582
|
-
match: entry.channel === "whatsapp" && normalizeReconnectAccountId(entry.accountId) === normalizedAccountId,
|
|
4583
|
-
bypassBackoff: isNoListenerReconnectError(entry.lastError)
|
|
4584
|
-
})
|
|
4585
|
-
}).catch((err) => {
|
|
4586
|
-
reconnectLogger.warn({
|
|
4587
|
-
connectionId: connection.connectionId,
|
|
4588
|
-
error: String(err)
|
|
4589
|
-
}, "reconnect drain failed");
|
|
4590
|
-
});
|
|
4591
|
-
const periodicDrainInterval = setInterval(() => {
|
|
4471
|
+
const drainDeliveries = (mode) => {
|
|
4592
4472
|
drainPendingDeliveries({
|
|
4593
4473
|
drainKey: `whatsapp:${normalizedAccountId}`,
|
|
4594
|
-
logLabel:
|
|
4474
|
+
logLabel: `WhatsApp ${mode} drain`,
|
|
4595
4475
|
cfg,
|
|
4596
4476
|
log: reconnectLogger,
|
|
4597
4477
|
selectEntry: (entry) => ({
|
|
4598
4478
|
match: entry.channel === "whatsapp" && normalizeReconnectAccountId(entry.accountId) === normalizedAccountId,
|
|
4599
|
-
bypassBackoff:
|
|
4479
|
+
bypassBackoff: mode === "reconnect" && isNoListenerReconnectError(entry.lastError)
|
|
4600
4480
|
})
|
|
4601
4481
|
}).catch((err) => {
|
|
4602
4482
|
reconnectLogger.warn({
|
|
4603
4483
|
connectionId: connection.connectionId,
|
|
4604
4484
|
error: String(err)
|
|
4605
|
-
},
|
|
4485
|
+
}, `${mode} drain failed`);
|
|
4606
4486
|
});
|
|
4607
|
-
}
|
|
4487
|
+
};
|
|
4488
|
+
drainDeliveries("reconnect");
|
|
4489
|
+
const periodicDrainInterval = setInterval(() => drainDeliveries("periodic"), 3e4);
|
|
4608
4490
|
const inboundPolicy = resolveWhatsAppInboundPolicy({
|
|
4609
4491
|
cfg,
|
|
4610
4492
|
accountId: account.accountId,
|