go-whatsapp-web-multidevice README

The project's README from github.com/aldinokemal/go-whatsapp-web-multidevice. As one markdown file: README.md.

GoWA Logo

Go WhatsApp — Built for Efficient Memory Use

Patreon

If you're using this tool to generate income, consider supporting its development by becoming a Patreon member!

Your support helps ensure the project stays maintained and receives regular updates!


release version Build Image Binary Release

ARM, AMD64, and MCP Support

Download:

n8n Community Node

Breaking Changes

Features

Configuration

Configuration is loaded in this order of priority:

  1. Command-line flags (highest priority)
  2. Environment variables
  3. .env file (lowest priority)

Environment Variables

To use environment variables:

  1. From the repository root, copy the example file: cp src/.env.example src/.env.
  2. Update the values in src/.env as needed.
  3. Alternatively, set the same variables in the process environment.

Available Environment Variables

Variable Description Default Example
APP_PORT Application port 3000 APP_PORT=8080
APP_HOST Host address to bind the server 0.0.0.0 APP_HOST=127.0.0.1
APP_DEBUG Enable debug logging false APP_DEBUG=true
APP_OS OS name (device name in WhatsApp) GOWA APP_OS=MyApp
APP_BASIC_AUTH Basic authentication credentials - APP_BASIC_AUTH=user1:pass1,user2:pass2
APP_BASE_PATH Base path for subpath deployment - APP_BASE_PATH=/gowa
APP_TRUSTED_PROXIES Trusted proxy IP ranges for reverse proxy - APP_TRUSTED_PROXIES=0.0.0.0/0
APP_CORS_ALLOWED_ORIGINS Allowed CORS origins (any origin when empty) - APP_CORS_ALLOWED_ORIGINS=https://ui.example.com
APP_UI_ENABLED Serve the downloaded gowa-ui dashboard true APP_UI_ENABLED=false
APP_UI_AUTO_UPDATE Download and periodically refresh the latest dashboard true APP_UI_AUTO_UPDATE=false
APP_UI_REPO GitHub repository containing gowa-ui releases aldinokemal/gowa-ui APP_UI_REPO=my-org/gowa-ui
APP_UI_ASSET_NAME Dashboard release asset filename gowa-ui.html APP_UI_ASSET_NAME=gowa-ui.html
APP_UI_UPDATE_INTERVAL Interval between dashboard update checks 3h APP_UI_UPDATE_INTERVAL=6h
APP_UI_GITHUB_TOKEN Optional GitHub token for a higher API rate limit - APP_UI_GITHUB_TOKEN=github_pat_xxx
APP_UI_ASSET_SHA256 Optional SHA-256 pin for the dashboard asset - APP_UI_ASSET_SHA256=<hex-digest>
MCP_ENABLED Serve the streamable HTTP MCP endpoint at /mcp true MCP_ENABLED=false
MCP_OAUTH_ENABLED Enable OAuth 2.1 authentication for MCP false MCP_OAUTH_ENABLED=true
MCP_OAUTH_ISSUER_URL Public HTTPS OAuth issuer URL - MCP_OAUTH_ISSUER_URL=https://gowa.example.com
MCP_OAUTH_RESOURCE_URL Optional canonical public MCP URL Derived from issuer and base path MCP_OAUTH_RESOURCE_URL=https://gowa.example.com/mcp
MCP_OAUTH_DB_URI SQLite URI for OAuth clients, codes, and token hashes file:storages/oauth.db MCP_OAUTH_DB_URI=file:storages/oauth.db
DB_URI Database connection URI file:storages/whatsapp.db DB_URI=postgres://user:pass@host/db
DB_KEYS_URI Optional database URI for encryption/session key cache. Leave blank to use DB_URI; avoid in-memory storage in production because restarts can lose WhatsApp session state. - DB_KEYS_URI=file:storages/whatsapp-keys.db?_foreign_keys=on
CHAT_STORAGE_MAX_OPEN_CONNS Maximum concurrent SQLite connections for chat storage 5 CHAT_STORAGE_MAX_OPEN_CONNS=10
WHATSAPP_AUTO_REPLY Auto-reply message - WHATSAPP_AUTO_REPLY="Auto reply message"
WHATSAPP_AUTO_MARK_READ Auto-mark incoming messages as read false WHATSAPP_AUTO_MARK_READ=true
WHATSAPP_AUTO_DOWNLOAD_MEDIA Auto-download media from incoming messages true WHATSAPP_AUTO_DOWNLOAD_MEDIA=false
WHATSAPP_IGNORE_STATUS_MEDIA Ignore downloading status media (status@broadcast) false WHATSAPP_IGNORE_STATUS_MEDIA=true
WHATSAPP_AUTO_REJECT_CALL Auto-reject incoming WhatsApp calls false WHATSAPP_AUTO_REJECT_CALL=true
WHATSAPP_WEBHOOK Webhook URL(s) for events (comma-separated) - WHATSAPP_WEBHOOK=https://webhook.site/xxx
WHATSAPP_WEBHOOK_SECRET Webhook secret for validation secret WHATSAPP_WEBHOOK_SECRET=super-secret-key
WHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFY Skip TLS verification for webhooks (insecure) false WHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFY=true
WHATSAPP_WEBHOOK_EVENTS Whitelist of events to forward (comma-separated, empty = all) - WHATSAPP_WEBHOOK_EVENTS=message,message.ack
WHATSAPP_WEBHOOK_IGNORE_JIDS JIDs/wildcards to skip when forwarding (comma-separated) - [email protected]
WHATSAPP_WEBHOOK_DEVICE_MERGE_GLOBAL Per-device webhook adds to the global URLs instead of replacing them false WHATSAPP_WEBHOOK_DEVICE_MERGE_GLOBAL=true
WHATSAPP_ACCOUNT_VALIDATION Enable account validation true WHATSAPP_ACCOUNT_VALIDATION=false
WHATSAPP_PRESENCE_ON_CONNECT Presence on connect: available, unavailable, or none unavailable WHATSAPP_PRESENCE_ON_CONNECT=unavailable
WHATSAPP_PROXY Outbound proxy for the WhatsApp WebSocket (SOCKS5/HTTP/HTTPS) - WHATSAPP_PROXY=socks5://user:pass@host:1080
WHATSAPP_PRESENCE_PULSE_ENABLED Enable daily available/unavailable presence pulse true WHATSAPP_PRESENCE_PULSE_ENABLED=false
WHATSAPP_PRESENCE_PULSE_INTERVAL Interval between presence pulses 24h WHATSAPP_PRESENCE_PULSE_INTERVAL=24h
WHATSAPP_PRESENCE_PULSE_DURATION Duration to stay available during each pulse 5m WHATSAPP_PRESENCE_PULSE_DURATION=5m
CHATWOOT_ENABLED Enable Chatwoot integration false CHATWOOT_ENABLED=true
CHATWOOT_URL Chatwoot instance URL - CHATWOOT_URL=https://app.chatwoot.com
CHATWOOT_API_TOKEN Chatwoot API access token - CHATWOOT_API_TOKEN=your-api-token
CHATWOOT_ACCOUNT_ID Chatwoot account ID - CHATWOOT_ACCOUNT_ID=12345
CHATWOOT_INBOX_ID Chatwoot inbox ID - CHATWOOT_INBOX_ID=67890
CHATWOOT_DEVICE_ID WhatsApp device ID for Chatwoot (single-device/env fallback) - [email protected]
CHATWOOT_ALLOWED_HOSTS Allowlist of Chatwoot hosts for per-device configs (SSRF guard) - CHATWOOT_ALLOWED_HOSTS=app.chatwoot.com,chat.example.com
CHATWOOT_IMPORT_MESSAGES Enable message history sync to Chatwoot false CHATWOOT_IMPORT_MESSAGES=true
CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGES Days of history to import 3 CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGES=7
CHATWOOT_IMPORT_DB_URI Direct Chatwoot PostgreSQL URI for history sync - CHATWOOT_IMPORT_DB_URI=postgresql://user:pass@host:5432/chatwoot_production?sslmode=disable
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE Insert text placeholders for media rows during direct DB import true CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=true
CHATWOOT_IMPORT_MEDIA_WITH_REST Upload direct-DB import media rows through Chatwoot REST false CHATWOOT_IMPORT_MEDIA_WITH_REST=true
CHATWOOT_AUTO_CREATE Auto-create or reuse the Chatwoot API inbox at startup false CHATWOOT_AUTO_CREATE=true
CHATWOOT_INBOX_NAME Inbox name used when auto-create is enabled WhatsApp CHATWOOT_INBOX_NAME=WhatsApp Support
CHATWOOT_WEBHOOK_URL Public GOWA Chatwoot reply webhook URL - CHATWOOT_WEBHOOK_URL=https://api.example.com/chatwoot/webhook?secret=shared
CHATWOOT_WEBHOOK_SECRET Shared secret required for incoming Chatwoot webhooks - CHATWOOT_WEBHOOK_SECRET=shared
CHATWOOT_REOPEN_CONVERSATION Reopen resolved Chatwoot conversations for returning contacts true CHATWOOT_REOPEN_CONVERSATION=false
CHATWOOT_CONVERSATION_PENDING Create new Chatwoot conversations as pending false CHATWOOT_CONVERSATION_PENDING=true
CHATWOOT_IGNORE_JIDS JIDs or wildcards to exclude from Chatwoot forwarding - [email protected],[email protected]
CHATWOOT_SIGN_MSG Prefix Chatwoot agent replies with the agent name false CHATWOOT_SIGN_MSG=true
CHATWOOT_SIGN_DELIMITER Delimiter between Chatwoot agent signature and message body \n\n CHATWOOT_SIGN_DELIMITER=" - "
CHATWOOT_FORWARD_EDITS Mirror WhatsApp edits into Chatwoot threaded notes true CHATWOOT_FORWARD_EDITS=false
CHATWOOT_FORWARD_DELETES Mirror WhatsApp delete-for-everyone events into Chatwoot notes true CHATWOOT_FORWARD_DELETES=false
CHATWOOT_MESSAGE_READ Sync read state for linked WhatsApp/Chatwoot messages false CHATWOOT_MESSAGE_READ=true
CHATWOOT_MESSAGE_DELETE Delete linked opposite-side messages when deletion is reported false CHATWOOT_MESSAGE_DELETE=true

Documentation:

Run ./whatsapp --help to see all command-line flags.

Requirements

System Requirements

Supported Platforms

Dependencies (without Docker)

Note: The webp package provides cwebp (encoder), dwebp (decoder), and webpmux (frame extractor) tools. FFmpeg is required for media processing. The libwebp tools (webpmux + dwebp) are used for animated WebP sticker support.

How to use

Basic

  1. Clone the repository: git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice.
  2. Open the cloned directory in a terminal.
  3. Run cd src.
  4. Run go run . rest.
  5. Open http://localhost:3000.

Docker

Docker avoids the need to install Go, FFmpeg, and libwebp directly on the host.

  1. Clone the repository: git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice.
  2. Open the cloned directory in a terminal.
  3. Copy the environment file: cp src/.env.example src/.env.
  4. Run docker compose up -d --build.
  5. Open http://localhost:3000.

Build your own binary

  1. Clone the repository: git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice.
  2. Open the cloned directory in a terminal.
  3. Run cd src.
  4. Build the binary:
    • Linux and macOS: go build -o whatsapp
    • Windows (Command Prompt or PowerShell): go build -o whatsapp.exe
  5. Start the server:
    • Linux and macOS: ./whatsapp rest
    • Windows: .\whatsapp.exe rest
  6. Open http://localhost:3000 in a browser.

