|
|
@@ -0,0 +1,261 @@
|
|
|
+# Teste de conexão da conta WhatsApp via Unipile
|
|
|
+
|
|
|
+Este documento descreve o passo a passo para testar a conexão de uma conta WhatsApp com o backend usando o fluxo Hosted Auth do Unipile.
|
|
|
+
|
|
|
+## Objetivo
|
|
|
+
|
|
|
+Validar que o backend consegue:
|
|
|
+
|
|
|
+- gerar o link de conexão da conta WhatsApp
|
|
|
+- receber o callback do Unipile
|
|
|
+- criar ou atualizar a integração na tabela `integration`
|
|
|
+- listar a conta conectada pela API
|
|
|
+
|
|
|
+## Fluxo resumido
|
|
|
+
|
|
|
+O fluxo implementado no código é este:
|
|
|
+
|
|
|
+1. o usuário autenticado chama `POST /v1/integrations/unipile/whatsapp/hosted-link`
|
|
|
+2. o backend gera uma URL de conexão no Unipile
|
|
|
+3. o usuário abre a URL e conecta a conta WhatsApp
|
|
|
+4. o Unipile chama `POST /v1/webhooks/unipile/hosted-auth`
|
|
|
+5. o backend grava ou atualiza a integração em `integration`
|
|
|
+6. a conta pode ser conferida em `GET /v1/integrations/unipile/whatsapp/accounts`
|
|
|
+
|
|
|
+## Pré-requisitos
|
|
|
+
|
|
|
+Antes de testar, confirme estes pontos.
|
|
|
+
|
|
|
+### 1. Variáveis de ambiente
|
|
|
+
|
|
|
+No arquivo `.env`, deixe configurado pelo menos:
|
|
|
+
|
|
|
+```env
|
|
|
+UNIPILE_DSN=https://SEU-DOMINIO-UNIPILE
|
|
|
+UNIPILE_API_KEY=SUA_API_KEY
|
|
|
+UNIPILE_NOTIFY_SECRET=UM_SECRET_FORTE
|
|
|
+JWT_SECRET=SEU_JWT_SECRET
|
|
|
+APP_PUBLIC_URL=https://SUA-URL-PUBLICA-DO-BACKEND
|
|
|
+```
|
|
|
+
|
|
|
+Opcionalmente, você também pode configurar:
|
|
|
+
|
|
|
+```env
|
|
|
+UNIPILE_SUCCESS_REDIRECT_URL=https://SUA-URL-PUBLICA-DO-BACKEND/v1/integrations/unipile/whatsapp/success
|
|
|
+UNIPILE_FAILURE_REDIRECT_URL=https://SUA-URL-PUBLICA-DO-BACKEND/v1/integrations/unipile/whatsapp/failure
|
|
|
+```
|
|
|
+
|
|
|
+### 2. URL pública HTTPS
|
|
|
+
|
|
|
+O callback do Unipile precisa alcançar o backend em uma URL pública.
|
|
|
+
|
|
|
+Sem isso, o Unipile não conseguirá chamar:
|
|
|
+
|
|
|
+```text
|
|
|
+POST /v1/webhooks/unipile/hosted-auth
|
|
|
+```
|
|
|
+
|
|
|
+Se estiver rodando localmente, use um túnel HTTPS, por exemplo:
|
|
|
+
|
|
|
+- `ngrok`
|
|
|
+- `cloudflared tunnel`
|
|
|
+
|
|
|
+### 3. Backend rodando
|
|
|
+
|
|
|
+Garanta que a API PHP esteja no ar e acessível na URL pública configurada em `APP_PUBLIC_URL`.
|
|
|
+
|
|
|
+### 4. Usuário autenticado
|
|
|
+
|
|
|
+A rota que gera o link Hosted Auth exige JWT.
|
|
|
+
|
|
|
+### 5. Operador vinculado ao usuário
|
|
|
+
|
|
|
+O backend tenta resolver o operador pelo e-mail do usuário autenticado.
|
|
|
+
|
|
|
+Idealmente, deve existir um registro em `operator` com:
|
|
|
+
|
|
|
+- mesmo `company_id` do usuário
|
|
|
+- `operator_email` igual ao `user_email`
|
|
|
+
|
|
|
+## Passo 1: fazer login e obter o JWT
|
|
|
+
|
|
|
+Faça login normalmente para obter o token.
|
|
|
+
|
|
|
+Exemplo:
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -X POST "http://localhost:8080/v1/login" \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{
|
|
|
+ "email": "admin@mixtech.com",
|
|
|
+ "password": "admin123"
|
|
|
+ }'
|
|
|
+```
|
|
|
+
|
|
|
+Copie o token retornado e use-o nos próximos requests.
|
|
|
+
|
|
|
+## Passo 2: gerar o link de conexão do WhatsApp
|
|
|
+
|
|
|
+Faça a chamada abaixo com o JWT:
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -X POST "http://localhost:8080/v1/integrations/unipile/whatsapp/hosted-link" \
|
|
|
+ -H "Authorization: Bearer SEU_JWT" \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{"type":"create"}'
|
|
|
+```
|
|
|
+
|
|
|
+### Resposta esperada
|
|
|
+
|
|
|
+O backend deve responder com uma URL:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "status": "ok",
|
|
|
+ "code": "S_OK",
|
|
|
+ "message": "Request ok.",
|
|
|
+ "data": {
|
|
|
+ "url": "https://..."
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### Se falhar neste passo
|
|
|
+
|
|
|
+Verifique:
|
|
|
+
|
|
|
+- `UNIPILE_DSN`
|
|
|
+- `UNIPILE_API_KEY`
|
|
|
+- `UNIPILE_NOTIFY_SECRET`
|
|
|
+- JWT válido
|
|
|
+- backend rodando
|
|
|
+
|
|
|
+Erros comuns:
|
|
|
+
|
|
|
+- `Unipile is not configured`
|
|
|
+- `UNIPILE_NOTIFY_SECRET is not configured`
|
|
|
+- `Unauthorized`
|
|
|
+- `Failed to create hosted auth link`
|
|
|
+
|
|
|
+## Passo 3: abrir a URL retornada
|
|
|
+
|
|
|
+Abra no navegador a URL recebida em `data.url`.
|
|
|
+
|
|
|
+Complete o fluxo de conexão da conta WhatsApp dentro da página hospedada do Unipile.
|
|
|
+
|
|
|
+## Passo 4: confirmar que o callback chegou
|
|
|
+
|
|
|
+Ao concluir a conexão, o Unipile deve chamar o backend em:
|
|
|
+
|
|
|
+```text
|
|
|
+POST /v1/webhooks/unipile/hosted-auth
|
|
|
+```
|
|
|
+
|
|
|
+Esse callback é o que cria ou atualiza a integração da conta conectada.
|
|
|
+
|
|
|
+### O callback depende de
|
|
|
+
|
|
|
+- `APP_PUBLIC_URL` correta
|
|
|
+- `UNIPILE_NOTIFY_SECRET` correta
|
|
|
+- `JWT_SECRET` consistente
|
|
|
+- backend acessível publicamente
|
|
|
+
|
|
|
+## Passo 5: listar as contas conectadas
|
|
|
+
|
|
|
+Depois de concluir o fluxo, consulte as integrações cadastradas:
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -H "Authorization: Bearer SEU_JWT" \
|
|
|
+ "http://localhost:8080/v1/integrations/unipile/whatsapp/accounts"
|
|
|
+```
|
|
|
+
|
|
|
+### Resultado esperado
|
|
|
+
|
|
|
+A resposta deve conter um item em `items` com campos como:
|
|
|
+
|
|
|
+- `provider`
|
|
|
+- `accountId`
|
|
|
+- `accountName`
|
|
|
+- `status`
|
|
|
+- `isConnected`
|
|
|
+
|
|
|
+## Passo 6: validar no banco de dados
|
|
|
+
|
|
|
+Se quiser confirmar direto no PostgreSQL, rode:
|
|
|
+
|
|
|
+```sql
|
|
|
+SELECT
|
|
|
+ integration_id,
|
|
|
+ company_id,
|
|
|
+ user_id,
|
|
|
+ operator_id,
|
|
|
+ integration_provider,
|
|
|
+ integration_account_id,
|
|
|
+ integration_account_name,
|
|
|
+ integration_status,
|
|
|
+ integration_is_connected,
|
|
|
+ integration_last_sync_at
|
|
|
+FROM integration
|
|
|
+WHERE integration_provider = 'whatsapp'
|
|
|
+ AND integration_deleted_at = 'infinity'
|
|
|
+ORDER BY integration_id DESC;
|
|
|
+```
|
|
|
+
|
|
|
+## Checklist de sucesso
|
|
|
+
|
|
|
+Considere o teste bem-sucedido quando:
|
|
|
+
|
|
|
+- a rota `hosted-link` retornar uma URL
|
|
|
+- o fluxo do Unipile abrir normalmente no navegador
|
|
|
+- o callback do Unipile chegar ao backend
|
|
|
+- surgir ou atualizar um registro em `integration`
|
|
|
+- `GET /v1/integrations/unipile/whatsapp/accounts` listar a conta
|
|
|
+
|
|
|
+## Problemas mais comuns
|
|
|
+
|
|
|
+### 1. O link é gerado, mas a integração não aparece
|
|
|
+
|
|
|
+Causa provável:
|
|
|
+
|
|
|
+- o callback `hosted-auth` não conseguiu alcançar o backend
|
|
|
+- `APP_PUBLIC_URL` inválida
|
|
|
+- backend não público
|
|
|
+- `UNIPILE_NOTIFY_SECRET` incorreta
|
|
|
+
|
|
|
+### 2. Erro `Invalid callback identity`
|
|
|
+
|
|
|
+Causa provável:
|
|
|
+
|
|
|
+- `JWT_SECRET` usada para assinar e validar o campo `name` não está consistente
|
|
|
+
|
|
|
+### 3. Erro `Unauthorized` no callback
|
|
|
+
|
|
|
+Causa provável:
|
|
|
+
|
|
|
+- `UNIPILE_NOTIFY_SECRET` não bate com a usada no `notify_url`
|
|
|
+
|
|
|
+### 4. Integração criada com associação ruim de operador
|
|
|
+
|
|
|
+Causa provável:
|
|
|
+
|
|
|
+- o usuário autenticado não possui correspondência em `operator.operator_email`
|
|
|
+
|
|
|
+## Teste de reconexão
|
|
|
+
|
|
|
+Se já existir uma integração e você quiser testar reconexão, use:
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -X POST "http://localhost:8080/v1/integrations/unipile/whatsapp/hosted-link" \
|
|
|
+ -H "Authorization: Bearer SEU_JWT" \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{"type":"reconnect","integration_id":1}'
|
|
|
+```
|
|
|
+
|
|
|
+## Observação final
|
|
|
+
|
|
|
+Este documento cobre apenas o teste de conexão da conta WhatsApp.
|
|
|
+
|
|
|
+Depois que a conta estiver conectada, o próximo teste natural é validar o recebimento de mensagens em:
|
|
|
+
|
|
|
+- `POST /v1/webhooks/unipile`
|
|
|
+- tabelas `webhook_event`, `client`, `conversation` e `message`
|