forked from rmyndharis/OpenWA
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
278 lines (242 loc) · 15.7 KB
/
Copy path.env.example
File metadata and controls
278 lines (242 loc) · 15.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# =============================================================================
# OpenWA - Environment Configuration
# =============================================================================
# Copy this file to .env and customize as needed.
# This is the Single Source of Truth for all configuration.
# =============================================================================
# CORE SETTINGS
# =============================================================================
NODE_ENV=production
API_PORT=2785
LOG_LEVEL=info # error | warn | info | debug
# Console output format. Default: json in production (containers, log aggregators),
# human-readable pretty otherwise. Force one with: json | pretty
# LOG_FORMAT=pretty
# Auto-start previously authenticated sessions on server boot
AUTO_START_SESSIONS=false
# 0 = unlimited. Set a positive integer to cap concurrently running/initializing sessions.
# Failed sessions still hold a slot until stopped (their engine stays resident); stop them to free capacity.
MAX_CONCURRENT_SESSIONS=0
# Domain Configuration
DOMAIN=localhost
# Host interface the dev compose binds the API/dashboard ports to. Defaults to 127.0.0.1
# (localhost only). Set to 0.0.0.0 to reach the dev stack from another machine (e.g. a remote
# VPS) — put a TLS reverse proxy in front for anything internet-facing (the API key is sent in
# cleartext over plain HTTP).
# BIND_HOST=0.0.0.0
# Public URLs (for startup banner and external access)
# BASE_URL=https://api.yourdomain.com
# DASHBOARD_URL=https://dashboard.yourdomain.com
# CORS Configuration: comma-separated allowed origins. The wildcard "*" is allowed
# only in development; in production it is REFUSED (cross-origin browser requests are
# blocked) — set explicit origin(s) there, e.g. https://dashboard.yourdomain.com
CORS_ORIGINS=*
# SSL/TLS: terminate TLS at your own reverse proxy (nginx, Caddy, a cloud load
# balancer, or a k8s Ingress) in front of the API — see docs/12-troubleshooting-faq.md.
# Trusted reverse proxies (comma-separated IPs/CIDRs) whose X-Forwarded-For
# header is trusted to determine the real client IP for API-key IP whitelisting.
# Leave empty (default) to ignore X-Forwarded-For and use the direct socket
# address, which prevents IP spoofing. If you run behind a reverse proxy AND use
# per-key allowedIps restrictions, set this to the proxy's address/subnet, e.g.:
# TRUSTED_PROXIES=172.18.0.0/16
# =============================================================================
# ENGINE CONFIGURATION
# =============================================================================
# Which WhatsApp engine to use (plugin-based)
# Options: whatsapp-web.js, baileys
# Left unset by default so the dashboard (Infrastructure > Engine) governs the active engine via
# data/.env.generated (defaults to whatsapp-web.js). Uncomment to pin an engine from the environment;
# a value set here always wins over the dashboard selection.
# ENGINE_TYPE=whatsapp-web.js
# Engine-specific settings
SESSION_DATA_PATH=./data/sessions
PUPPETEER_HEADLESS=true
PUPPETEER_ARGS=--no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-gpu
# Path to a system Chromium/Chrome binary. Leave unset to use the bundled Puppeteer browser.
# Required in the Docker image and on hosts without a bundled browser (e.g. Alpine/ARM).
# PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
# Optional WhatsApp Web client version pin. Leave unset (or use "latest", "auto", or "off") to
# let whatsapp-web.js auto-select. If sessions get stuck at "authenticating" after scanning the QR,
# set this to a known-good version from https://github.com/wppconnect-team/wa-version (browse the
# html/ folder). WWEBJS_WEB_VERSION_REMOTE_PATH overrides the URL template (use {version} as the
# placeholder) if you self-host the version HTML.
# WWEBJS_WEB_VERSION=2.3000.1040641150-alpha
# Extend the initial boot/inject wait (milliseconds) before QR generation. On slow first boots
# (WSL2 or low-resource containers) the default 30000ms can expire before WhatsApp Web finishes
# loading. Raise it (e.g. 120000) if startup times out. Unset keeps the default (30000).
# WWEBJS_AUTH_TIMEOUT_MS=120000
# Baileys engine (used when ENGINE_TYPE=baileys). WebSocket client, no Chromium.
# NOTE: the Baileys engine is loaded lazily (dynamic import, only when ENGINE_TYPE=baileys), so there is no
# global Node.js version floor. Node.js 22 LTS is recommended for all deployments.
BAILEYS_AUTH_DIR=./data/baileys
# NOTE: proxy (PROXY_URL/PROXY_TYPE) is not yet supported by the baileys engine; it is ignored.
# Pull the FULL message-history archive on connect (large). Off by default: the engine still enables the
# initial sync (contacts, chats, recent messages, lid mappings) without downloading the entire history.
BAILEYS_SYNC_FULL_HISTORY=false
# Surface the Baileys library's own logs for debugging (trace|debug|info|warn|error). Silent by default.
# `trace` dumps the decoded WhatsApp wire frames to stdout (context "baileys-wire").
# BAILEYS_LOG_LEVEL=debug
# Humanise single sends: show a "typing…" indicator and pause briefly (length-scaled, jittered)
# before each text send so messages don't look instantaneous (anti-ban). ON by default — set to
# false to disable. SIMULATE_TYPING_MAX_MS caps the pause (default 5000). Does not affect bulk
# sends, which have their own delayBetweenMessages throttle.
# SIMULATE_TYPING=false
# SIMULATE_TYPING_MAX_MS=5000
# Inline @lid -> phone resolution (#263). When a sender is identified by a WhatsApp privacy id
# (@lid) instead of a phone number, attach a best-effort `senderPhone` (MSISDN digits, or null when
# the engine can't map it) to the message.received webhook + websocket payload. OFF by default —
# it adds a per-sender lookup (cached). The on-demand endpoint GET /sessions/:id/contacts/:id/phone
# works regardless of this flag.
# RESOLVE_LID_TO_PHONE=true
# Observability — Prometheus scrape endpoint at GET /api/metrics.
# Disabled by default; set a token to enable. Scrapers must send `Authorization: Bearer <token>`.
# METRICS_TOKEN=change-me-to-a-long-random-string
# Audit-log retention. Logs older than this many days are pruned daily (and once at startup).
# Default 90; set to 0 to keep audit logs forever (disable pruning).
# AUDIT_RETENTION_DAYS=90
# =============================================================================
# DATABASE
# =============================================================================
# Options: sqlite, postgres
DATABASE_TYPE=sqlite
POSTGRES_BUILTIN=false # Use built-in PostgreSQL container?
# PostgreSQL settings (ignored for sqlite, auto-configured if POSTGRES_BUILTIN=true)
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=openwa
DATABASE_USERNAME=openwa
# MUST set a strong, unique value before using Postgres — no default is shipped.
# Production refuses to start if this is empty or a known placeholder when DATABASE_TYPE=postgres.
DATABASE_PASSWORD=
DATABASE_SYNCHRONIZE=false # WARNING: Set false in production! (data DB)
DATABASE_LOGGING=false
# Auth/audit (main) DB schema management. Default ON (zero-config first boot).
# Set to "false" to manage the api_keys/audit_logs schema via the bundled main-owned
# migration instead of synchronize (migrationsRun creates them at boot).
MAIN_DATABASE_SYNCHRONIZE=true
DATABASE_SSL=false # Set true for managed Postgres (Supabase, Heroku, Render, Railway)
DATABASE_SSL_REJECT_UNAUTHORIZED=true # Set false to allow self-signed certs (only when DATABASE_SSL=true)
# Postgres pool/query timeouts (ms). Defaults are conservative; set any to 0 to disable.
DATABASE_STATEMENT_TIMEOUT_MS=30000 # Aborts a single runtime query that runs longer (server-side; not applied to migrations)
DATABASE_IDLE_TIMEOUT_MS=30000 # Closes idle pooled connections after this long
DATABASE_CONNECTION_TIMEOUT_MS=10000 # Fails fast if a new connection can't be acquired in time
# =============================================================================
# REDIS / QUEUE (Phase 2)
# =============================================================================
REDIS_ENABLED=false # Enable Redis for queue and caching
REDIS_BUILTIN=false # Use built-in Redis container?
# Redis settings (auto-configured if REDIS_BUILTIN=true)
REDIS_HOST=localhost
REDIS_PORT=6379
# Fail Redis queue/cache connection attempts after this many ms.
REDIS_CONNECT_TIMEOUT_MS=5000
# REDIS_PASSWORD=
# =============================================================================
# STORAGE
# =============================================================================
# Options: local, s3
STORAGE_TYPE=local
MINIO_BUILTIN=false # Use built-in MinIO container?
# Local storage path (if STORAGE_TYPE=local)
STORAGE_LOCAL_PATH=./data/media
# S3/MinIO settings (if STORAGE_TYPE=s3, auto-configured if MINIO_BUILTIN=true)
S3_ENDPOINT=http://localhost:9000
S3_BUCKET=openwa
S3_REGION=us-east-1
# MUST set strong, unique values before using S3/MinIO — no defaults shipped.
# Production refuses to start if these are empty/placeholder when STORAGE_TYPE=s3 (external).
# Canonical names (what the app reads first and the dashboard writes); the legacy
# S3_ACCESS_KEY / S3_SECRET_KEY are still accepted as a fallback for older setups.
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
# =============================================================================
# WEBHOOK
# =============================================================================
WEBHOOK_TIMEOUT=10000 # Timeout in milliseconds
WEBHOOK_MAX_RETRIES=3 # Number of retry attempts
WEBHOOK_RETRY_DELAY=5000 # Delay between retries in ms
# Block outbound WEBHOOK deliveries to internal/reserved addresses (SSRF
# protection). ON by default; set to "false" only on closed networks. When on,
# webhook URLs resolving to loopback/private/link-local/metadata ranges are
# refused (at registration AND delivery) and redirects are not followed.
# (Server-side media-by-URL fetches are ALWAYS SSRF-guarded, regardless of this flag.)
WEBHOOK_SSRF_PROTECT=true
# Expose the FULL sender `contact` field set (id, number, shortName, business flags, isBlocked,
# labels, …) on the message.received webhook + websocket payload. OFF by default — the payload keeps
# the minimal { name, pushName }. Opt in only if your consumer needs the richer data; all fields are
# read from the already-cached contact (no extra WhatsApp API calls).
# WEBHOOK_CONTACT_DETAILS=true
# Comma-separated hosts/IPs allowed to bypass SSRF protection for BOTH webhooks
# and media — escape-hatch for trusted internal targets (e.g. a localhost media
# store or a sidecar webhook receiver).
# SSRF_ALLOWED_HOSTS=localhost,minio
# Server-side media size/time limits:
# MEDIA_DOWNLOAD_ENABLED=true # Set to false to skip downloading inbound media entirely
# # (no decryption, no memory allocation, no storage).
# # NOTE: disabling also makes hasMedia report false and removes the
# # media field from webhooks and the dashboard.
# STORE_EPHEMERAL_MESSAGES=true # Set to false to skip persisting and dispatching incoming
# # WhatsApp disappearing messages (ephemeralDuration > 0).
# # Default: true (backward compatible — store everything).
# MEDIA_DOWNLOAD_MAX_BYTES=52428800 # cap remote-URL sends, inbound media, AND outbound base64 sends (default 50 MiB; oversized inbound media is dropped, message kept; oversized base64 is rejected with 400)
# MEDIA_DOWNLOAD_TIMEOUT_MS=30000 # abort a slow media download (default 30s)
# Storage import/export limits (ADMIN /infra/storage/* endpoints):
# STORAGE_IMPORT_MAX_BYTES=209715200 # per-entry cap for a tar.gz import; aborts on overflow (default 200 MiB)
# STORAGE_IMPORT_MAX_ENTRIES=100000 # max entries in an import archive; aborts beyond this (default 100000)
# STORAGE_EXPORT_TTL_MS=3600000 # auto-delete an export archive after this long (default 1h)
# =============================================================================
# RATE LIMITING (all TTLs are in MILLISECONDS)
# =============================================================================
# The "medium" tier is the one enforced on the API; short/long are optional extra tiers.
RATE_LIMIT_MEDIUM_TTL=60000 # window in ms (default 60000 = 60s)
RATE_LIMIT_MEDIUM_LIMIT=100 # max requests per window
# RATE_LIMIT_SHORT_TTL=1000 # 1s burst window (default)
# RATE_LIMIT_SHORT_LIMIT=10
# RATE_LIMIT_LONG_TTL=3600000 # 1h window (default)
# RATE_LIMIT_LONG_LIMIT=1000
# Per-instance fairness cap on the Integration Fabric ingress route (POST /api/ingress/:pluginId/:instanceId/*).
# Providers deliver every tenant's webhooks from one shared egress IP, so this is keyed on
# (pluginId, instanceId) instead of IP — a noisy tenant gets 429'd without throttling its neighbors.
# Independent of, and in addition to, the IP-keyed tiers above.
# INGRESS_INSTANCE_LIMIT=120 # max requests per instance per window (default 120)
# INGRESS_INSTANCE_TTL=60000 # window in ms (default 60000 = 60s)
# =============================================================================
# MCP (Model Context Protocol) — Agent / AI-assistant tool server
# =============================================================================
# Off by default. When enabled, mounts a stateless Streamable-HTTP MCP server
# at POST /mcp on the same port. See docs/24-mcp-integration.md for details.
# MCP_ENABLED=true
# Mount read-only tools only (no sends, no mutations). Recommended for observer agents.
# MCP_READONLY=true
# Per-key sliding-window rate limit for tool calls.
# Any blank/non-positive/non-numeric value falls back to the default.
# MCP_RATE_LIMIT_MAX=60 # max tool calls per key per window (default 60)
# MCP_RATE_LIMIT_WINDOW_MS=60000 # window size in ms (default 60000 = 1 min)
# Pre-auth, per-IP sliding-window throttle for the /mcp mount (gates invalid-key requests before
# key validation, since the raw mount bypasses the global throttler). Same fallback rules.
# MCP_IP_RATE_LIMIT_MAX=120 # max requests per IP per window (default 120)
# MCP_IP_RATE_LIMIT_WINDOW_MS=60000 # window size in ms (default 60000 = 1 min)
# =============================================================================
# PLUGINS
# =============================================================================
PLUGINS_ENABLED=true # Enable plugin system
PLUGINS_DIR=./data/plugins # Plugin directory
# =============================================================================
# SECURITY
# =============================================================================
# Master API key (leave empty to disable, or set to secure value)
API_MASTER_KEY=
# First-boot default admin key. By default a cryptographically random key is
# generated (printed in the startup banner / written to data/.api-key). Set this
# to true ONLY for local development to seed the well-known, insecure
# `dev-admin-key` instead. Ignored when API_MASTER_KEY is set.
# ALLOW_DEV_API_KEY=true
# Optional server-side pepper for API-key hashing (HMAC-SHA256 instead of plain SHA-256).
# Recommended in production. Note: setting or changing it invalidates all existing key hashes,
# so re-issue keys after enabling. Leave unset to keep the current (unpeppered) behaviour.
# API_KEY_PEPPER=
# =============================================================================
# DEVELOPER SETTINGS
# =============================================================================
ENABLE_SWAGGER=true # Enable API documentation at /api/docs (set false to disable on exposed deployments)
BODY_SIZE_LIMIT=25mb # Max request body size (base64 media sends ride in the JSON body)