Do not restart session when updating some apps - AppDefinition.restartOnChange
5.1 KiB
5.1 KiB
WAHA Agent Playbook
This guide summarizes how to explore, modify, and validate the WhatsApp HTTP API (WAHA) codebase when assisting as an automation or coding agent.
Product & Variants
- WAHA ships in Core and Plus editions
- Core lives under
src/coreand supports the default session with minimal media features - Plus extends core via
src/plusto add multi-session orchestration, richer media handling, and external storage integrations - Core code must remain free from Plus-only references (pre-commit hook rejects "plus" in core files)
- Commit subjects: changes that touch
src/plusrequire[PLUS] …prefix; everything else uses[core] …
Tech Stack
- Runtime: Node.js 22.x, Yarn 3.6 (Berry)
- Framework: NestJS v11 with dependency injection and modular controllers in
src/api - Engines: WhatsApp engines are abstracted (
WEBJS,GOWS,NOWEB,WPP). Core usesSessionManagerCore; Plus swaps toSessionManagerPluswith extra storage backends (Mongo/Postgres/SQLite) - ESM Bridge: ESM-only dependencies (Baileys) load through
src/vendor/esm.ts - Utilities: RxJS streams drive webhook event fan-out. Prefer existing
helpers in
src/utilsandsrc/core/utils
Key Paths
src/main.ts: runtime entry point; dynamically loads AppModule (Core vs Plus)src/api/**: REST controllers and WebSocket gatewaysrc/core/**: shared abstractions (config services, engine bootstrap, storage, session management)src/plus/**: multi-session orchestration, advanced media services, and external persistence layerssrc/structures/**andsrc/utils/**: DTOs, enums (event names followdomain.action), helper utilities
Coding Expectations
- Favor composability and long-lived solutions
- Reuse existing helpers (
parseBool,DefaultMap, media factories) instead of reinventing logic - Stick to NestJS patterns: inject dependencies through constructors, expose provider tokens from modules
- Logging goes through injected
PinoLoggeror helpers insrc/utils/logging.ts - Respect path aliases (
@waha/...) defined intsconfig.json - Prefer named function declarations over
constarrow functions - Avoid naming unused variables with a leading underscore
- Always use explicit property names in object literals — never shorthand: write
{ key: value }, not{ value }(even when the variable name matches the key) - Do not write verbose ternaries; use idiomatic helpers like
??(nullish coalescing) - Do not place
awaitor other async calls inside ternary expressions (?:) or nullish-coalescing expressions (??); use explicitif/elseblocks or assign the awaited value to a variable first - For configs, prefer runtime configurability over constants (environment keys
follow
WAHA_*andWAHA_SESSION_CONFIG_*) - Do not use decorative comment blocks (lines of dashes/underscores with a
label) such as
// ─────────── NAME ───────────; use plain inline comments or no comment at all
How to Run API
export DEBUG=1
export WAHA_API_KEY=666
export WAHA_DASHBOARD_PASSWORD=666
export WAHA_DASHBOARD_USERNAME=admin
export WWHATSAPP_SWAGGER_USERNAME=admin
export WHATSAPP_SWAGGER_PASSWORD=666
export WHATSAPP_DEFAULT_ENGINE={WEBJS|WPP|NOWEB|GOWS}
export WAHA_DEBUG_MODE=True
export WAHA_HTTP_STRICT_MODE=1
export WAHA_MEDIA_STORAGE=LOCAL
export WHATSAPP_FILES_FOLDER=./.media
npm run start
Code Guidelines
- Add
@Activity()(fromsrc/core/abc/activity.ts) to every engine method that makes a network call to WhatsApp servers - It triggers
maintainPresenceOnline()before the method runs, keeping the session ONLINE during API activity and scheduling an OFFLINE transition after an idle period - Skip it on methods that only throw
NotImplementedByEngineError/AvailableInPlusVersion
MCP Tools
MCP tools live in src/apps/mcp/tools/ and expose the HTTP API to AI clients.
Each tool file mirrors an API domain (e.g. chats.tools.ts → chats endpoints).
When you change an existing API endpoint:
- Check the corresponding
*.tools.tsfile and update the tool'sinputSchema, description, or behavior if the API signature changed.
When you add a new API endpoint:
- Ask the user whether an MCP tool is needed for the new endpoint before creating one.
- If yes, add the tool to the matching
*.tools.tsfile (or create a new file for a new domain). - Every
@Tooldecorator must include anannotationsblock with all three fields:annotations: { readOnlyHint: true | false, // true = no side effects (GET-style) destructiveHint: true | false, // true = irreversible deletion/logout idempotentHint: true | false, // true = safe to repeat with same args } - Input schemas live in the matching
*.zod.tsfile. - Tools call the API via
this.textRequest({ method, url, ... })inherited fromMcpController.
Related Sources
- WEBJS:
../whatsapp-web.js - NOWEB:
../WhiskeySockets-Baileysand../whatsapp-rust-bridge - GOWS:
../gowsand../whatsmeow - WPP:
../wa-js,../wppconnect,../wppconnect-server - ChatWoot:
../chatwoot