Skip to main content

Every bot

Runtime

  • Node.js 22 or later, and your app is ESM ("type": "module" in package.json, or .mjs files). The packages ship no CommonJS build.
  • A process manager restarts the bot when it exits: PM2, systemd, Docker restart: unless-stopped or your orchestrator. See Deployment.
  • Graceful shutdown: on SIGTERM/SIGINT call await bot.stop({ drain: true, timeout: '15s' }) so replies in flight are sent and recorded before the process exits (Graceful shutdown).
  • Pin your versions (commit the lockfile). While the packages are in beta, read the migration pages before each upgrade.

State

  • A persistent store. The default MemoryStore keeps everything in RAM. Use SQLiteStore for one process or RedisStore for several (Persistent store).
  • Pass the store instance: store: new SQLiteStore({ file }). A string such as store: 'sqlite' is accepted for compatibility but still creates a MemoryStore.
  • Multi-step flows are .persistent(), so a user in the middle of a flow resumes it after a restart (Flows).
  • On Node.js 24.19 or later, use better-sqlite3 13 with SQLiteStore (why).
  • Volumes and backups: the WhatsApp session folder (sessions/) and the data folder (data/) are mounted on persistent disk and backed up together (Backups).

Secrets

  • Tokens, API keys and webhook secrets come from the environment (or your secret manager), never from the source tree. The framework reads no environment variable by itself: you map them to the provider options (Environment variables).
  • sessions/, .env, *.db and *.qr.png are in .gitignore and never copied into a Docker image.

Webhooks (Cloud API, Telegram webhook, Twilio…)

  • Served over HTTPS, with the channel’s signature check configured (appSecret, webhookSecret…). Never set allowUnsignedWebhooks: true in production (Security).
  • The signature is checked on the raw body: do not put a JSON body parser in front of the webhook route (Webhook server).

Observability

  • Logs: pass your own pino logger (or keep the built-in one, which logs at warn). Chat and sender ids are hashed in log lines by default (logIds: 'hash'); keep it that way outside local debugging.
  • Errors: listen to bot.on('error', …) and send them to your error tracker.
  • Health and metrics: expose a liveness/readiness endpoint and bot.metrics() in Prometheus format (Health checks, Operations).

Channel limits

  • WhatsApp on Baileys: keep the provider’s rate limiter on and avoid unsolicited bulk sends (Rate limiting).
  • Cloud API: free-form replies only within the 24-hour window; use templates outside it (WhatsApp 24h window).
  • Message log growth: the persistent stores keep every message unless you set maxMessagesPerChat (Persistent store).

When you need more

All of these are opt-in: without the option, the bot runs exactly as before.

Which packages are published

The npm packages (36) are @botmesh/core; the channels @botmesh/baileys, @botmesh/meta, @botmesh/telegram, @botmesh/messenger, @botmesh/instagram, @botmesh/discord, @botmesh/evolution, @botmesh/wppconnect, @botmesh/twilio, @botmesh/gupshup, @botmesh/gohighlevel and @botmesh/email; the stores @botmesh/sqlite-store, @botmesh/redis-store, @botmesh/postgres-store, @botmesh/mysql-store and @botmesh/mongo-store; the infrastructure @botmesh/http, @botmesh/graph-core, @botmesh/wa-gateway-kit, @botmesh/server, @botmesh/events and @botmesh/otel; the plugins @botmesh/ai, @botmesh/rag, @botmesh/voice, @botmesh/nlu, @botmesh/dialogflow, @botmesh/chatwoot, @botmesh/tickets and @botmesh/moderation; and the tooling @botmesh/flow-schema, @botmesh/mcp, eslint-plugin-botmesh and create-botmesh. All 36 are on npm. Ten of them were first published during the alpha (core, baileys, meta, telegram, sqlite-store, redis-store, ai, http, graph-core and create-botmesh); the other 26 shipped for the first time with the beta. Some pages also describe packages that live only in the repository for now (the TikTok channel, @botmesh/manager, the sandbox…). Each of those pages says so. Plan a production deployment on the published ones.

Before each release of your bot

  • Tests pass with createTestBot / MockProvider (Testing).
  • The store files or databases are backed up before upgrading @botmesh/sqlite-store: a newer schema version cannot be opened by an older release (Schema versions).
  • With replicas, every replica runs a version that understands the options you turn on (for example coordination.handover.flows: 'forward').