Run ./whatsapp --help (or .\whatsapp.exe --help on Windows) to see all flags.

Cross-compile for Raspberry Pi (ARM)

To build for a Raspberry Pi or another ARM device without a C toolchain (CGO), use the purego build tag. This selects a pure-Go SQLite implementation.

  1. Clone the repository: git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice.

  2. Open the cloned directory in a terminal.

  3. Run cd src.

  4. Build for Raspberry Pi Zero / 1 (ARMv6):

    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 go build -tags purego -o whatsapp-armv6
    
  5. Build for Raspberry Pi 2 / 3 / 4 (ARMv7 32-bit):

    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -tags purego -o whatsapp-armv7
    
  6. Transfer the binary to your Pi, give it execution permission (chmod +x), and run it:

    • If you built ARMv6: ./whatsapp-armv6 rest
    • If you built ARMv7: ./whatsapp-armv7 rest

MCP Server (Model Context Protocol)

MCP is not a separate mode or process — it's served by the REST server itself. Whenever ./whatsapp rest is running, the MCP endpoint is available at http://<host>:<port><base-path>/mcp (default http://localhost:3000/mcp) using the streamable HTTP transport. Disable it with MCP_ENABLED=false or --mcp-enabled=false (default: enabled).

Available MCP Tools

There are six consolidated tools; agents choose behavior through a type/action argument instead of one tool per operation:

