Pular para conteúdo

API: Conversations

Visão Geral

Gerenciamento de conversas entre contatos WhatsApp e a plataforma. Suporta modo IA (automático) e modo Manual (operador humano).

Autorização e Rate Limiting

O grupo de endpoints de conversas requer autenticação e usa a política de rate limiting Realtime: 120 requisições por 60 segundos por usuário.

O endpoint de envio de mensagens (POST /api/conversations/{id}/messages) usa uma política separada SendMessage: 30 requisições por 60 segundos por usuário.

Endpoint Política Limite Janela
Todos (exceto SendMessage) Realtime 120 req 60s
POST /conversations/{id}/messages SendMessage 30 req 60s

Endpoints

GET /api/instances/{instanceId}/conversations

Lista conversas de uma instância.

Query Parameters: - status (opcional): Active, Resolved - page (opcional): Página (default: 1) - pageSize (opcional): Itens por página (default: 20)

Response (200 OK):

{
  "items": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "contactPhone": "+5511999998888",
      "contactName": "João Silva",
      "contactProfilePictureUrl": "https://cdn.exemplo.com/profile.jpg",
      "status": "Active",
      "mode": "AI",
      "startedAt": "2024-01-20T10:00:00Z",
      "lastMessageAt": "2024-01-20T10:30:00Z",
      "lastMessage": "Qual o horário de funcionamento?",
      "unreadCount": 2
    }
  ],
  "totalCount": 50,
  "page": 1,
  "pageSize": 20
}


GET /api/conversations/{id}

Retorna detalhes de uma conversa.

Response (200 OK):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "instanceId": "660e8400-e29b-41d4-a716-446655440001",
  "instanceName": "Suporte Principal",
  "agentId": "770e8400-e29b-41d4-a716-446655440002",
  "agentName": "Suporte TI",
  "contactPhone": "+5511999998888",
  "contactName": "João Silva",
  "contactProfilePictureUrl": "https://cdn.exemplo.com/profile.jpg",
  "status": "Active",
  "mode": "AI",
  "modeChangedAt": null,
  "startedAt": "2024-01-20T10:00:00Z",
  "lastMessageAt": "2024-01-20T10:30:00Z",
  "resolvedAt": null,
  "summary": null,
  "totalInputTokens": 1500,
  "totalOutputTokens": 800
}


GET /api/conversations/{id}/messages

Lista mensagens de uma conversa com paginação.

Query Parameters: - before (opcional): Cursor para paginação (ID da mensagem) - limit (opcional): Quantidade (default: 50)

Response (200 OK):

{
  "items": [
    {
      "id": "880e8400-e29b-41d4-a716-446655440000",
      "role": "User",
      "type": "Text",
      "content": "Qual o horário de funcionamento?",
      "mediaUrl": null,
      "mediaMimeType": null,
      "mediaFileName": null,
      "status": "Read",
      "createdAt": "2024-01-20T10:30:00Z",
      "inputTokens": null,
      "outputTokens": null,
      "reactions": [
        {
          "emoji": "👍",
          "senderPhone": "+5511999998888",
          "fromMe": false
        }
      ],
      "systemEventType": null,
      "actorName": null
    },
    {
      "id": "990e8400-e29b-41d4-a716-446655440001",
      "role": "Assistant",
      "type": "Text",
      "content": "Nosso horário é das 8h às 18h.",
      "mediaUrl": null,
      "mediaMimeType": null,
      "mediaFileName": null,
      "status": "Delivered",
      "createdAt": "2024-01-20T10:30:05Z",
      "inputTokens": 50,
      "outputTokens": 20,
      "reactions": [],
      "systemEventType": null,
      "actorName": null
    },
    {
      "id": "aa0e8400-e29b-41d4-a716-446655440002",
      "role": "System",
      "type": "Text",
      "content": "Conversa transferida para atendimento humano.",
      "mediaUrl": null,
      "mediaMimeType": null,
      "mediaFileName": null,
      "status": "Read",
      "createdAt": "2024-01-20T10:30:06Z",
      "inputTokens": null,
      "outputTokens": null,
      "reactions": null,
      "systemEventType": "EscalatedByAi",
      "actorName": "Suporte TI"
    }
  ],
  "hasMore": true,
  "oldestMessageId": "770e8400-e29b-41d4-a716-446655440000"
}


POST /api/conversations/start

Inicia uma nova conversa a partir do portal.

Request:

{
  "instanceId": "660e8400-e29b-41d4-a716-446655440001",
  "contactPhone": "+5511999998888",
  "message": "Olá, como posso ajudar?"
}

Response (201 Created):

{
  "conversationId": "550e8400-e29b-41d4-a716-446655440000",
  "messageId": "880e8400-e29b-41d4-a716-446655440000"
}


POST /api/conversations/{id}/messages

Envia uma mensagem na conversa.

Rate Limiting: SendMessage (30 req/60s)

Request:

{
  "content": "Segue o documento solicitado.",
  "attachments": [
    {
      "fileName": "manual.pdf",
      "mimeType": "application/pdf",
      "base64": "JVBERi0xLjQK..."
    }
  ],
  "isVoiceMessage": false
}

Response (200 OK):

{
  "messageId": "880e8400-e29b-41d4-a716-446655440000",
  "whatsappMessageId": "wamid.xxx",
  "status": "Sent"
}


POST /api/conversations/{id}/transfer

Transfere o modo da conversa (AI ↔ Manual).

Request:

{
  "targetMode": "AI",
  "triggerImmediateResponse": true
}

Campo Tipo Obrigatório Descrição
targetMode string Sim "AI" ou "Manual"
triggerImmediateResponse bool Não (default: false) Quando true e targetMode = "AI", agenda resposta imediata da IA via pipeline DeferredAiResponse (sem aguardar nova mensagem do contato)

Validação: Ao transferir para modo IA, o sistema verifica se o agente está ativo e se o tenant possui créditos de IA disponíveis. Caso o agente esteja desativado ou não haja créditos, retorna erro 409.

Response (200 OK):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "mode": "AI",
  "modeChangedAt": "2024-01-20T11:00:00Z"
}


POST /api/conversations/{id}/resolve

Resolve uma conversa.

Request:

{
  "summary": "Cliente tinha dúvida sobre horário. Esclarecido."
}

Response (200 OK):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "Resolved",
  "resolvedAt": "2024-01-20T11:30:00Z"
}


PUT /api/conversations/{id}/read

Marca a conversa como lida pelo operador.

Response: 204 No Content


POST /api/conversations/{conversationId}/messages/{messageId}/react

Adiciona ou remove uma reação a uma mensagem.

Request:

{
  "emoji": "👍"
}

Response (200 OK):

{
  "messageId": "880e8400-e29b-41d4-a716-446655440000",
  "emoji": "👍",
  "added": true
}


Tipos de Mensagem

Type Descrição
Text Mensagem de texto
Image Imagem (jpg, png, gif, webp)
Audio Áudio/Voice message
Video Vídeo
Document Documento (pdf, doc, etc)
Sticker Sticker do WhatsApp

Status de Mensagem

Status Descrição
Pending Aguardando envio
Sent Enviada (✓)
Delivered Entregue (✓✓)
Read Lida (✓✓ azul)
Failed Falhou

Modos de Conversa

Mode Descrição
AI IA processa as mensagens automaticamente
Manual Operador humano responde via portal

SignalR - Eventos Real-time

O hub ConversationHub emite eventos para atualizações em tempo real:

Evento Descrição
NewMessage Nova mensagem na conversa (inclui mensagens de sistema com SystemEventType e ActorName)
MessageStatusUpdated Status de entrega atualizado
ConversationUpdated Conversa atualizada (status, modo)
ConversationEscalated Conversa escalada para modo manual
NewConversation Nova conversa iniciada
CreditBalanceUpdated Saldo de créditos atualizado

Mensagens de Sistema

Mensagens com role: "System" representam eventos internos do sistema. Nunca são enviadas ao WhatsApp e nunca incluídas no histórico da IA. Campos adicionais:

Campo Tipo Descrição
systemEventType string? Tipo do evento (AiCapReached, AiFailure, CreditsExhausted, EscalatedByAi, ResolvedByAi, ResolvedByOperator, ModeChangedToManual, ModeChangedToAi)
actorName string? Quem causou o evento (nome do operador/agente IA, null para automático)

Exemplo de Uso (Blazor)

_hubConnection.On<MessageNotification>("NewMessage", message =>
{
    // Mensagens de sistema têm role = "System" e systemEventType preenchido
    _messages.Add(MapToMessageItemResponse(message));
    StateHasChanged();
});

Erros Comuns

Status Código Descrição
404 CONVERSATION_NOT_FOUND Conversa não encontrada
400 INSTANCE_DISCONNECTED Instância WhatsApp desconectada
400 CONVERSATION_RESOLVED Conversa já resolvida