Obter Tickets
Endpoint para buscar tickets com sistema de hierarquia de critérios e filtros avançados
Visão Geral
O endpoint /api/externalAPIs/public/tickets/getTickets permite buscar tickets usando um sistema de hierarquia de critérios inteligente, com priorização automática baseada nos parâmetros fornecidos.
O sistema usa uma lógica de prioridade hierárquica: ticketId (prioridade máxima) > leadId > conversationId (prioridade mínima).
Características Principais
- Busca Hierárquica: Sistema de prioridade inteligente (ticketId > leadId > conversationId)
- Dados Enriquecidos: Informações completas do ticket com entidades relacionadas
- Filtros Avançados: Filtros por avatar, inclusão de eventos, fechados e deletados
- Histórico de Eventos: Opção de incluir histórico completo de eventos
- Performance Otimizada: Utiliza índices existentes do banco de dados
Casos de Uso
- Recuperar ticket específico por ID
- Obter todos os tickets de um lead/cliente
- Obter todos os tickets de uma conversa
- Filtrar tickets por avatar/agente específico
- Construir dashboards e relatórios com dados completos
Endpoint
POST /api/externalAPIs/public/tickets/getTickets
Autenticação
- Header:
Authorization: Bearer <token> - Content-Type:
application/json - Middleware:
tolkyAuthMiddleware(resolvehostIdautomaticamente)
Parâmetros de Consulta
Identificadores (Prioridade Hierárquica)
| Parâmetro | Tipo | Obrigatório | Descrição | Prioridade |
|---|---|---|---|---|
ticketId | string (UUID) | Não | ID específico do ticket | 1 (Mais alta) |
leadId | string (UUID) | Não | ID do lead/cliente | 2 |
conversationId | string (UUID) | Não | ID da conversa | 3 (Mais baixa) |
Filtros Opcionais
| Parâmetro | Tipo | Descrição |
|---|---|---|
avatarId | string (UUID) | array | Filtrar por avatar específico ou múltiplos avatares |
includeEvents | boolean | Incluir histórico de eventos (padrão: true) |
includeClosed | boolean | Incluir tickets fechados (padrão: true) |
includeDeleted | boolean | Incluir tickets deletados (padrão: false) |
Regras de Negócio
- Obrigatório: Estar autenticado (host filtrado pelo middleware)
- Critério Mínimo: Pelo menos um entre
ticketId,leadIdouconversationId - Prioridade: Se múltiplos identificadores forem fornecidos, o de maior prioridade prevalece
- Host:
hostIdé resolvido automaticamente pelo middleware
Exemplos de Requisição
Buscar Ticket Específico
{
"ticketId": "b8c9f8c4-0b6a-4b2a-8f8f-0c9d9e2f5a1a",
"includeEvents": true
}
Buscar por Lead
{
"leadId": "5db2c5f7-16b7-40e5-9a0f-f7f0c69c3e77",
"includeClosed": false,
"includeEvents": true
}
Buscar por Conversa com Filtro de Avatar
{
"conversationId": "0c8e3fa7-0601-4a75-9b9c-c1c919c50a8c",
"avatarId": [
"e0fe2a9f-7c1e-4c73-8c70-cb7b0f2e99e0",
"a45b9ce4-9c57-4725-8a28-2252cd039699"
],
"includeDeleted": false
}
Buscar Múltiplos Avatares
{
"leadId": "5db2c5f7-16b7-40e5-9a0f-f7f0c69c3e77",
"avatarId": "e0fe2a9f-7c1e-4c73-8c70-cb7b0f2e99e0",
"includeEvents": true,
"includeClosed": true
}
Resposta de Sucesso
{
"code": 200,
"success": true,
"data": [
{
"id": "b8c9f8c4-0b6a-4b2a-8f8f-0c9d9e2f5a1a",
"protocol": "ABCD-1234",
"subject": "Problema de conectividade",
"description": "Usuário reporta dificuldades para acessar o sistema",
"definitionOfDone": "Sistema funcionando normalmente",
"status": {
"name": "Em Progresso",
"level": 2,
"color": "#F6AD55",
"isClosed": false
},
"createdAt": "2025-01-15T09:00:00.000Z",
"updatedAt": "2025-01-15T10:30:00.000Z",
"importance": 3,
"importanceColor": "#F6AD55",
"closed": false,
"closedAt": null,
"deleted": false,
"hostId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"leadId": "5db2c5f7-16b7-40e5-9a0f-f7f0c69c3e77",
"conversationId": "0c8e3fa7-0601-4a75-9b9c-c1c919c50a8c",
"sessionId": "s1e2s3s4-i5o6-n789-0abc-def123456789",
"avatarId": "e0fe2a9f-7c1e-4c73-8c70-cb7b0f2e99e0",
"externalId": "EXT-12345",
"movedByIa": false,
"lastSeen": null,
"lastSeenBy": null,
"lastConversationUpdate": "2025-01-15T10:30:00.000Z",
"assignedUser": {
"id": "4a6b9f6e-0f2f-4e2b-9a77-98b0d64c4d11",
"name": "João Silva"
},
"contact": {
"name": "Maria Santos",
"email": "maria@empresa.com",
"phone": "55999998888"
},
"events": [
{
"id": "evt-789",
"type": "status",
"createdAt": "2025-01-15T09:00:00.000Z",
"description": "Ticket criado automaticamente",
"summary": "Status alterado para: Em Progresso",
"pendingActions": null,
"email": null,
"wpp": null,
"userId": "4a6b9f6e-0f2f-4e2b-9a77-98b0d64c4d11"
},
{
"id": "evt-790",
"type": "info",
"createdAt": "2025-01-15T10:30:00.000Z",
"description": "Ticket atribuído ao usuário João Silva",
"summary": "Atribuição realizada",
"pendingActions": null,
"email": null,
"wpp": null,
"userId": "4a6b9f6e-0f2f-4e2b-9a77-98b0d64c4d11"
}
],
"ticketLevelId": "3fb2a9f0-5aa3-4f6d-8d37-c2a0b1d7b9a2"
}
],
"count": 1,
"searchCriteria": {
"ticketId": "b8c9f8c4-0b6a-4b2a-8f8f-0c9d9e2f5a1a",
"leadId": null,
"conversationId": null,
"hostId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"avatarId": null
},
"message": "Successfully retrieved 1 ticket(s)"
}
Estrutura dos Dados
Ticket Object
| Campo | Tipo | Descrição |
|---|---|---|
id | string (UUID) | ID único do ticket |
protocol | string | Protocolo/número do ticket |
subject | string | Assunto do ticket |
description | string | Descrição detalhada |
definitionOfDone | string | Definição de pronto (DOD) |
status | object | Status atual do ticket |
status.name | string | Nome do status |
status.level | number | Nível numérico do status |
status.color | string | Cor do status (hex) |
status.isClosed | boolean | Se o status indica fechamento |
createdAt | string | Data de criação (ISO 8601) |
updatedAt | string | Data da última atualização (ISO 8601) |
importance | number | Nível de importância (1-4) |
importanceColor | string | Cor da importância (hex) |
closed | boolean | Se o ticket está fechado |
closedAt | string | null | Data de fechamento (ISO 8601) |
deleted | boolean | Se o ticket foi deletado |
hostId | string (UUID) | ID do host |
leadId | string (UUID) | ID do lead/cliente |
conversationId | string (UUID) | ID da conversa |
sessionId | string (UUID) | ID da sessão |
avatarId | string (UUID) | ID do avatar responsável |
externalId | string | ID externo do ticket |
movedByIa | boolean | Se foi movido por IA |
lastSeen | string | null | Última visualização |
lastSeenBy | string | null | Último usuário que visualizou |
lastConversationUpdate | string | null | Última atualização da conversa |
assignedUser | object | null | Usuário responsável |
contact | object | Dados do contato |
events | array | Histórico de eventos |
ticketLevelId | string (UUID) | ID do nível atual |
AssignedUser Object
| Campo | Tipo | Descrição |
|---|---|---|
id | string (UUID) | ID do usuário |
name | string | Nome do usuário |
Contact Object
| Campo | Tipo | Descrição |
|---|---|---|
name | string | Nome do contato |
email | string | Email do contato |
phone | string | Telefone do contato |
Event Object
| Campo | Tipo | Descrição |
|---|---|---|
id | string (UUID) | ID único do evento |
type | string | Tipo do evento (status, info, motivo) |
createdAt | string | Data/hora do evento (ISO 8601) |
description | string | Descrição do evento |
summary | string | Resumo do evento |
pendingActions | object | null | Ações pendentes |
email | object | null | Dados de email |
wpp | object | null | Dados de WhatsApp |
userId | string (UUID) | ID do usuário responsável |
Códigos de Erro
| Código | Erro | Descrição | Solução |
|---|---|---|---|
400 | MissingSearchParameter | Nenhum parâmetro de busca fornecido | Fornecer pelo menos um identificador (ticketId, leadId ou conversationId) |
403 | Invalid credentials | Credenciais inválidas | Verificar token de autenticação |
500 | GetTicketsError | Erro interno na busca | Contatar suporte técnico |
Exemplo com cURL
curl -X POST "$BASE_URL/api/externalAPIs/public/tickets/getTickets" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"leadId": "5db2c5f7-16b7-40e5-9a0f-f7f0c69c3e77",
"includeEvents": true,
"includeClosed": false
}'
Exemplo de Integração Completa
class TicketRetriever {
constructor(apiToken, baseUrl) {
this.apiToken = apiToken;
this.baseUrl = baseUrl;
}
async getTickets(params = {}) {
try {
const response = await fetch(`${this.baseUrl}/api/externalAPIs/public/tickets/getTickets`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiToken}`
},
body: JSON.stringify(params)
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Erro ${response.status}: ${error.message}`);
}
return await response.json();
} catch (error) {
console.error('Erro ao buscar tickets:', error);
throw error;
}
}
// Buscar ticket específico
async getTicketById(ticketId, includeEvents = true) {
return await this.getTickets({
ticketId,
includeEvents
});
}
// Buscar tickets de um lead
async getTicketsByLead(leadId, filters = {}) {
return await this.getTickets({
leadId,
includeEvents: true,
includeClosed: true,
...filters
});
}
// Buscar tickets de uma conversa
async getTicketsByConversation(conversationId, filters = {}) {
return await this.getTickets({
conversationId,
includeEvents: true,
includeClosed: true,
...filters
});
}
// Buscar tickets por avatar
async getTicketsByAvatar(avatarId, additionalFilters = {}) {
return await this.getTickets({
avatarId,
includeEvents: true,
includeClosed: true,
...additionalFilters
});
}
// Buscar tickets abertos de um lead
async getOpenTicketsByLead(leadId) {
return await this.getTickets({
leadId,
includeEvents: true,
includeClosed: false
});
}
// Buscar tickets com eventos específicos
async getTicketsWithEvents(criteria) {
return await this.getTickets({
...criteria,
includeEvents: true
});
}
}
// Uso da classe
const ticketRetriever = new TicketRetriever('seu_token_aqui', 'https://api.tolky.to');
// Exemplos de uso
async function examples() {
try {
// Buscar ticket específico
const ticket = await ticketRetriever.getTicketById('b8c9f8c4-0b6a-4b2a-8f8f-0c9d9e2f5a1a');
console.log('Ticket encontrado:', ticket.data[0]);
// Buscar tickets de um lead
const leadTickets = await ticketRetriever.getTicketsByLead('5db2c5f7-16b7-40e5-9a0f-f7f0c69c3e77', {
includeClosed: false
});
console.log(`Tickets abertos do lead: ${leadTickets.data.length}`);
// Buscar tickets por avatar
const avatarTickets = await ticketRetriever.getTicketsByAvatar('e0fe2a9f-7c1e-4c73-8c70-cb7b0f2e99e0');
console.log(`Tickets do avatar: ${avatarTickets.data.length}`);
// Buscar tickets de uma conversa específica
const conversationTickets = await ticketRetriever.getTicketsByConversation('0c8e3fa7-0601-4a75-9b9c-c1c919c50a8c');
console.log(`Tickets da conversa: ${conversationTickets.data.length}`);
// Processar eventos dos tickets
leadTickets.data.forEach(ticket => {
if (ticket.events && ticket.events.length > 0) {
console.log(`Ticket ${ticket.protocol} tem ${ticket.events.length} eventos`);
ticket.events.forEach(event => {
console.log(`- ${event.type}: ${event.description}`);
});
}
});
} catch (error) {
console.error('Erro:', error.message);
}
}
Sistema de Prioridade Hierárquica
O sistema implementa uma lógica de prioridade inteligente:
- ticketId (Prioridade 1): Busca direta por ID específico
- leadId (Prioridade 2): Busca todos os tickets de um lead
- conversationId (Prioridade 3): Busca todos os tickets de uma conversa
Importante: Forneça pelo menos um identificador (ticketId, leadId ou conversationId). Requisições sem identificadores resultarão em erro 400.
Dica: Use includeEvents=true para obter o histórico completo de eventos, útil para auditoria e acompanhamento detalhado.
Nota: O parâmetro includeDeleted=false por padrão exclui tickets deletados. Use includeDeleted=true apenas quando necessário para auditoria ou recuperação de dados.