📑 Índice


🎯 Visão Geral

Endpoint

POST /api/externalAPIs/public/investigateMessage

Funcionalidades Principais


🔑 Autenticação

A rota utiliza autenticação via Bearer Token através do middleware tolkyAuthMiddleware. O token deve ser enviado no cabeçalho Authorization.

Cabeçalhos Obrigatórios

Authorization: Bearer <seu_token_aqui>
Content-Type: application/json

⚙️ Parâmetros da Requisição

Body (JSON)

CampoTipoObrigatórioDescrição
messageIdstring (UUID)SimID único da mensagem a ser investigada
useAIbooleanNãoSe true, executa análise IA legada e adiciona aiAnalysis ao resultado (padrão: false)
useAIV2booleanNãoSe true, executa análise investigateV2 e adiciona aiAnalysis ao resultado (padrão: false)
generalInstructionsstringNãoInstruções customizadas para a análise IA (usado quando useAIV2 é true)
replaceDomainNamestringNãoSubstitui “tolky” por este valor na resposta (ex.: white-label)

Variações do formato de resposta (sempre 200):

  1. Apenas base (useAI=false, useAIV2=false): objeto com host_slug, time_ranking, tolky_recap, message, iaRequests, externalApiRequests, control. O campo aiAnalysis não vem na resposta.
  2. Base + aiAnalysis (useAI=true) — análise legada: mesmo objeto base + aiAnalysis com analysis.json.analyzed_parts, error, tokens_used (objeto com prompt_tokens, completion_tokens, total_tokens).
  3. Base + aiAnalysis (useAIV2=true) — análise V2: mesmo objeto base + aiAnalysis no mesmo formato unificado. generalInstructions opcional customiza o prompt da análise. tokens_used pode ser objeto ou número.

📦 Estrutura da Resposta

Resposta de Sucesso (Análise Básica)

{
  "success": true,
  "data": {
    "host_slug": "exemplo-host",
    "time_ranking": [1.2, 0.8, 2.1],
    "tolky_recap": "Resumo da conversa gerado pela IA",
    "message": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "conversation_id": "456e7890-e89b-12d3-a456-426614174001",
      "role": "assistant",
      "content": "Conteúdo da mensagem",
      "description": "Descrição da mensagem",
      "transcription": "Transcrição de áudio se aplicável",
      "url": "https://exemplo.com/arquivo",
      "host_id": "789e0123-e89b-12d3-a456-426614174002",
      "avatar_id": "012e3456-e89b-12d3-a456-426614174003",
      "request_control_id": "345e6789-e89b-12d3-a456-426614174004",
      "responder": "avatar-name",
      "campaign_id": "678e9012-e89b-12d3-a456-426614174005",
      "status": "delivered",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z",
      "deleted": false
    },
    "iaRequests": [
      {
        "id": "901e2345-e89b-12d3-a456-426614174006",
        "model": "gpt-4",
        "caller": "conversation-handler",
        "payload": {
          "messages": [...],
          "temperature": 0.7
        },
        "response": "Resposta da IA",
        "prompt_tokens": 150,
        "completion_tokens": 75,
        "total_tokens": 225,
        "cost": 0.0034,
        "createdAt": "2024-01-15T10:30:00Z"
      }
    ],
    "externalApiRequests": [
      {
        "request": "curl -X POST 'https://api.exemplo.com/endpoint' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"param\": \"value\"}'",
        "response": {
          "status": 200,
          "data": {...}
        }
      }
    ],
    "control": {
      "totalInputTokens": 150,
      "totalOutputTokens": 75,
      "timeControl": {
        "startTime": "2024-01-15T10:30:00Z",
        "endTime": "2024-01-15T10:30:05Z",
        "duration": 5000
      },
      "tolkyRequestLog": [
        "Log de requisição 1",
        "Log de requisição 2"
      ],
      "responseStatus": {
        "ok": true,
        "status": "delivered"
      },
      "promptChunkData": {
        "chunks": [...],
        "metadata": {...}
      }
    }
  }
}

Descrição Detalhada dos Campos

Campos Principais

  • host_slug: Slug identificador do host proprietário da mensagem
  • time_ranking: Array com métricas de tempo de processamento
  • tolky_recap: Resumo da conversa gerado pela IA Tolky
  • message: Objeto completo da mensagem investigada
  • iaRequests: Array com todas as requisições de IA realizadas
  • externalApiRequests: Array com chamadas para APIs externas (formatadas como curl)
  • control: Objeto com métricas e dados de controle

Objeto message

Contém todos os dados da mensagem do banco de dados:

