DEV Community

Suharxxxx
Suharxxxx

Posted on

Building a WhatsApp Multi-Instance REST API with Go, Echo, and Whatsmeow ๐Ÿš€

Introduction
Ever needed to manage multiple WhatsApp accounts programmatically? Whether you're building a customer service platform, notification system, or automation tool, handling multiple WhatsApp instances can be challenging.

In this article, I'll share my journey building SUDEVWA - a production-ready WhatsApp Multi-Instance REST API using Go, Echo framework, and the powerful Whatsmeow library.

๐ŸŽฏ What We're Building
A REST API that can:

โœ… Manage multiple WhatsApp accounts simultaneously
โœ… Send/receive messages in real-time via WebSocket
โœ… Handle media files (images, videos, documents)
โœ… Maintain persistent sessions across server restarts
โœ… Auto-reconnect disconnected instances

๐Ÿ› ๏ธ Tech Stack
Go 1.21+ - Performance and concurrency
Echo v4 - Fast HTTP router
Whatsmeow - WhatsApp Web multidevice API
PostgreSQL - Session persistence
Gorilla WebSocket - Real-time communication

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Client โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ HTTP/WebSocket
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Echo API โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Service โ”‚ โ† Multi-instance manager
โ”‚ Layer โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Whatsmeow โ”‚ โ† WhatsApp protocol
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ PostgreSQL โ”‚ โ† Session storage
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿš€ Key Features Implementation

Multi-Instance Management

Each WhatsApp account is isolated as an "instance" with its own:
Database connection
Whatsmeow client
Event handlers
Session data

type Session struct {
    InstanceID  string
    Client      *whatsmeow.Client
    IsConnected bool
    JID         string
}

var sessions = make(map[string]*Session)

Enter fullscreen mode Exit fullscreen mode

Real-time Message Listener via WebSocket

Two WebSocket endpoints for different use cases:

Global WebSocket (/ws) - System events:

QR code generation
Login/logout events
Connection status changes
Instance-specific WebSocket (/api/listen/:instanceId) - Message inbox:
Incoming messages for specific instance

// Broadcast incoming messages to WebSocket clients
case *events.Message:
    Realtime.BroadcastToInstance(instanceID, map[string]interface{}{
        "event":       "incoming_message",
        "instance_id": instanceID,
        "from":        v.Info.Sender.String(),
        "message":     messageText,
        "timestamp":   v.Info.Timestamp.Unix(),
        "is_group":    v.Info.IsGroup,
    })

Enter fullscreen mode Exit fullscreen mode

Persistent Sessions with Auto-Reconnect

Sessions survive server restarts by storing device data in PostgreSQL:

func LoadAllDevices() error {
    devices, err := model.GetAllConnectedInstances()
    for _, device := range devices {
        // Recreate whatsmeow client
        client := whatsmeow.NewClient(device.Store, waLog.Stdout("Client", "INFO", true))
        client.AddEventHandler(eventHandler(device.InstanceID))

        // Reconnect
        if err := client.Connect(); err != nil {
            log.Printf("Failed to reconnect %s: %v", device.InstanceID, err)
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Ping-based WebSocket Keep-Alive

Prevent connection timeouts with automatic ping/pong:

func (c *Client) WritePump() {
    ticker := time.NewTicker(5 * time.Minute)
    defer ticker.Stop()

    for {
        select {
        case event := <-c.send:
            // Send message

        case <-ticker.C:
            // Send ping every 5 minutes
            if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
                return
            }
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Flexible Message Sending

Send messages by instance ID or phone number:

// By instance ID
POST /api/send/:instanceId
{
    "to": "628123456789",
    "message": "Hello!"
}

// By phone number (finds instance automatically)
POST /api/by-number/:phoneNumber
{
    "to": "628987654321",
    "message": "Hi there!"
}

Enter fullscreen mode Exit fullscreen mode

๐Ÿ“Š WebSocket Real-time Events
Example incoming message event:

{
  "event": "incoming_message",
  "timestamp": "2025-12-08T00:00:00Z",
  "data": {
    "instance_id": "instance123",
    "from": "6281234567890@s.whatsapp.net",
    "from_me": false,
    "message": "Hello World",
    "timestamp": 1733587980,
    "is_group": false,
    "message_id": "3EB0ABC123DEF456",
    "push_name": "John Doe"
  }
}

Enter fullscreen mode Exit fullscreen mode

๐Ÿ” Security & Best Practices

JWT Authentication - Protect all API endpoints
Rate Limiting - 10 requests/second per IP
CORS Configuration - Whitelist allowed origins
Number Validation - Verify WhatsApp registration before sending
Graceful Shutdown - Proper cleanup on logout

๐ŸŽฏ Use Cases

Customer Service - Multi-agent support with different WhatsApp numbers
Notifications - Send alerts from multiple business accounts
Chatbots - Build conversational AI with WhatsApp
Automation - Scheduled messages, bulk sending
Monitoring - Real-time message tracking dashboard

๐Ÿ“ˆ Performance Considerations

Goroutines for concurrent instance management
Channel-based event broadcasting
Connection pooling for PostgreSQL
Memory-efficient session storage
Auto-cleanup of ghost WebSocket connections (15min timeout)

๐Ÿšง Challenges & Solutions
Challenge 1: Session Persistence
Problem: Sessions lost on server restart
Solution: Store Whatsmeow device data in PostgreSQL, reload on startup

Challenge 2: Memory Leaks from Dead Connections
Problem: WebSocket connections not properly closed
Solution: Ping/pong mechanism with 15-minute timeout

Challenge 3: Race Conditions with Multiple Instances
Problem: Concurrent map access
Solution: sync.RWMutex for thread-safe operations

๐Ÿ”ฎ What's Next?
๐Ÿ“‹ Webhook support for incoming messages
๐Ÿ‘ฅ Group management (create, add members, etc.)
๐Ÿ“ฑ Status/story posting
๐Ÿ“Š Analytics dashboard
๐Ÿ”„ Message templates for bulk sending
๐Ÿ“ฆ Try It Yourself

The project is open-source and available on GitHub:

GitHub logo suharyadi2112 / Sudev-Whatsapp-Tools

WhatsApp Multi-Instance Manager A robust WhatsApp automation tool built with Go and Whatsmeow, designed for managing multiple WhatsApp instances with real-time monitoring and message handling capabilities.

๐Ÿ“ฑ SUDEVWA - WhatsApp Multi-Device API (Go)

REST API for managing WhatsApp Web Multi-Device using Go, Echo, PostgreSQL, and whatsmeow.

โœจ Key Features

๐Ÿ” Authentication & Instance Management

  • Multi-instance โ€” manage multiple WhatsApp numbers simultaneously
  • QR Code authentication โ€” generate QR for device pairing
  • Persistent sessions โ€” sessions survive restart, stored in PostgreSQL
  • Auto-reconnect โ€” instances automatically reconnect after server restart
  • Instance reusability โ€” logged out instances can scan QR again without creating new instance
  • Graceful logout โ€” complete cleanup (device store + session memory)

๐Ÿ’ฌ Messaging

  • Send text messages (by instance ID or by phone number)
  • Send media from URL / file upload
  • Support text, image, video, document
  • Recipient number validation before sending
  • Real-time incoming message listener โ€” listen to incoming messages via WebSocket per instance

๐Ÿ”Œ Real-time Features (WebSocket)

  • Global WebSocket (/ws) โ€” monitor QR events, status changes, system events for all instances
  • โ€ฆ






# Clone repository
git clone https://github.com/suharyadi2112/Sudev-Whatsapp-Tools.git
cd Sudev-Whatsapp-Tools

# Setup environment
cp .env.example .env
# Edit .env with your PostgreSQL credentials

# Run migrations
go run main.go --createschema

# Start server
go run main.go

Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:2121 and you're ready! ๐ŸŽ‰

๐Ÿ’ก Key Takeaways
Whatsmeow makes WhatsApp automation accessible in Go

WebSocket perfect for real-time messaging features

PostgreSQL essential for session persistence

Multi-instance architecture enables scalability

Event-driven design keeps code maintainable

๐Ÿค Contribute
Found this useful? Consider:

โญ Star the repository
๐Ÿ› Report issues
๐Ÿ”ง Submit pull requests
๐Ÿ’ฌ Share feedback
๐Ÿ“š Resources

Whatsmeow Documentation

Echo Framework Guide
Gorilla WebSocket

What's your experience with WhatsApp automation? Have questions about the implementation? Drop a comment below! ๐Ÿ‘‡

golang #go #whatsapp #api #websocket #opensource #tutorial

Top comments (0)