Tool type / action values
whatsapp_send text, image, video, audio, document, sticker, location, contact, poll, link, forward
whatsapp_schedule list, get, pause, resume, cancel
whatsapp_message react, edit, revoke, delete, mark_read, mark_played, star, unstar, download_media
whatsapp_chat list_chats, list_contacts, get_messages, archive
whatsapp_group create, join_with_link, leave, info, participants, add_participants, remove_participants, promote, demote, invite_link, set_name, set_topic, set_settings, join_requests, manage_join_requests
whatsapp_app status, login_qr, login_code, logout, reconnect

whatsapp_send also accepts scheduled_at, timezone, recurrence, weekdays, day_of_month, end_at, and occurrence_limit to schedule the message instead of sending it now; manage the result with whatsapp_schedule.

Device selection

For multi-device deployments, the X-Device-Id header on the MCP client connection selects the device used by every tool call on that connection. If omitted, it falls back to the default device, just like REST. Any individual call can override it with an optional device_id argument.

MCP Configuration

Point your MCP client at the /mcp endpoint. It inherits the REST server's Basic Auth, so include the same Authorization header your REST calls use:

{
  "mcpServers": {
    "whatsapp": {
      "url": "http://localhost:3000/mcp",
      "headers": {
        "Authorization": "Basic dXNlcjpzZWNyZXQ=",
        "X-Device-Id": "628123456789"
      }
    }
  }
}

headers is optional: include Authorization only when Basic Auth is configured, and X-Device-Id only for multi-device setups.

OAuth for remote MCP clients

OAuth 2.1 is available for remote clients that cannot attach a Basic Auth header. It is disabled by default. A minimal configuration is:

APP_BASIC_AUTH=admin:replace-with-a-strong-password
MCP_ENABLED=true
MCP_OAUTH_ENABLED=true
MCP_OAUTH_ISSUER_URL=https://gowa.example.com

When OAuth is enabled, /mcp accepts either a Bearer token or the configured Basic Auth credentials. OAuth does not authenticate REST or UI routes. See MCP OAuth for client setup, reverse-proxy requirements, subpath behavior, and the security model.

Migrating from the standalone MCP mode

Production REST Server (Docker)

Using Docker Hub:

docker volume create whatsapp-storages
docker volume create whatsapp-statics
docker run --detach \
  --publish 3000:3000 \
  --name whatsapp \
  --restart always \
  --volume whatsapp-storages:/app/storages \
  --volume whatsapp-statics:/app/statics \
  aldinokemal2104/go-whatsapp-web-multidevice \
  rest --autoreply="Don't reply to this message, please"

Using GitHub Container Registry:

docker volume create whatsapp-storages
docker volume create whatsapp-statics
docker run --detach \
  --publish 3000:3000 \
  --name whatsapp \
  --restart always \
  --volume whatsapp-storages:/app/storages \
  --volume whatsapp-statics:/app/statics \
  ghcr.io/aldinokemal/go-whatsapp-web-multidevice \
  rest --autoreply="Don't reply to this message, please"

Production REST Server (Docker Compose)

Create a docker-compose.yml file with one of the following configurations.

Using Docker Hub:

services:
  whatsapp:
    image: aldinokemal2104/go-whatsapp-web-multidevice
    container_name: whatsapp
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - whatsapp_storages:/app/storages
      - whatsapp_statics:/app/statics
    command:
      - rest
      - --basic-auth=admin:admin
      - --port=3000
      - --debug=true
      - --os=Chrome
      - --account-validation=false

volumes:
  whatsapp_storages:
  whatsapp_statics:

Using GitHub Container Registry:

services:
  whatsapp:
    image: ghcr.io/aldinokemal/go-whatsapp-web-multidevice
    container_name: whatsapp
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - whatsapp_storages:/app/storages
      - whatsapp_statics:/app/statics
    command:
      - rest
      - --basic-auth=admin:admin
      - --port=3000
      - --debug=true
      - --os=Chrome
      - --account-validation=false

volumes:
  whatsapp_storages:
  whatsapp_statics:

Using environment variables with Docker Hub:

services:
  whatsapp:
    image: aldinokemal2104/go-whatsapp-web-multidevice
    container_name: whatsapp
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - whatsapp_storages:/app/storages
      - whatsapp_statics:/app/statics
    environment:
      - APP_BASIC_AUTH=admin:admin
      - APP_PORT=3000
      - APP_DEBUG=true
      - APP_OS=Chrome
      - WHATSAPP_ACCOUNT_VALIDATION=false

volumes:
  whatsapp_storages:
  whatsapp_statics:

Using environment variables with GitHub Container Registry:

services:
  whatsapp:
    image: ghcr.io/aldinokemal/go-whatsapp-web-multidevice
    container_name: whatsapp
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - whatsapp_storages:/app/storages
      - whatsapp_statics:/app/statics
    environment:
      - APP_BASIC_AUTH=admin:admin
      - APP_PORT=3000
      - APP_DEBUG=true
      - APP_OS=Chrome
      - WHATSAPP_ACCOUNT_VALIDATION=false

volumes:
  whatsapp_storages:
  whatsapp_statics:

Start the selected stack with docker compose up -d.

Production Server (Binary)

Download a binary from the releases page, then run it with the rest subcommand.

You may also fork or modify the source code.

Current API

MCP (Model Context Protocol) API

HTTP REST API

