Executando verificação de segurança...
5

Melhorando a performance de APIs baseadas em WhatsApp Web com Go (Open Source)

Olá, pessoal!

Gostaria de compartilhar um projeto que desenvolvi para melhorar a performance e a latência em fluxos de automação (como n8n e Typebot) integrados ao WhatsApp Web.

Muitas soluções atuais são baseadas em Node.js. Embora excelentes, elas podem ser pesadas para VPS de entrada (512MB/1GB RAM) quando precisamos escalar para múltiplas instâncias.

Construí a apime utilizando Go e a biblioteca whatsmeow. O objetivo foi criar uma camada de orquestração que permita estabilidade mesmo em infraestruturas mais limitadas.

Principais decisões técnicas da arquitetura:

Performance: Binário compilado em Go, garantindo execução nativa e baixo overhead.

Protocolo: Implementação baseada no protocolo web (não oficial) via whatsmeow, visando automações de baixo custo.

Persistência e Cache: Uso de Postgres para dados relacionais e Redis para gerenciamento de estado e filas, garantindo que as sessões não caiam em reboots.

Dashboard Integrado: Interface minimalista para gerenciamento de instâncias e pareamento via QR Code sem necessidade de terminal.

Webhooks: Fluxo de eventos pronto para integração direta com ferramentas de workflow.

O projeto é 100% Open Source e focado em quem precisa de uma solução self-hosted leve para iniciar testes e estudar o funcionamento de automações.

Repositório no GitHub: https://github.com/open-apime/apime

Gostaria de saber da comunidade: alguém aqui utiliza Go para microsserviços de mensageria? Como tem sido a experiência de vocês em comparação a outras stacks?

Carregando publicação patrocinada...
1

Opa, olha só eu uso já em dois clientes a WhatsMeow, mas facilmente usariamos a ApiMe com algumas adaptações, possivelmente vamos usar nas próximas.

O que achei muito bom, bem estruturado, camadas separadas (handlers → services → repositories), factory pattern para storage, já suporta troca entre postgres e memory via config, interfaces bem definidas.

Segurança, autenticação JWT (usuário), API Token (programático), Instance Token (por instância), RBAC implementado, Admin vs User roles, webhooks assinados com HMAC-SHA256 para verificação. Graceful shutdown e restauração de sessões, reconecta instâncias automaticamente no restart.

Questões a observar, eu acho o Redis desnecessário para casos simples:

No factory.go:30-38:
// Inicializar Redis (sempre necessário para webhooks)
redisClient, err := redis.New(cfg.Redis, log)

O Redis é usado apenas como fila de webhooks com operações simples, LPush para enfileirar, BRPop para desenfileirar (bloqueante). Isso pode ser feito in-memory com um channel Go.

type InMemoryQueue struct {
events chan Event
}

O uso atual do Redis é overkill para instalações single-node, desenvolvimento local, casos com poucas instâncias.

Quando Redis faz sentido é em casos de múltiplas réplicas do API (horizontal scaling), persistência de eventos durante restart, monitoramento externo da fila

PostgreSQL vs In-Memory, o driver memory já existe e funciona, mas não há persistência, ao reiniciar, perde-se tudo (usuários, instâncias, tokens).

SQLite seria melhor que PostgreSQL para, single-node deployments, desenvolvimento local, ambientes com poucos recursos, já está sendo usado para sessões WhatsMeow.

PostgreSQL faz sentido em multi-tenant com muitos usuários, backup e replicação necessários, queries complexas (que não existem no código atual), compliance/auditoria.

O projeto já usa SQLite para sessões WhatsMeow (por instância), postgreSQL para metadados da instância. Isso cria complexidade desnecessária.

Outra coisa, o webhook trabalha single-threaded.

Em worker.go:38-50:
for {
select {
case <-ctx.Done():
return
default:
w.processNext(ctx) // Um evento por vez
}
}

Processa eventos sequencialmente, para alto throughput, deveria ter worker pool.

Vi também que está sem rate limiting, não há proteção contra abuse na API. Qualquer token válido pode fazer requests ilimitados.

Para a maioria dos casos de uso (desenvolvimento, single-node, poucas instâncias), PostgreSQL e Redis são overhead desnecessário. O projeto já tem 90% da implementação in-memory pronta, falta apenas:

  1. Criar QueueDriver in-memory (channel Go)
  2. Tornar Redis opcional no factory.go
  3. Considerar SQLite como opção de persistência leve

A arquitetura atual é preparada para enterprise mas adiciona complexidade de infra que muitos usuários não precisam.

2

Opa,

A ideia do Redis/Postgres foi pensando em escalabilidade logo de cara, mas concordo com você, pra maioria dos casos vira um overhead desnecessário. Vou ajustar pra tornar o Redis opcional e considerar o SQLite para os metadados.

Vou implementar e testar também os demais pontos que você levantou e conforme eu for ajustando atualizo aqui.

Valeu mesmo pelo review, feedback e considerações!

1

Gostei do que você criou. Vou fazer um teste para ver se ficou bom, mas tenho uma dúvida: sincroniza as mensagens enviadas pelo celular? Elas chegam no webhook ou algo assim?

1
1
1

em geral é bem rapido.

A demora está acontecendo após a leitura do qrcode e no dispositivo fica na tela de leitura ou o qrcode que está demorando pra carregar?

1

valeu pelo feedback, ajustes realizados e a conexão está sendo liberada rapidamente, além disso realizei mais algumas melhorias e correçoes..

0
1