-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Evolution API - Multi-Device Fix #2332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Reviewer's GuideThis PR changes the WhatsApp Baileys client initialization to rely on Baileys’ native multi‑device mode instead of identifying as a WebClient, and adds deployment/configuration artifacts (compose files, deployment script, and documentation) tailored for running this multi‑device build locally and on a VPS. Sequence diagram for Baileys multi_device client initializationsequenceDiagram
participant BaileysStartupService
participant ConfigService
participant BaileysSocketFactory
participant WhatsAppServer
BaileysStartupService->>BaileysStartupService: defineAuthState
BaileysStartupService->>BaileysStartupService: set phoneNumber if provided
BaileysStartupService->>BaileysStartupService: log Using Multi_Device native mode
BaileysStartupService->>BaileysSocketFactory: fetchLatestWaWebVersion
BaileysSocketFactory-->>BaileysStartupService: version
BaileysStartupService->>BaileysSocketFactory: makeWASocket(authState, socketConfig without browser)
BaileysSocketFactory-->>BaileysStartupService: WASocket (multi_device)
BaileysSocketFactory->>WhatsAppServer: open MD session as linked_device
WhatsAppServer-->>BaileysSocketFactory: connection established (no WebClient slot used)
rect rgb(230,230,230)
BaileysStartupService-x ConfigService: ConfigSessionPhone and browserOptions no longer used
end
Flow diagram for deploy_vps.sh multi_device deployment scriptflowchart TD
start([Start deploy_vps.sh]) --> check_file{docker_compose_prod_yaml exists?}
check_file -- No --> error_missing_file["Print error and exit"] --> end_node
check_file -- Yes --> backup_check{docker_compose_yaml exists?}
backup_check -- Yes --> backup_file["Backup docker_compose_yaml to timestamped file"] --> stop_containers
backup_check -- No --> stop_containers["Stop existing containers with docker compose down"]
stop_containers --> build_image["Build API image with Multi_Device fix (no cache)"]
build_image --> up_containers["Start containers with docker compose up -d"]
up_containers --> wait_api["Sleep 10 seconds for API to start"]
wait_api --> show_status["Show docker compose ps and last API logs"]
show_status --> end_node([Deploy finished])
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey - I've found 4 issues, and left some high level feedback:
- Consider moving the new deployment artifacts (
docker-compose.prod.yaml,docker-compose.local.yaml,deploy-vps.sh,DEPLOY-MULTIDEVICE-FIX.md) into anexamples/ordeploy/subdirectory or a separate ops repo so that environment-specific setup does not live at the project root and is clearly separated from application code. - Avoid committing real or example-specific credentials in the compose files (e.g.
POSTGRES_USER=caio,POSTGRES_PASSWORD=caio123, fixedAUTHENTICATION_API_KEY); instead, read these from an.envfile or document them as variables so they are not hard-coded in version control. - The new log message
Using Multi-Device native mode (no browser identification)is in English while some comments and other messages appear to be in Portuguese; it may be worth aligning the language with the existing logging/locale convention for consistency.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider moving the new deployment artifacts (`docker-compose.prod.yaml`, `docker-compose.local.yaml`, `deploy-vps.sh`, `DEPLOY-MULTIDEVICE-FIX.md`) into an `examples/` or `deploy/` subdirectory or a separate ops repo so that environment-specific setup does not live at the project root and is clearly separated from application code.
- Avoid committing real or example-specific credentials in the compose files (e.g. `POSTGRES_USER=caio`, `POSTGRES_PASSWORD=caio123`, fixed `AUTHENTICATION_API_KEY`); instead, read these from an `.env` file or document them as variables so they are not hard-coded in version control.
- The new log message `Using Multi-Device native mode (no browser identification)` is in English while some comments and other messages appear to be in Portuguese; it may be worth aligning the language with the existing logging/locale convention for consistency.
## Individual Comments
### Comment 1
<location> `src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts:558` </location>
<code_context>
+
+// Multi-Device mode: não definimos browser para evitar ser tratado como WebClient
+// Isso faz o Baileys usar o modo MD nativo, que não conflita com outras sessões
+this.logger.info('Using Multi-Device native mode (no browser identification)');
+
+// ... no socketConfig:
</code_context>
<issue_to_address>
**issue (bug_risk):** Avoid resetting `this.phoneNumber` to `undefined` when `number` is not provided.
With `if (number || this.phoneNumber)`, when `this.phoneNumber` is already set and `number` is omitted, the branch still runs and assigns `undefined` to `this.phoneNumber`, also logging `Phone number: undefined`. Consider only assigning when `number` is truthy, or split the logic so that you use `number` when provided and otherwise keep the existing `this.phoneNumber` unchanged.
</issue_to_address>
### Comment 2
<location> `deploy-vps.sh:35-44` </location>
<code_context>
+
+# Build da nova imagem
+echo -e "${YELLOW}🔨 Buildando imagem com Multi-Device fix...${NC}"
+docker compose -f docker-compose.prod.yaml build --no-cache api
+
+# Subir containers
+echo -e "${YELLOW}🚀 Iniciando containers...${NC}"
+docker compose -f docker-compose.prod.yaml up -d
+
+# Aguardar API iniciar
+echo -e "${YELLOW}⏳ Aguardando API iniciar...${NC}"
+sleep 10
+
+# Verificar status
+echo -e "${GREEN}✅ Deploy concluído!${NC}"
+echo ""
+echo "📊 Status dos containers:"
+docker compose -f docker-compose.prod.yaml ps
+
+echo ""
+echo "📋 Últimos logs da API:"
+docker compose -f docker-compose.prod.yaml logs api --tail 20
+
+echo ""
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Use a consistent `docker compose` vs `docker-compose` strategy throughout the script.
The `down` step already falls back to `docker-compose` if `docker compose` is unavailable, but `build`, `up`, `ps`, and `logs` use only `docker compose`. On hosts with only legacy `docker-compose` installed, the script will fail partway through. Consider detecting the available CLI once (e.g., a helper variable/function) and reusing it for all commands.
Suggested implementation:
```
# Detectar comando Docker Compose disponível (v2 `docker compose` ou v1 `docker-compose`)
if command -v docker &>/dev/null && docker compose version &>/dev/null; then
DOCKER_COMPOSE="docker compose"
elif command -v docker-compose &>/dev/null; then
DOCKER_COMPOSE="docker-compose"
else
echo -e "${RED:-}❌ Docker Compose não encontrado (nem v2 'docker compose' nem v1 'docker-compose').${NC:-}"
exit 1
fi
# Parar containers existentes (mantém volumes)
echo -e "${YELLOW}⏹️ Parando containers existentes...${NC}"
$DOCKER_COMPOSE -f docker-compose.prod.yaml down 2>/dev/null || true
# Build da nova imagem
echo -e "${YELLOW}🔨 Buildando imagem com Multi-Device fix...${NC}"
$DOCKER_COMPOSE -f docker-compose.prod.yaml build --no-cache api
# Subir containers
echo -e "${YELLOW}🚀 Iniciando containers...${NC}"
$DOCKER_COMPOSE -f docker-compose.prod.yaml up -d
```
```
echo ""
echo "📊 Status dos containers:"
$DOCKER_COMPOSE -f docker-compose.prod.yaml ps
echo ""
echo "📋 Últimos logs da API:"
$DOCKER_COMPOSE -f docker-compose.prod.yaml logs api --tail 20
```
If there are other `docker compose` or `docker-compose` usages earlier or later in `deploy-vps.sh` (outside the snippet shown), they should also be updated to use `$DOCKER_COMPOSE` to keep the behavior consistent across the entire script.
</issue_to_address>
### Comment 3
<location> `docker-compose.prod.yaml:49` </location>
<code_context>
+ - POSTGRES_USER=caio
+ - POSTGRES_PASSWORD=caio123
+ - POSTGRES_DB=evolution
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ volumes:
+ - evolution-clean_postgres_data:/var/lib/postgresql/data
</code_context>
<issue_to_address>
**🚨 issue (security):** Using `POSTGRES_HOST_AUTH_METHOD=trust` with an exposed Postgres port is risky for a VPS deployment.
With `trust` auth enabled, any matching client can connect without a password, which combined with exposing port 5432 is a serious security risk in a VPS. Prefer using the configured `POSTGRES_USER`/`POSTGRES_PASSWORD`, avoid exposing Postgres directly (or tightly restrict it via firewall), and remove `POSTGRES_HOST_AUTH_METHOD=trust` unless you have a very tightly controlled, documented use case.
</issue_to_address>
### Comment 4
<location> `docker-compose.prod.yaml:45-49` </location>
<code_context>
+ restart: always
+ ports:
+ - 5432:5432
+ environment:
+ - POSTGRES_USER=caio
+ - POSTGRES_PASSWORD=caio123
+ - POSTGRES_DB=evolution
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ volumes:
+ - evolution-clean_postgres_data:/var/lib/postgresql/data
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Evitar credenciais em claro e `POSTGRES_HOST_AUTH_METHOD=trust` em exemplo de configuração de produção.
Como o arquivo se chama `docker-compose.prod.yaml`, é provável que seja usado como referência de produção. Sugiro trocar `POSTGRES_USER=caio` / `POSTGRES_PASSWORD=caio123` por placeholders (por ex.: `POSTGRES_USER=<usuario>` e `POSTGRES_PASSWORD=<senha_segura>`) e remover `POSTGRES_HOST_AUTH_METHOD=trust` ou marcar explicitamente que é apenas para ambiente de desenvolvimento/teste, para evitar que essa configuração insegura seja copiada para produção.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
|
||
| // Multi-Device mode: não definimos browser para evitar ser tratado como WebClient | ||
| // Isso faz o Baileys usar o modo MD nativo, que não conflita com outras sessões | ||
| this.logger.info('Using Multi-Device native mode (no browser identification)'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Avoid resetting this.phoneNumber to undefined when number is not provided.
With if (number || this.phoneNumber), when this.phoneNumber is already set and number is omitted, the branch still runs and assigns undefined to this.phoneNumber, also logging Phone number: undefined. Consider only assigning when number is truthy, or split the logic so that you use number when provided and otherwise keep the existing this.phoneNumber unchanged.
| - POSTGRES_USER=caio | ||
| - POSTGRES_PASSWORD=caio123 | ||
| - POSTGRES_DB=evolution | ||
| - POSTGRES_HOST_AUTH_METHOD=trust |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚨 issue (security): Using POSTGRES_HOST_AUTH_METHOD=trust with an exposed Postgres port is risky for a VPS deployment.
With trust auth enabled, any matching client can connect without a password, which combined with exposing port 5432 is a serious security risk in a VPS. Prefer using the configured POSTGRES_USER/POSTGRES_PASSWORD, avoid exposing Postgres directly (or tightly restrict it via firewall), and remove POSTGRES_HOST_AUTH_METHOD=trust unless you have a very tightly controlled, documented use case.
🚀 Evolution API - Multi-Device Fix
📋 Resumo da Alteração
Problema: A Evolution API estava caindo/desconectando quando o WhatsApp Android estava ativo, porque se identificava como "WebClient" (WhatsApp Web), ocupando o slot de sessão web.
Solução: Remover a identificação de browser para usar o modo Multi-Device nativo do Baileys 7.x, que não conflita com outras sessões.
🔧 Alteração no Código
Arquivo:
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.tsANTES (WebClient - CAI):
DEPOIS (Multi-Device nativo - NÃO CAI):
Imports removidos:
ConfigSessionPhonedo@config/env.configWABrowserDescriptiondobaileysreleasedoos📦 Repositório Fork
URL: https://github.com/joinads/evolution-api
Commit:
5dbf3e93- "fix: usar Multi-Device nativo para evitar desconexões"🐳 Deploy na VPS com Docker Compose
Pré-requisitos
Volumes Utilizados (externos)
📝 Comandos de Deploy
1. Clone o repositório
2. Copie o .env existente
3. Crie o docker-compose.prod.yaml
4. Pare a Evolution antiga (se estiver rodando)
5. Build da nova imagem
6. Suba os containers
7. Verifique os logs
🔄 Comandos Úteis
Ver status dos containers
Reiniciar a API
Ver logs em tempo real
Parar todos os containers
Rebuild após alterações no código
🔍 Verificar se o Fix está Funcionando
Nos logs da API, você deve ver:
NÃO deve mais aparecer:
Instâncias existentes: Continuam funcionando normalmente. As credenciais salvas não dependem do parâmetro
browser.Novas conexões: Usarão o modo Multi-Device nativo automaticamente.
Se uma sessão expirar: Ao reconectar via QR Code, já usará o novo modo.
Volumes externos: O docker-compose usa
external: truepara apontar para os volumes existentes, preservando todos os dados.📊 Comparação: Antes vs Depois
['Evolution API', 'Chrome', OS]🆘 Rollback (Voltar para versão oficial)
Se precisar voltar para a versão oficial:
🔗 Links
Summary by Sourcery
Enable WhatsApp multi-device native mode in the Baileys integration and add deployment tooling and docs for running the customized Evolution API setup.
New Features:
Bug Fixes:
Enhancements:
Documentation: