API HTTP em Go para gerenciar instâncias do WhatsApp com Whatsmeow.
whatsapp-go-api expõe funcionalidades do WhatsApp por meio de uma API HTTP escrita em Go. O projeto usa Whatsmeow para a integração com o WhatsApp e Fiber v3 para o servidor HTTP.
A aplicação permite criar e autenticar múltiplas instâncias, conectar uma sessão por QR Code ou código de pareamento, consultar estado de conexão, enviar mensagens, operar recursos de chat e grupo, persistir dados no PostgreSQL e encaminhar eventos por webhook.
Este projeto não usa a API oficial do WhatsApp.
- Gerenciamento de instâncias com token próprio por instância.
- Autenticação administrativa global por header de API key.
- Conexão por QR Code.
- Conexão por código de pareamento com telefone.
- Fluxo de pareamento por passkey.
- Estado de conexão, logout e remoção de instância.
- Envio de texto, link com preview, mídia por base64, mídia por upload, áudio no formato WhatsApp, contato, localização e reação.
- Opções de mensagem para presença, delay, citação e menções.
- Operações de chat para validação de números, leitura, arquivamento, exclusão, edição, foto de perfil, rejeição de chamada e download de mídia.
- Operações de grupo para criação, foto, convite, revogação de convite, participantes e saída.
- Webhooks por instância e webhook global opcional.
- Persistência opcional de mensagens, atualizações de mensagem e contatos.
- Persistência de sessões Whatsmeow em PostgreSQL ou SQLite.
- Reconexão automática de sessões persistidas no startup.
- Migrations SQL internas para o banco principal.
- Especificação OpenAPI estática para endpoints de mensagem.
- Go
1.26. - Fiber
v3.4.0. - Whatsmeow
v0.0.0-20260630180629-b572e5bcb92b. - PostgreSQL via
pgx/v5. - SQLite via
go-sqlite3para store de sessão Whatsmeow. sqlcpara código de acesso a dados já gerado no repositório.zerologpara logs.go-playground/validatorpara validação.golang-jwt/jwt/v5para tokens por instância.aircomo ferramenta opcional de desenvolvimento, com.air.tomljá presente.
.
|-- cmd/
| |-- api/
| |-- migrate/
| `-- webhook-docs/
|-- docs/
|-- internal/
| |-- app/
| |-- authentication/
| |-- chat/
| |-- config/
| |-- database/
| |-- group/
| |-- http/
| |-- instance/
| |-- message/
| |-- webhook/
| `-- whatsapp/
|-- tests/
|-- .air.toml
|-- .env.dev
|-- go.mod
|-- go.sum
`-- sqlc.yaml
Executáveis em cmd/:
cmd/api: inicia a API HTTP.cmd/migrate: executa migrations do banco principal e inicializa as migrations da store Whatsmeow.cmd/webhook-docs: regeneradocs/webhooks.mda partir do contrato interno de webhooks.
Para desenvolvimento local:
- Git, caso ainda precise clonar o projeto.
- Go compatível com
go 1.26. - PostgreSQL acessível pela variável
DATABASE_URL. - Opcionalmente Air para hot reload.
- Opcionalmente SQLite quando
WHATSAPP_SESSION_STORE=sqlite.
Para produção:
- Go ou um binário compilado da API.
- PostgreSQL para o banco principal.
- Store de sessão Whatsmeow em PostgreSQL ou SQLite, conforme configuração.
- Variáveis de ambiente seguras para autenticação e conexão.
Para Docker:
- Docker Engine ou Docker Desktop com
docker compose. - BuildKit/Buildx para builds multiplataforma.
- PostgreSQL acessível pela rede usada pelo container.
- FFmpeg não precisa ser instalado no host quando a API roda pela imagem Docker; a imagem final já contém
ffmpegeffprobe.
Instale o Go pela página oficial: go.dev/dl.
- Windows: use o instalador
.msioficial e abra um novo terminal após a instalação. - macOS: use o pacote oficial
.pkgou um gerenciador de pacotes de sua preferência. - Linux: use o pacote oficial ou o repositório da sua distribuição.
Valide a instalação:
go versionO diretório de binários do Go precisa estar no PATH para comandos instalados com go install. Versões anteriores à diretiva go 1.26 do go.mod não são suportadas por este projeto.
O projeto possui .air.toml, então o Air pode ser usado como dependência opcional de desenvolvimento:
go install github.com/air-verse/air@latestO binário normalmente é instalado em:
go env GOPATHNo Linux ou macOS, se air não estiver no PATH, adicione o diretório de binários do Go:
export PATH="$PATH:$(go env GOPATH)/bin"Depois execute:
airA configuração atual compila ./cmd/api/main.go e gera o binário temporário em tmp/main.exe.
O repositório contém Dockerfile, docker-compose.yml, .env.docker.example e scripts/build-and-push.sh para executar e publicar a API em container.
Links oficiais:
Valide a instalação:
docker version
docker compose versionUse docker compose; não use o comando legado docker-compose.
git clone https://github.com/code-chat-br/whatsapp-api-go.git
cd whatsapp-go-apigo mod download
go mod verifyPara execução local fora de Docker, a aplicação carrega .env. Use o arquivo de referência existente:
cp .env.dev .envNo Windows PowerShell:
Copy-Item .env.dev .envVariáveis mínimas para iniciar a API:
DOCKER_ENV=falseSERVER_PORTDATABASE_URLAUTHENTICATION_JWT_EXPIRES_INAUTHENTICATION_JWT_SECRETAUTHENTICATION_GLOBAL_AUTH_TOKENQRCODE_LIMITQRCODE_EXPIRATION_TIMEQRCODE_LIGHT_COLORQRCODE_DARK_COLORWHATSAPP_AUTO_RECONNECTWHATSAPP_STARTUP_RECONNECT_CONCURRENCYWHATSAPP_CONNECT_TIMEOUTWHATSAPP_RECONNECT_INITIAL_DELAYWHATSAPP_RECONNECT_MAX_DELAYWHATSAPP_PROFILE_PICTURE_TIMEOUT
Consulte a documentação de variáveis de ambiente para a lista completa.
O banco principal da API é PostgreSQL, configurado por DATABASE_URL. Crie o banco antes de iniciar a aplicação, antes de executar migrations.
CREATE DATABASE WHATSAPP;Configure a URL no .env, por exemplo:
DATABASE_URL="postgres://postgres:postgres@postgres.local:5432/whatsapp?sslmode=disable"A store de sessão Whatsmeow é escolhida por WHATSAPP_SESSION_STORE:
postgres: usaWHATSAPP_SESSION_POSTGRES_URLquando preenchida, ouDATABASE_URLquando vazia.sqlite: usaWHATSAPP_SESSION_SQLITE_DSN, com valor padrão compatível comfile:./data/whatsmeow.db?_foreign_keys=on.
A API executa as migrations no startup. Também existe um comando dedicado:
go run ./cmd/migrateAs migrations do banco principal ficam em internal/database/migrations e registram o estado em schema_migrations. Há arquivos .down.sql, mas o código atual não expõe comando de rollback nem comando de status.
Leia mais em Migrations.
go run ./cmd/apiCom Air:
airPor padrão, quando SERVER_PORT não é alterado, a API escuta em:
http://localhost:8084
Rotas públicas de saúde:
GET /health
GET /ready
Linux ou macOS:
go build -o ./api ./cmd/apiWindows PowerShell:
go build -o .\api.exe .\cmd\apiO container executa a API pelo entrypoint real ./cmd/api, compilado como /app/codechat-api. A imagem final usa Alpine, instala ffmpeg e ffprobe, define DOCKER_ENV=true, roda como usuário não-root app e mantém as migrations em /app/internal/database/migrations, porque o runner atual lê internal/database/migrations do filesystem.
Imagem oficial no DockerHub.
docker run --rm \
--env-file .env \
-p 8084:8084 \
codechat/whatsapp-go-api:latestNo Docker, mantenha DOCKER_ENV=true. A porta interna padrão é 8084, lida de SERVER_PORT, e as rotas públicas de saúde são:
GET /health
GET /ready
Crie um arquivo .env a partir do exemplo e preencha as variáveis reais. Não versiona secrets.
cp .env.docker.example .env
docker compose up -dLogs:
docker compose logs -f codechat-apiEncerrar:
docker compose downO Compose não publica a porta no host por padrão; ele usa expose para o Traefik. Para teste local direto sem Traefik, use docker run -p 8084:8084 ou um arquivo override próprio com ports.
Crie a rede externa somente se ela ainda não existir:
docker network create public_networkO serviço entra nas redes codechat_network e traefik_network. A rede externa é parametrizada por:
TRAEFIK_NETWORK=public_networkRegra padrão:
Host(`api.codechat.local`)
Variáveis principais:
API_HOST=api.codechat.local
TRAEFIK_ENTRYPOINT=websecure
TRAEFIK_TLS=true
TRAEFIK_CERT_RESOLVER=letsencryptA porta configurada no load balancer Traefik é a mesma da aplicação:
traefik.http.services.codechat-api.loadbalancer.server.port=8084
O arquivo base não adiciona labels vazias para middlewares ou serversTransport. Quando precisar referenciar middlewares externos, adicione-os em um override de produção, por exemplo:
services:
codechat-api:
labels:
- "traefik.http.routers.codechat-api.middlewares=compress@file,cors@file"
- "traefik.http.services.codechat-api.loadbalancer.serverstransport=sse_transport@file"Não configure timeouts no Traefik que encerrem conexões persistentes, porque a API usa conexões HTTP longas durante fluxos de WhatsApp e uploads.
A imagem Docker contém:
/usr/bin/ffmpeg
/usr/bin/ffprobe
Variáveis usadas dentro do container:
FFMPEG_PATH=/usr/bin/ffmpeg
FFPROBE_PATH=/usr/bin/ffprobe
TMPDIR=/app/tmpFora do Docker, se FFMPEG_PATH e FFPROBE_PATH não forem definidas, a aplicação continua procurando ffmpeg e ffprobe no PATH.
Verificar no container:
docker compose exec codechat-api ffmpeg -version
docker compose exec codechat-api ffprobe -versionInstalação fora do Docker:
Ubuntu e Debian:
sudo apt-get update
sudo apt-get install -y ffmpegAlpine:
apk add --no-cache ffmpegmacOS:
brew install ffmpegWindows:
winget install --id Gyan.FFmpegValide:
ffmpeg -version
ffprobe -versionAs variáveis estão agrupadas nas seguintes áreas:
- Servidor HTTP: porta e modo de execução.
- Logs: nível de log.
- Banco principal: URL e persistência opcional de mensagens, atualizações e contatos.
- Autenticação: segredo JWT, expiração e token global.
- WhatsApp: QR Code, dispositivo vinculado, timeouts e reconexão.
- Sessões Whatsmeow: backend
postgresousqlite. - Webhooks: URL global e ativação global.
- Processamento de mensagens: workers, fila e timeouts.
Consulte a documentação de variáveis de ambiente.
A documentação técnica completa está disponível em /docs.
- Variáveis de ambiente: descreve execução local, execução em Docker e configuração da store de sessões Whatsmeow.
- Migrations: resume o comando dedicado de migrations e o comportamento no startup.
- Pareamento por Passkey: detalha endpoints, headers, estados e limitações do fluxo de passkey.
- Envio de mensagens: documenta corpos, respostas, opções, fila, erros e limitações dos endpoints de mensagem.
- Webhooks: descreve configuração, envelope, headers, entrega e payloads dos eventos suportados.
- OpenAPI: especificação OpenAPI estática dos endpoints de envio de mensagem.
A API usa dois escopos de autenticação.
Autenticação administrativa global:
- Protege criação e listagem de instâncias.
- Usa o valor de
AUTHENTICATION_GLOBAL_AUTH_TOKEN. - Headers aceitos:
apikey,x-api-keyeapiKey. - Se mais de um desses headers for enviado, os valores precisam ser iguais.
Exemplo:
apikey: <GLOBAL_API_KEY>Autenticação por instância:
- Protege conexão, estado, logout, remoção, token refresh, webhooks, mensagens, chats e grupos.
- Usa JWT gerado na criação da instância.
- O token precisa pertencer ao
:instanceNameda rota.
Exemplo:
Authorization: Bearer <INSTANCE_TOKEN>Os exemplos abaixo usam dados fictícios e assumem a API em http://localhost:8084.
curl -X POST "http://localhost:8084/instance/create" \
-H "Content-Type: application/json" \
-H "apikey: <GLOBAL_API_KEY>" \
-d '{
"instanceName": "minha-instancia",
"description": "Instância de desenvolvimento"
}'A resposta inclui auth.token. Use esse valor como <INSTANCE_TOKEN>.
curl -X GET "http://localhost:8084/instance/connect/minha-instancia" \
-H "Authorization: Bearer <INSTANCE_TOKEN>"A resposta contém o código e o QR Code em base64 quando a instância ainda não está conectada.
curl -X GET "http://localhost:8084/instance/connect/minha-instancia/code/5511999999999" \
-H "Authorization: Bearer <INSTANCE_TOKEN>"curl -X GET "http://localhost:8084/instance/connectionState/minha-instancia" \
-H "Authorization: Bearer <INSTANCE_TOKEN>"curl -X POST "http://localhost:8084/message/sendText/minha-instancia" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <INSTANCE_TOKEN>" \
-d '{
"number": "5511999999999",
"textMessage": {
"text": "Olá!"
}
}'curl -X PUT "http://localhost:8084/webhook/set/minha-instancia" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <INSTANCE_TOKEN>" \
-d '{
"url": "https://example.com/webhooks/whatsapp",
"enabled": true,
"events": {
"qrcodeUpdated": true,
"connectionUpdated": true,
"messagesUpsert": true,
"sendMessage": true
}
}'O projeto possui especificação OpenAPI estática em docs/openapi.yaml. O servidor HTTP atual não registra rota de Swagger, Scalar ou Redoc.
Endpoints de mensagem implementados:
POST /message/sendText/:instanceNamePOST /message/sendLink/:instanceNamePOST /message/sendMedia/:instanceNamePOST /message/sendMediaFile/:instanceNamePOST /message/sendWhatsAppAudio/:instanceNamePOST /message/sendWhatsAppAudioFile/:instanceNamePOST /message/sendContact/:instanceNamePOST /message/sendLocation/:instanceNamePOST /message/sendReaction/:instanceName
As opções aceitas incluem delay, presence, quotedMessageId, quotedMessage, externalAttributes e mentionAll. Para detalhes de payload, respostas e limitações, consulte Envio de mensagens.
O webhook por instância é configurado por:
PUT /webhook/set/:instanceName
GET /webhook/find/:instanceName
O corpo de configuração aceita:
url: URL HTTP ou HTTPS de destino.enabled: habilita ou desabilita a entrega da instância.events: objeto com flags por evento, usando campos comoqrcodeUpdated,connectionUpdated,messagesUpsertesendMessage.
Também existe webhook global opcional por WEBHOOK_GLOBAL_URL e WEBHOOK_GLOBAL_ENABLED.
O envelope geral entregue é:
{
"event": "messages.upsert",
"instance": {
"id": 1,
"name": "minha-instancia",
"connectionStatus": "ONLINE",
"ownerJid": "5511999999999@s.whatsapp.net",
"externalAttributes": {}
},
"data": {},
"timestamp": "2026-07-07T12:00:00Z"
}Headers enviados:
Content-TypeUser-Agentx-request-idx-owner-jidx-instance-namex-instance-idx-webhook-event
A entrega é assíncrona por fila em memória. Falhas são registradas em log; o código atual não implementa retry persistente.
Consulte Webhooks para o mapa completo de eventos e payloads.
As sessões e dispositivos do WhatsApp são persistidos pela sqlstore do Whatsmeow.
Backend configurável:
WHATSAPP_SESSION_STORE="postgres"Valores aceitos:
postgres: usaWHATSAPP_SESSION_POSTGRES_URLou, quando vazia,DATABASE_URL.sqlite: usaWHATSAPP_SESSION_SQLITE_DSN.
Quando WHATSAPP_AUTO_RECONNECT=true, o startup tenta restaurar as sessões persistidas. O número de restaurações concorrentes é controlado por WHATSAPP_STARTUP_RECONNECT_CONCURRENCY.
Consulte Variáveis de ambiente.
O projeto implementa endpoints de pareamento por passkey:
POST /instance/connect/:instanceName/passkey/challenge
POST /instance/connect/:instanceName/passkey/assertion
O fluxo cria um challenge temporário para a instância e espera a assertion do cliente. Ele depende da mesma autenticação por instância via Authorization: Bearer <INSTANCE_TOKEN>.
Consulte Pareamento por Passkey para requisitos, estados, erros e limitações.
go mod download
go mod verify
go run ./cmd/migrate
go run ./cmd/api
go run ./cmd/webhook-docs
go test ./...
go vet ./...
go build ./...
airNão há Makefile ou Taskfile no repositório atual.
Execute:
go test ./...Alguns testes e caminhos de inicialização dependem de configuração válida de ambiente e PostgreSQL quando exercitam banco real. A suíte existente também possui testes unitários para configuração, HTTP, mensagens, webhooks e WhatsApp.
- Go em versão incompatível: confirme
go versione use uma versão compatível comgo 1.26. air: command not found: instale comgo install github.com/air-verse/air@lateste adicione$(go env GOPATH)/binaoPATH..envausente em execução local: copie.env.devpara.env.DATABASE_URLausente ou inválida: confira a URL do PostgreSQL e o parâmetrosslmodequando necessário.- PostgreSQL indisponível: valide host, porta, credenciais e existência do banco.
- Migrations pendentes ou falhando: execute
go run ./cmd/migratee confira a tabelaschema_migrations. - Porta em uso: altere
SERVER_PORTno.env. - Sessão não reconectada: confirme
WHATSAPP_AUTO_RECONNECT=true, store de sessão correta e registros de estado da instância. - QR Code expirado: solicite novamente
GET /instance/connect/:instanceName. - Token recusado: confirme se o header é
Authorization: Bearer <INSTANCE_TOKEN>e se o token pertence ao mesmoinstanceName. - Webhook sem entrega: confira
enabled,events, URL HTTP/HTTPS e logs de falha da fila.
Este projeto não é afiliado, patrocinado ou endossado pelo WhatsApp ou pela Meta. Ele usa uma integração não oficial via Whatsmeow, e alterações no protocolo do WhatsApp podem causar interrupções.
O usuário é responsável por cumprir leis, termos de serviço e políticas aplicáveis. Não use a API para spam, abuso ou envio de mensagens sem consentimento.
Cuidados operacionais:
- Não envie tokens, chaves,
.envou bancos de sessão ao Git. - Use valores fortes para
AUTHENTICATION_JWT_SECRETeAUTHENTICATION_GLOBAL_AUTH_TOKEN. - Evite registrar tokens, números completos, conteúdos de mensagem ou dados sensíveis em logs.
- Proteja o acesso HTTP com rede privada, proxy autenticado ou controles equivalentes em produção.
Este projeto é disponibilizado sob a licença GNU Affero General Public License v3.0, utilizando o identificador SPDX AGPL-3.0-only.
O uso comercial é permitido sob os termos da AGPL. Organizações que necessitem manter modificações privadas, incorporar o projeto em software proprietário ou utilizar termos diferentes podem solicitar uma licença comercial separada.
Componentes de terceiros permanecem sujeitos às suas respectivas licenças. Consulte também os arquivos NOTICE e THIRD_PARTY_NOTICES.md.
Este projeto não é oficial, não é afiliado à Meta ou ao WhatsApp, e o usuário é responsável por cumprir leis, termos de serviço e políticas aplicáveis.
Leia CONTRIBUTING.md antes de enviar contribuições. Contribuições externas poderão exigir aceite do CLA.md.