CampoTipoDescrição
idstring (UUID)ID único da mensagem
conversation_idstring (UUID)ID da conversa à qual a mensagem pertence
rolestringPapel da mensagem (user, assistant, system)
contentstringConteúdo textual da mensagem
descriptionstringDescrição adicional da mensagem
transcriptionstringTranscrição de áudio (se aplicável)
urlstringURL de arquivo anexo (se aplicável)
host_idstring (UUID)ID do host proprietário
avatar_idstring (UUID)ID do avatar que processou a mensagem
request_control_idstring (UUID)ID do controle de requisição
responderstringNome do avatar responsável pela resposta
campaign_idstring (UUID)ID da campanha (se aplicável)
statusstringStatus da mensagem (delivered, failed, pending)
created_atstring (ISO 8601)Data de criação
updated_atstring (ISO 8601)Data da última atualização
deletedbooleanFlag indicando se a mensagem foi deletada

Array iaRequests

Contém todas as requisições de IA realizadas para processar a mensagem, ordenadas por data de criação:

CampoTipoDescrição
idstring (UUID)ID único da requisição de IA
modelstringModelo de IA utilizado (gpt-4, gpt-3.5-turbo, etc.)
callerstringIdentificador do componente que fez a chamada
payloadobjectDados enviados para a IA
responsestringResposta recebida da IA
prompt_tokensnumberNúmero de tokens de entrada
completion_tokensnumberNúmero de tokens de saída
total_tokensnumberTotal de tokens utilizados
costnumberCusto da requisição em USD
createdAtstring (ISO 8601)Data da requisição

Array externalApiRequests

Contém todas as chamadas para APIs externas realizadas, formatadas como comandos curl:

CampoTipoDescrição
requeststringComando curl da requisição para API externa
responseobjectResposta recebida da API externa (formato JSON)
correlationIdstringID de correlação request/response (quando presente)

Objeto control

Contém métricas e dados de controle:

CampoTipoDescrição
totalInputTokensnumberTotal de tokens de entrada utilizados
totalOutputTokensnumberTotal de tokens de saída utilizados
timeControlobjectMétricas de tempo de processamento
tolkyRequestLogarrayLog detalhado das requisições Tolky
responseStatusobjectStatus da resposta (ok, status)
promptChunkDataobjectDados dos chunks de prompt utilizados

🤖 Análise com IA

Quando useAI: true ou useAIV2: true, a resposta inclui um campo adicional aiAnalysis. O formato de aiAnalysis é unificado em ambos os modos (legado e V2). Com useAIV2: true é possível enviar generalInstructions para customizar o prompt da análise.

{
  "success": true,
  "data": {
    // ... todos os campos da análise básica ...
    "aiAnalysis": {
      "analysis": {
        "json": {
          "analyzed_parts": [
            {
              "conversation_part": "Primeira parte da mensagem gerada",
              "payload_contributions": [
                "Conteúdo específico do payload que influenciou esta parte",
                "Outro elemento relevante do payload"
              ],
              "reasoning": "Explicação detalhada do raciocínio por trás desta parte da resposta"
            },
            {
              "conversation_part": "Segunda parte da mensagem gerada",
              "payload_contributions": [
                "Elementos do payload que contribuíram para esta parte"
              ],
              "reasoning": "Explicação do raciocínio para esta parte"
            }
          ]
        },
        "formato": "json"
      },
      "error": null,
      "tokens_used": {
        "prompt_tokens": 1200,
        "completion_tokens": 800,
        "total_tokens": 2000
      }
    }
  }
}

Objeto aiAnalysis

Contém a análise detalhada realizada pela IA:

CampoTipoDescrição
analysis.json.analyzed_partsarrayArray com partes analisadas da mensagem
analysis.json.analyzed_parts[].conversation_partstringParte específica da mensagem gerada
analysis.json.analyzed_parts[].payload_contributionsarrayElementos do payload que influenciaram esta parte
analysis.json.analyzed_parts[].reasoningstringExplicação do raciocínio por trás desta parte
tokens_usedobject | numberTokens utilizados na análise (objeto com prompt_tokens, completion_tokens, total_tokens em useAI; em useAIV2 pode ser objeto ou valor único). null em caso de falha.

💡 Exemplos de Uso

  • 📤 Análise Básica

  • 📤 Com Análise IA (useAI)

  • 📤 Com Análise IA V2 (useAIV2)

  • 📥 Resposta Básica

  • 📥 Resposta com IA

curl -X POST "{{BASE_URL}}/api/externalAPIs/public/investigateMessage" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "messageId": "123e4567-e89b-12d3-a456-426614174000"
  }'

Exemplo Completo de Uso

#!/bin/bash

# Configurações
API_URL="{{BASE_URL}}/api/externalAPIs/public/investigateMessage"
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
MESSAGE_ID="123e4567-e89b-12d3-a456-426614174000"

echo "🔍 Investigando mensagem básica..."
response_basic=$(curl -s -X POST "$API_URL" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"messageId\": \"$MESSAGE_ID\"}")

if echo "$response_basic" | jq -e '.success' > /dev/null; then
    echo "✅ Investigação básica realizada com sucesso!"
    echo "Host: $(echo "$response_basic" | jq -r '.data.host_slug')"
    echo "Status: $(echo "$response_basic" | jq -r '.data.message.status')"
    echo "Total de tokens: $(echo "$response_basic" | jq -r '.data.control.totalInputTokens + .data.control.totalOutputTokens')"
    echo "Custo total IA: $(echo "$response_basic" | jq -r '[.data.iaRequests[].cost] | add')"
    echo "APIs externas chamadas: $(echo "$response_basic" | jq -r '.data.externalApiRequests | length')"
else
    echo "❌ Erro na investigação básica:"
    echo "$response_basic" | jq -r '.error.message'
    exit 1
fi

echo ""
echo "🤖 Investigando com análise IA (useAIV2 + generalInstructions)..."
response_ai=$(curl -s -X POST "$API_URL" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"messageId\": \"$MESSAGE_ID\", \"useAIV2\": true, \"generalInstructions\": \"Por que a resposta ficou tão formal?\"}")

if echo "$response_ai" | jq -e '.success' > /dev/null; then
    echo "✅ Análise com IA realizada com sucesso!"
    echo "Partes analisadas: $(echo "$response_ai" | jq -r '.data.aiAnalysis.analysis.json.analyzed_parts | length')"
    # tokens_used pode ser objeto (useAI) ou número (useAIV2)
    tokens=$(echo "$response_ai" | jq -r '.data.aiAnalysis.tokens_used')
    if echo "$tokens" | jq -e 'type == "object"' > /dev/null 2>&1; then
        echo "Tokens usados na análise: $(echo "$tokens" | jq -r '.total_tokens // .')"
    else
        echo "Tokens usados na análise: $tokens"
    fi
    echo ""
    echo "📋 Resumo da análise:"
    echo "$response_ai" | jq -r '.data.aiAnalysis.analysis.json.analyzed_parts[] | "- \(.conversation_part): \(.reasoning)"'
else
    echo "❌ Erro na análise com IA:"
    echo "$response_ai" | jq -r '.error.message'
fi

⚠️ Tratamento de Erros

Erro de Autenticação (401)

{
  "success": false,
  "error": {
    "message": "Invalid credentials",
    "code": 401
  }
}

Erro de Validação (400)

{
  "success": false,
  "error": {
    "message": "Message ID is required",
    "code": 400
  }
}

Mensagem Não Encontrada (404)

{
  "success": false,
  "error": {
    "message": "Message not found for id: 123e4567-e89b-12d3-a456-426614174000",
    "code": 404
  }
}

Erro de Banco de Dados (500)

{
  "success": false,
  "error": {
    "message": "Failed to get message by id: connection timeout",
    "code": 500
  }
}

Erro na Análise IA

{
  "success": true,
  "data": {
    // ... dados básicos ...
    "aiAnalysis": {
      "analysis": null,
      "error": "RequestControl ou payload não disponível para análise",
      "tokens_used": null
    }
  }
}

🚀 Casos de Uso

Análise Básica (useAI: false ou omitido)

Análise com IA (useAI: true ou useAIV2: true)


⚡ Cache e Performance

A rota implementa cache com TTL de 24 horas para otimizar performance:

  • Análise básica: messages/investigateMessageById/{messageId}
  • Análise com IA: messages/investigateMessageWithAI/{messageId}

Diferenças entre os modos

AspectoApenas baseuseAI (legado)useAIV2
RespostaSem aiAnalysisBase + aiAnalysisBase + aiAnalysis
CustomizaçãogeneralInstructions opcional
VelocidadeRápida (cache)Mais lenta (chamada IA)Mais lenta (chamada IA)
CustoSem custo extraTokens adicionaisTokens adicionais
Cache24h (investigateMessageById)24h (investigateMessageWithAI)24h (investigateMessageWithAI)

🔒 Limitações

  • Requer autenticação válida com token Bearer
  • Mensagem deve existir e não estar deletada
  • Cache de 24 horas pode retornar dados não atualizados
  • Análise com IA (useAI ou useAIV2) consome tokens adicionais
  • Dados sensíveis podem estar presentes nos logs de requisição
  • Análise com IA requer request_control e payload disponíveis
  • generalInstructions só tem efeito quando useAIV2: true
  • replaceDomainName substitui “tolky” na resposta (ex.: white-label)

🔄 Endpoints Relacionados

Tolky Reasoning

Para processamento de perguntas e respostas contextualizadas utilizando a inteligência do Tolky.

Endpoint: POST /api/externalAPIs/public/tolkyReasoning/callReasoning

Ver documentação completa

Smart Feedback

Para processamento assíncrono de múltiplas conversas com retomada inteligente.

Endpoint: POST /api/externalAPIs/public/tolkyReasoning/smartFeedback

Ver documentação completa