Copy the storage (Mongo/Postgres/SQLite), media (S3/Postgres), engine
auth/store and util implementations from src/plus into src/core, and fold
the *Plus engine sessions, session manager, factories, health and channels
services into their *Core classes.
Core now supports multi-session orchestration, Mongo/Postgres session
storage, S3/Postgres media storage, FFmpeg media conversion, real health
checks and channels metadata. mediaConverter is set once in the base
session, and AppModuleCore wires the conditional media modules and health
indicators.
Session stuck in 'starting' or 'stoped' state due to Node.js Buffer limit reached when loading large RemoteAuth database entries (PostgreSQL/WebJS) #2090
Fix#2084 - All outbound messages fail with server returned error 400 until session restart
Fix#2085 - MediaRetry to also trigger on ciphertext hash mismatch (not only 403)
Fix#2080 - status@broadcast batch timeouts, add WAHA_GOWS_STATUS_PARTICIPANTS_BATCH_SIZE
Problem:
- stickerMessage often has URL https://a.whatsapp.net with no path for
encrypted media. The previous fix only copied uppercase URL to lowercase url,
so DownloadMedia still tried HTTP GET on that host (for example DNS lookup
failures) instead of using directPath and media keys.
- Lottie (application/was) stickers usually ship a full mmg.whatsapp.net URL,
so they worked; image/webp stickers with the placeholder broke.
Solution:
- Treat a.whatsapp.net with an empty path as a placeholder: clone the message
and delete both URL and url on stickerMessage before gRPC DownloadMedia.
- For real CDN URLs, keep mirroring URL to url when url is missing.
Lottie stickers arrive from WhatsApp as a ZIP archive (mimetype
application/was) containing animation/animation.json. This change
intercepts those stickers in the GOWS Plus session, renders each
animation frame off-screen, and delivers an animated WebP to the
webhook instead of the raw ZIP.
Implementation:
- src/plus/utils/lottie-converter.ts (new):
- Extracts animation.json from the ZIP via adm-zip
- Renders frames with @lottiefiles/dotlottie-web + @napi-rs/canvas
(HTMLCanvasElement polyfill required; ImageData must NOT be polyfilled
to avoid per-frame pixel caching in WASM memory)
- Drives frames manually via dotLottie.setFrame(i) after 'load' for
reliable synchronous capture
- Encodes each RGBA frame to single-frame WebP with sharp (quality=80)
- Assembles animated WebP via node-webpmux with full alpha transparency
- Frame delay derived from animation fps; clamped to >=30ms
- Fallback delay configurable via WAHA_LOTTIE_DEFAULT_DELAY_MS env var
- sharp/adm-zip/node-webpmux loaded via require() — their module.exports
is the callable itself with no .default, so ESM default import resolves
to undefined at runtime
- src/plus/engines/gows/session.gows.plus.ts:
- Overrides downloadMedia with LottieAwareGOWSEngineMediaProcessor
- normalizeStickerUrl: fixes GOWS URL field case mismatch (URL vs url)
that caused an infinite network loop on Lottie downloads
- Reports mimetype image/webp and extension .webp for Lottie stickers
- package.json: add @lottiefiles/dotlottie-web, @napi-rs/canvas,
node-webpmux to dependencies
Add tctoken lifecycle - fix#2050
Fix "Sessions take a long time to start after server restart" - fix#2012
Fix 403 on some media download - use re-upload request from the phone for this - fix#2049