Status Operation Method URL
✅ Health Check GET /health
✅ List Devices GET /devices
✅ Add Device POST /devices
✅ Get Device Info GET /devices/:device_id
✅ Remove Device DELETE /devices/:device_id
✅ Login Device (QR) GET /devices/:device_id/login
✅ Login Device (Code) POST /devices/:device_id/login/code
✅ Logout Device POST /devices/:device_id/logout
✅ Reconnect Device POST /devices/:device_id/reconnect
✅ Get Device Status GET /devices/:device_id/status
✅ Get Device Webhook GET /devices/:device_id/webhook
✅ Set Device Webhook PATCH /devices/:device_id/webhook
✅ Log In with QR Code GET /app/login
✅ Log In with Pairing Code GET /app/login-with-code
✅ Passkey Pairing Status GET /app/passkey
✅ Passkey Pairing Response POST /app/passkey/response
✅ Confirm Passkey Pairing POST /app/passkey/confirm
✅ Logout GET /app/logout
✅ Reconnect GET /app/reconnect
✅ Devices GET /app/devices
✅ Connection Status GET /app/status
✅ App Info (version, limits) GET /app/info
✅ User Info GET /user/info
✅ User Avatar GET /user/avatar
✅ Change User Avatar POST /user/avatar
✅ Change User Push Name POST /user/pushname
✅ List My Groups* GET /user/my/groups
✅ List My Newsletters GET /user/my/newsletters
✅ Get My Privacy Settings GET /user/my/privacy
✅ List My Contacts GET /user/my/contacts
✅ Check WhatsApp User GET /user/check
✅ Get Business Profile GET /user/business-profile
✅ Send Message POST /send/message
✅ Send Image POST /send/image
✅ Send Audio POST /send/audio
✅ Send File POST /send/file
✅ Send Video POST /send/video
✅ Send Sticker POST /send/sticker
✅ Send Contact POST /send/contact
✅ Send Link POST /send/link
✅ Send Location POST /send/location
✅ Send Poll / Vote POST /send/poll
✅ Send Presence POST /send/presence
✅ Send Chat Presence (Typing Indicator) POST /send/chat-presence
✅ List Scheduled Sends GET /send/schedules
✅ Get Scheduled Send GET /send/schedules/:schedule_id
✅ Pause Scheduled Send POST /send/schedules/:schedule_id/pause
✅ Resume Scheduled Send POST /send/schedules/:schedule_id/resume
✅ Cancel Scheduled Send POST /send/schedules/:schedule_id/cancel
✅ Revoke Message POST /message/:message_id/revoke
✅ React Message POST /message/:message_id/reaction
✅ Delete Message POST /message/:message_id/delete
✅ Edit Message POST /message/:message_id/update
✅ Mark Message as Read POST /message/:message_id/read
✅ Mark Audio Message as Played POST /message/:message_id/played
✅ Star Message POST /message/:message_id/star
✅ Unstar Message POST /message/:message_id/unstar
✅ Forward Message POST /message/:message_id/forward
✅ Download Message Media GET /message/:message_id/download
✅ Reject Call POST /call/reject
✅ Join Group with Link POST /group/join-with-link
✅ Get Group Info from Link GET /group/info-from-link
✅ Get Group Info GET /group/info
✅ Leave Group POST /group/leave
✅ Create Group POST /group
✅ List Group Participants GET /group/participants
✅ Add Group Participants POST /group/participants
✅ Remove Group Participants POST /group/participants/remove
✅ Promote Group Participants POST /group/participants/promote
✅ Demote Group Participants POST /group/participants/demote
✅ Export Group Participants (CSV) GET /group/participants/export
✅ List Group Join Requests GET /group/participant-requests
✅ Approve Group Join Requests POST /group/participant-requests/approve
✅ Reject Group Join Requests POST /group/participant-requests/reject
✅ Set Group Photo POST /group/photo
✅ Set Group Name POST /group/name
✅ Lock or Unlock Group Settings POST /group/locked
✅ Set Group Announcement Mode POST /group/announce
✅ Set Group Topic POST /group/topic
✅ Get Group Invite Link GET /group/invite-link
✅ Unfollow Newsletter POST /newsletter/unfollow
✅ Get Newsletter Messages GET /newsletter/messages
✅ Download Newsletter Message Media GET /newsletter/messages/{server_id}/download
✅ Get Chat List GET /chats
✅ Get Chat Messages GET /chat/:chat_jid/messages
✅ Pin Chat POST /chat/:chat_jid/pin
✅ Archive Chat POST /chat/:chat_jid/archive
✅ Set Disappearing Messages POST /chat/:chat_jid/disappearing
✅ Request Chat History (Load Older Msgs) POST /chat/:chat_jid/history
✅ Chatwoot Sync History POST /chatwoot/sync
✅ Chatwoot Sync Status GET /chatwoot/sync/status
✅ List Chatwoot Configurations GET /chatwoot/configs
✅ Get Device Chatwoot Configuration GET /devices/:device_id/chatwoot/config
✅ Set Device Chatwoot Configuration PUT /devices/:device_id/chatwoot/config
✅ Delete Device Chatwoot Configuration DELETE /devices/:device_id/chatwoot/config
✅ Chatwoot Reply Webhook POST /chatwoot/webhook
✅ Device Chatwoot Reply Webhook POST /chatwoot/webhook/:device_id

✅ = available. * = has known limitations; see the notes below.

Notes:

User Interface

MCP UI

Web dashboard (gowa-ui)

The dashboard lives in its own repository: aldinokemal/gowa-ui. Each gowa-ui release publishes a single self-contained gowa-ui.html; the server downloads the latest release at startup (and every APP_UI_UPDATE_INTERVAL, which defaults to 3h), verifies its SHA-256 digest, caches it under storages/ui/, and serves it at / behind Basic Auth.

Setting Default Purpose
APP_UI_ENABLED true Serve the dashboard at /; false returns a JSON banner (API-only)
APP_UI_AUTO_UPDATE true Download/refresh from GitHub; disable for air-gapped deployments
APP_UI_REPO aldinokemal/gowa-ui Repository the updater follows—always its latest release, not a version pin
APP_UI_ASSET_NAME gowa-ui.html Release asset filename to download
APP_UI_UPDATE_INTERVAL 3h How often to check releases/latest
APP_UI_GITHUB_TOKEN (empty) Optional token to raise the GitHub API rate limit
APP_UI_ASSET_SHA256 (empty) Supply-chain pin: refuse any dashboard whose SHA-256 differs

Trust model: the release digest proves the download matches what GitHub advertises, not who published it. Operators who audit a specific build can pin it with APP_UI_ASSET_SHA256 (each release ships a .sha256 asset—this is the only setting that pins an exact build), point APP_UI_REPO at a fork they control (the updater still tracks that repo's latest release), or pre-seed the cache and disable auto-update entirely.

Air-gapped servers: place a downloaded gowa-ui.html at storages/ui/index.html and set APP_UI_AUTO_UPDATE=false. The dashboard can also be self-hosted anywhere static and pointed at this server's URL (see the gowa-ui README).

macOS Note

If you see invalid flag in pkg-config --cflags: -Xpreprocessor, run:

export CGO_CFLAGS_ALLOW="-Xpreprocessor"

Important

go-whatsapp-web-multidevice (aldinokemal/go-whatsapp-web-multidevice)

whatsapp
Searching Database…

What is this?GOWA is a self-hosted Go server that exposes WhatsApp as a REST API, so you can send messages, stickers and status updates, manage multiple linked WhatsApp accounts, and receive events via webhooks or an MCP server for AI agents.
Is this a CLI tool or a server I run and call over HTTP?It is a long-running server: you start the binary (or Docker image) and it exposes a REST API plus an optional web dashboard and an MCP endpoint, not a one-shot command-line tool.
How do I get it running and link my WhatsApp account?Download a prebuilt release binary or run the Docker image, start it with `./whatsapp rest`, then open the dashboard or API and scan the QR code to pair your WhatsApp account with the server.
Do I need a database or anything besides the binary?No external database is required; configuration is done through command-line flags, environment variables, or a .env file, and the dashboard HTML is fetched automatically at startup.
What changed recently that could trip up an existing setup?As of v9, MCP is no longer a separate mode — it is unified under `rest` and served at /mcp — and the web dashboard was moved out of this repo into gowa-ui, downloaded and SHA-256 verified at startup instead of being bundled.
Does it run as a plain server I self-host, or only via Docker?Both: prebuilt ARM and AMD64 binaries are available, and there's also a Docker Hub / GitHub Container Registry image, so you can run it as a native process or as a container on your own infrastructure.
Can I control multiple WhatsApp accounts from one server?Yes, since v8 the server supports multi-device management: you register multiple accounts under one instance and scope REST and WebSocket calls with a device ID.
What can I automate besides sending text messages?You can send stickers (auto-converted from JPG/PNG/GIF/WebP), post status updates, mention users (including 'ghost mentions' of a whole group), schedule one-time or recurring sends, and auto-reply or auto-reject incoming calls.
How do webhooks work and are they secure?Webhooks push events like messages, reactions, group changes and newsletter activity, each signed with an HMAC-SHA-256 signature in the X-Hub-Signature-256 header, and you can filter which events or chats are forwarded.
Can this plug into AI agents or workflow tools like n8n?Yes, it ships an MCP server (with optional OAuth 2.1) for AI agent integration, plus an official n8n community node (@aldinokemal2104/n8n-nodes-gowa) and Chatwoot support.
Size
27.7 MB
Stars
4.9K
Age
4y
Commits · 90 Days