{
  "openapi": "3.0.0",
  "info": {
    "title": "wChat External Integration API",
    "description": "API para integração de sistemas externos (CRM, IA, ERP) com o WhatsApp via wChat.\n\n## Autenticação\n\nTodas as requisições devem incluir o header `X-API-Key` com uma chave válida.\n\n```\nX-API-Key: sk_live_abc123...\n```\n\nAs chaves são geradas pelo administrador no painel de configurações do wChat.\n\n## Tipos de mensagem\n\n| Tipo | Descrição | Campos obrigatórios |\n|------|-----------|---------------------|\n| `text` | Mensagem de texto | `body` |\n| `image` | Imagem (JPEG, PNG, WebP) | `mediaUrl` ou `mediaBase64`, `mimeType` |\n| `document` | Documento (PDF, etc) | `mediaUrl` ou `mediaBase64`, `mimeType`, `filename` |\n| `audio` | Áudio | `mediaUrl` ou `mediaBase64`, `mimeType` |\n| `video` | Vídeo | `mediaUrl` ou `mediaBase64`, `mimeType` |\n| `ptt` | Áudio gravado (push-to-talk) | `mediaUrl` ou `mediaBase64`, `mimeType` |\n| `location` | Localização | `lat`, `lng` |\n| `vcard` | Cartão de contato | `vcard` |\n\n## Webhooks\n\nO wChat pode enviar eventos em tempo real para a URL configurada pelo administrador no painel.\n\nCada entrega inclui o header `X-WChat-Signature` com assinatura HMAC-SHA256 do payload usando o `secret` configurado.\n\n### Eventos disponíveis\n- `message.received` — Nova mensagem recebida do cliente\n- `message.sent` — Mensagem enviada (confirmação)\n- `message.status_changed` — Status da mensagem alterado (entregue, lido, etc)\n\n### Payload do webhook\n```json\n{\n  \"event\": \"message.received\",\n  \"timestamp\": \"2026-03-06T12:00:00.000Z\",\n  \"data\": {\n    \"messageId\": \"abc123\",\n    \"chatId\": \"xyz789\",\n    \"from\": { \"phone\": \"5567985382270\", \"name\": \"João\" },\n    \"type\": \"text\",\n    \"body\": \"Preciso do boleto\",\n    \"isFromMe\": false,\n    \"session\": { \"queueId\": \"...\", \"queueName\": \"Vendas\" }\n  }\n}\n```\n\n### Verificação HMAC\n```python\nimport hmac, hashlib\nsignature = hmac.new(secret.encode(), payload_bytes, hashlib.sha256).hexdigest()\nassert signature == request.headers['X-WChat-Signature']\n```",
    "version": "1.0.0",
    "contact": {
      "name": "wChat Suporte",
      "url": "https://wchat.com.br"
    }
  },
  "servers": [
    {
      "url": "https://{host}",
      "description": "Servidor da instância wChat",
      "variables": {
        "host": {
          "default": "sua-instancia.wchat.com.br",
          "description": "Host da sua instância wChat"
        }
      }
    }
  ],
  "security": [
    { "ApiKeyAuth": [] }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Chave de API gerada pelo administrador no painel wChat. Formato: `sk_live_...`"
      }
    },
    "schemas": {
      "SendMessageDto": {
        "type": "object",
        "required": ["to", "type"],
        "properties": {
          "to": {
            "type": "string",
            "description": "Número de telefone (apenas dígitos, com código do país)",
            "example": "5567985382270"
          },
          "type": {
            "type": "string",
            "enum": ["text", "image", "document", "audio", "video", "ptt", "location", "vcard"],
            "description": "Tipo da mensagem",
            "example": "text"
          },
          "body": {
            "type": "string",
            "description": "Corpo da mensagem (obrigatório para tipo `text`)",
            "example": "Olá! Segue seu boleto."
          },
          "mediaUrl": {
            "type": "string",
            "format": "uri",
            "description": "URL pública da mídia (para tipos de mídia)",
            "example": "https://exemplo.com/boleto.pdf"
          },
          "mediaBase64": {
            "type": "string",
            "description": "Mídia codificada em Base64 (alternativa ao `mediaUrl`)"
          },
          "mimeType": {
            "type": "string",
            "description": "MIME type do arquivo (obrigatório para mídia)",
            "example": "application/pdf"
          },
          "filename": {
            "type": "string",
            "description": "Nome do arquivo (recomendado para documentos)",
            "example": "boleto.pdf"
          },
          "caption": {
            "type": "string",
            "description": "Legenda (para imagem, vídeo ou documento)",
            "example": "Boleto de Janeiro"
          },
          "lat": {
            "type": "number",
            "description": "Latitude (obrigatório para tipo `location`)",
            "example": -23.55
          },
          "lng": {
            "type": "number",
            "description": "Longitude (obrigatório para tipo `location`)",
            "example": -46.63
          },
          "vcard": {
            "type": "string",
            "description": "Dados do VCard (obrigatório para tipo `vcard`)"
          }
        }
      },
      "SendTemplateDto": {
        "type": "object",
        "required": ["to", "templateId"],
        "properties": {
          "to": {
            "type": "string",
            "description": "Número de telefone (apenas dígitos, com código do país)",
            "example": "5567985382270"
          },
          "templateId": {
            "type": "string",
            "description": "ID do template no MongoDB",
            "example": "65a1b2c3d4e5f6g7h8i9j0k1"
          },
          "headerVariable": {
            "type": "string",
            "description": "Variável do cabeçalho (substitui {{1}} no header)"
          },
          "bodyVariables": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Variáveis do corpo (substituem {{1}}, {{2}}, etc)",
            "example": ["João", "Pedido #123"]
          },
          "headerMediaId": {
            "type": "string",
            "description": "ID da mídia do cabeçalho (para templates com imagem/vídeo/documento)"
          },
          "lat": {
            "type": "number",
            "description": "Latitude (para templates de localização)",
            "example": -23.55
          },
          "lng": {
            "type": "number",
            "description": "Longitude (para templates de localização)",
            "example": -46.63
          },
          "addressName": {
            "type": "string",
            "description": "Nome do local"
          },
          "address": {
            "type": "string",
            "description": "Endereço completo"
          }
        }
      },
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "messageId": { "type": "string" },
          "chatId": { "type": "string" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "statusCode": { "type": "integer", "example": 400 },
          "message": { "type": "string", "example": "Field \"to\" is required" },
          "error": { "type": "string", "example": "Bad Request" }
        }
      }
    }
  },
  "paths": {
    "/integration/send-message": {
      "post": {
        "tags": ["Mensagens"],
        "summary": "Enviar mensagem",
        "description": "Envia texto, imagem, documento, áudio, vídeo, localização ou vCard para um número WhatsApp.",
        "operationId": "sendMessage",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SendMessageDto" },
              "examples": {
                "texto": {
                  "summary": "Mensagem de texto",
                  "value": {
                    "to": "5567985382270",
                    "type": "text",
                    "body": "Olá! Segue as informações do seu boleto."
                  }
                },
                "documento": {
                  "summary": "Envio de PDF",
                  "value": {
                    "to": "5567985382270",
                    "type": "document",
                    "mediaUrl": "https://exemplo.com/boleto.pdf",
                    "mimeType": "application/pdf",
                    "filename": "boleto-janeiro-2026.pdf",
                    "caption": "Boleto de Janeiro"
                  }
                },
                "imagem": {
                  "summary": "Envio de imagem",
                  "value": {
                    "to": "5567985382270",
                    "type": "image",
                    "mediaUrl": "https://exemplo.com/comprovante.jpg",
                    "mimeType": "image/jpeg",
                    "caption": "Comprovante de pagamento"
                  }
                },
                "localizacao": {
                  "summary": "Envio de localização",
                  "value": {
                    "to": "5567985382270",
                    "type": "location",
                    "lat": -23.5505,
                    "lng": -46.6333
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mensagem enviada com sucesso",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SuccessResponse" }
              }
            }
          },
          "400": {
            "description": "Parâmetros inválidos",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "401": { "description": "API key inválida ou sem permissão" }
        }
      }
    },
    "/integration/send-template": {
      "post": {
        "tags": ["Mensagens"],
        "summary": "Enviar template",
        "description": "Envia um template aprovado do WhatsApp Business via CloudAPI oficial. Os templates devem ser previamente aprovados pela Meta.",
        "operationId": "sendTemplate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SendTemplateDto" },
              "examples": {
                "simples": {
                  "summary": "Template com variáveis no corpo",
                  "value": {
                    "to": "5567985382270",
                    "templateId": "65a1b2c3d4e5f6g7h8i9j0k1",
                    "bodyVariables": ["João", "Pedido #123", "R$ 150,00"]
                  }
                },
                "com_midia": {
                  "summary": "Template com mídia no header",
                  "value": {
                    "to": "5567985382270",
                    "templateId": "65a1b2c3d4e5f6g7h8i9j0k1",
                    "headerMediaId": "1234567890",
                    "bodyVariables": ["Maria", "Fatura #456"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Template enviado com sucesso" },
          "400": { "description": "Template não encontrado ou parâmetros inválidos" },
          "401": { "description": "API key inválida ou sem permissão" }
        }
      }
    },
    "/integration/templates": {
      "get": {
        "tags": ["Mensagens"],
        "summary": "Listar templates disponíveis",
        "description": "Retorna todos os templates aprovados disponíveis na conta CloudAPI.",
        "operationId": "listTemplates",
        "responses": {
          "200": { "description": "Lista de templates" }
        }
      }
    },
    "/integration/chats": {
      "get": {
        "tags": ["Chats e Mensagens"],
        "summary": "Listar chats",
        "description": "Retorna chats das filas configuradas na integração, com paginação.",
        "operationId": "getChats",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Página (começa em 0)",
            "schema": { "type": "integer", "default": 0 },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Itens por página",
            "schema": { "type": "integer", "default": 20 },
            "example": 20
          }
        ],
        "responses": {
          "200": { "description": "Lista de chats paginada" }
        }
      }
    },
    "/integration/messages/{chatId}": {
      "get": {
        "tags": ["Chats e Mensagens"],
        "summary": "Ler mensagens de um chat",
        "description": "Retorna as últimas mensagens de um chat específico.",
        "operationId": "getMessages",
        "parameters": [
          {
            "name": "chatId",
            "in": "path",
            "required": true,
            "description": "ID do chat",
            "schema": { "type": "string" }
          },
          {
            "name": "count",
            "in": "query",
            "description": "Quantidade de mensagens a retornar",
            "schema": { "type": "integer", "default": 50 },
            "example": 50
          }
        ],
        "responses": {
          "200": { "description": "Lista de mensagens" }
        }
      }
    }
  },
  "tags": [
    { "name": "Mensagens", "description": "Envio de mensagens e templates via WhatsApp" },
    { "name": "Chats e Mensagens", "description": "Leitura de chats e histórico de mensagens" }
  ]
}