go-whatsapp-web-multidevice

repository·main·Indexed 26 days ago

https://github.com/aldinokemal/go-whatsapp-web-multidevice

A high-performance WhatsApp Web multi-device API written in Go. It provides a REST and Model Context Protocol (MCP) interface to send messages, manage multiple accounts, and receive webhooks for WhatsApp events. Features include support for multi-device scoping via X-Device-Id headers, automated presence management, and a comprehensive set of MCP tools for AI agents to handle messaging, contacts, and group management.

Tokens
35.1K
Snippets
72
Records
147
Agent score
89%

What's inside go-whatsapp-web-multidevice

  1. Project Limitations and Warnings

    main

    Important Notices

    • Unofficial Status: This project is unofficial and is not affiliated with WhatsApp. It is recommended to use the official WhatsApp API to avoid issues.
    • Capability Limitation: Due to limitations in the underlying whatsmeow library, this project can only run MCP (Model Context Protocol) or REST API. Independent MCP will be available in the future.
  2. Enable Direct Database Import for Chatwoot History Sync

    main

    For self-hosted Chatwoot deployments, you can enable direct PostgreSQL import to sync message history. This method is recommended over the REST API because it preserves original WhatsApp timestamps, preserves correct group names, is significantly faster, and is idempotent.

    Setup Steps

    1. Ensure the Go WhatsApp API service has network access to Chatwoot's PostgreSQL database (port 5432).
    2. Set the CHATWOOT_IMPORT_DB_URI environment variable with your connection string. If your password contains URL-reserved characters (like @, :, /, ?, #), you must percent-encode them (e.g., @ becomes %40).
    3. Enable history import using CHATWOOT_IMPORT_MESSAGES=true.
    4. (Optional) Set CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGES to limit how many days of history to import.

    Behavior

    • Historical sync: Triggered on connect or via manual /chatwoot/sync. It writes directly to Chatwoot's PostgreSQL tables.
    • Live messages: Incoming WhatsApp messages and Chatwoot webhook replies continue to use the REST API to ensure Chatwoot's event pipeline (automations, assignment rules) works correctly.
    • Media: If CHATWOOT_IMPORT_MEDIA_WITH_REST=true is set, downloadable media is uploaded via REST first to ensure Chatwoot ActiveStorage attachments are created, then the direct-DB import skips those rows to avoid duplication.
    environment:
      - CHATWOOT_ENABLED=true
      - CHATWOOT_URL=https://chatwoot.example.com
      - CHATWOOT_API_TOKEN=your_api_token
      - CHATWOOT_ACCOUNT_ID=1
      - CHATWOOT_INBOX_ID=1
      - CHATWOOT_DEVICE_ID=my-device
      - CHATWOOT_IMPORT_MESSAGES=true
      - CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGES=7
      - CHATWOOT_IMPORT_DB_URI=postgresql://postgres:password@chatwoot-db:5432/chatwoot_production?sslmode=disable
  3. Deploy Production REST via Docker

    main

    For production deployment, use Docker with persistent storage for sessions.

    Using Docker Hub:

    docker run --detach --publish=3000:3000 --name=whatsapp --restart=always --volume=$(docker volume create --name=whatsapp):/app/storages aldinokemal2104/go-whatsapp-web-multidevice rest --autoreply="Dont't reply this message please"

    Using GitHub Container Registry:

    docker run --detach --publish=3000:3000 --name=whatsapp --restart=always --volume=$(docker volume create --name=whatsapp):/app/storages ghcr.io/aldinokemal/go-whatsapp-web-multidevice rest --autoreply="Dont't reply this message please"
  4. Configure the application using environment variables

    main

    The application can be configured using three methods, ordered by priority:

    1. Command-line flags (Highest priority)
    2. Environment variables
    3. .env file (Lowest priority)

    To set up environment variables via a .env file:

    1. Copy the example file to your project root: cp src/.env.example src/.env
    2. Modify the values in .env as needed.
    3. Alternatively, set them as system environment variables.
    cp src/.env.example src/.env
  5. Configure Webhook Endpoints

    main

    You can configure one or more webhook URLs to receive WhatsApp events. You can set these via command-line flags when running the rest command or via environment variables.

    Command Line Flags:

    • --webhook: The URL(s) to send webhooks to. Use a comma-separated list for multiple endpoints.
    • --webhook-secret: A secret key used to sign payloads for HMAC verification.

    Environment Variables:

    • WHATSAPP_WEBHOOK: Single or comma-separated list of webhook URLs.
    • WHATSAPP_WEBHOOK_SECRET: The secret key for signature verification.
    # Single webhook
    ./whatsapp rest --webhook="https://yourapp.com/webhook"
    
    # Multiple webhooks
    ./whatsapp rest --webhook="https://app1.com/webhook,https://app2.com/webhook"
    
    # Custom secret
    ./whatsapp rest --webhook-secret="your-secret-key"
  6. Verify Webhook Signatures

    main

    To ensure webhook authenticity, the system sends an HMAC SHA256 signature in the x-hub-signature-256 header. You should verify this signature using your configured WHATSAPP_WEBHOOK_SECRET and the raw request body.

    Implementation Requirements:

    1. Use the raw request body for signature calculation.
    2. The signature header format is sha256=<hash>.
    3. Use a constant-time comparison function to prevent timing attacks.
    const crypto = require('crypto');
    
    function verifyWebhookSignature(payload, signature, secret) {
        const expectedSignature = crypto
            .createHmac('sha256', secret)
            .update(payload, 'utf8')
            .digest('hex');
    
        const receivedSignature = signature.replace('sha256=', '');
        return crypto.timingSafeEqual(
            Buffer.from(expectedSignature, 'hex'),
            Buffer.from(receivedSignature, 'hex')
        );
    }
  7. Install and Run from Source

    main

    To run from source, you must have Go 1.25.5 or higher and FFmpeg installed on your system.

    Basic REST API mode:

    1. Clone the repository.
    2. Navigate to the src directory.
    3. Run go run . rest.
    4. Access the service at http://localhost:3000.
    git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice
    cd go-whatsapp-web-multidevice/src
    go run . rest
  8. Verify Webhook HMAC Signatures

    main

    To secure your webhook endpoint, verify the X-Hub-Signature-256 header. The signature follows the format sha256={signature} and is generated using HMAC SHA256 with a secret configured via --webhook-secret or WHATSAPP_WEBHOOK_SECRET (default is secret).

    ### Verification Example (Node.js)
    
    ```javascript
    const crypto = require('crypto');
    
    function verifyWebhookSignature(payload, signature, secret) {
        const expectedSignature = crypto
            .createHmac('sha256', secret)
            .update(payload, 'utf8')
            .digest('hex');
    
        const receivedSignature = signature.replace('sha256=', '');
        return crypto.timingSafeEqual(
            Buffer.from(expectedSignature, 'hex'),
            Buffer.from(receivedSignature, 'hex')
        );
    }

    Verification Example (Python)

    import hmac
    import hashlib
    
    def verify_webhook_signature(payload, signature, secret):
        expected_signature = hmac.new(
            secret.encode('utf-8'),
            payload,
            hashlib.sha256
        ).hexdigest()
    
        received_signature = signature.replace('sha256=', '')
        return hmac.compare_digest(expected_signature, received_signature)
  9. Sync WhatsApp message history to Chatwoot

    main

    You can import existing WhatsApp messages into Chatwoot to provide context for agents.

    Automatic Sync: Enable CHATWOOT_IMPORT_MESSAGES=true and set CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGES (e.g., 7) to sync history whenever a device connects.

    Manual Sync: Trigger a sync via the REST API for a specific device.

    # Start Sync
    curl -X POST "http://your-api:3000/chatwoot/sync" \
      -H "Content-Type: application/json" \
      -d '{
        "device_id": "my-device-id",
        "days_limit": 7,
        "include_media": true,
        "include_groups": true
      }'
    
    # Check Sync Status
    curl "http://your-api:3000/chatwoot/sync/status?device_id=my-device-id"
  10. Integrate Go WhatsApp Web Multidevice with Chatwoot

    main

    The Chatwoot integration allows you to receive WhatsApp messages in a Chatwoot inbox and reply to them directly from Chatwoot. It supports text, images, audio, video, and file attachments for both individual and group chats.

    Prerequisites

    • Go WhatsApp Web Multidevice running and accessible via a public URL.
    • Chatwoot instance (self-hosted or cloud) with admin access.
    • An API Channel inbox created in Chatwoot.
    • At least one WhatsApp device connected and logged in.
  11. Install and Run via Docker

    main

    The easiest way to run the project is using Docker, which handles all dependencies like FFmpeg and libwebp automatically.

    Quickstart with Docker Compose:

    1. Clone the repository.
    2. Run docker-compose up -d --build.
    3. Access the service at http://localhost:3000.
    git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice
    cd go-whatsapp-web-multidevice
    docker-compose up -d --build
  12. Step-by-Step Chatwoot Setup Guide

    main

    Step 1: Create an API Channel Inbox

    1. Log in to Chatwoot dashboard.
    2. Navigate to Settings > Inboxes.
    3. Click Add Inbox and select API as the channel type.
    4. Configure the name (e.g., WhatsApp) and leave the Webhook URL empty for now.
    5. Click Create Inbox and note the Inbox ID.

    Step 2: Get Your API Token

    1. Navigate to Settings > Profile Settings.
    2. Copy the Access Token.

    Step 3: Find Your Account ID

    Your account ID is in the URL: https://app.chatwoot.com/app/accounts/[ACCOUNT_ID]/dashboard.

    Step 4: Configure the API Channel Webhook

    1. Navigate to Settings > Inboxes and open your API-channel inbox.
    2. Set the API channel webhook URL to: https://your-gowa.example.com/chatwoot/webhook?secret=strong-shared-secret.
    3. Save the inbox.

    Note: If running GOWA locally, use a service like ngrok to provide a public URL.