Configurar webhook HTTPS para finalização de chamado

Introdução

Este artigo descreve como configurar o webhook que é executado antes do chamado ser finalizado. O gatilho envia um POST HTTPS com payload JSON contendo informações do ticket, usuário e request_data.

Requisitos

  • URL em HTTPS (obrigatório).
  • Endpoint que aceite POST e header Content-Type: application/json.
  • Método de autenticação (Bearer token, Basic Auth ou assinatura HMAC recomendada).

Configuração do webhook

1. Defina a URL HTTPS

Use uma URL pública e válida em HTTPS (ex: https://seu-dominio.com/webhook). Certifique-se de que o certificado TLS seja válido e renovado automaticamente.

2. Headers e autenticação

Envie o header Content-Type: application/json. Para segurança, use um header Authorization: Bearer <TOKEN> ou uma assinatura HMAC no header (ex: X-Signature).

3. Método e corpo

O gatilho enviará um HTTP POST com um JSON contendo os objetos ticket, user e request_data. Verifique os campos _finalizado e _respondido para decidir ações internas.

4. Timeout, retries e idempotência

Defina timeout curto (5–10s). Em caso de falha, aplique retries exponenciais. Torne o processamento idempotente usando ticket.id para evitar duplicidade.

Exemplos de payload

Finalizado sem enviar resposta

Os dados abaixo serão enviados caso o usuário edite o chamado sem fornecer nenhuma reposta ou solução:

{
  "action": "api/chamados/editar/2",
  "ticket": {
    "id": 2,
    "created_at": "2025-09-25 15:34:46",
    "updated_at": "2025-11-18 12:09:56",
    "id_usuario": 3,
    "id_usuario_solicitante": 3,
    "id_grupo_usuario_solicitante": null,
    "id_usuario_ultima_mensagem": 2,
    "id_chamado_mestre": null,
    "id_chamado_etapa": 5,
    "id_chamado_acordo": 1,
    "id_chamado_tipo": 2,
    "id_setor": 1,
    "id_cliente": 1,
    "resposta_pendente": 0,
    "nome": "Chamado para testar a primeira vez",
    "observacoes": [],
    "nome_publico": "1763478596-SGPX98THPG-DGDCTH0RPR",
    "data_resposta": "2025-09-25 16:04:46",
    "data_solucao": "2025-09-26 15:04:46",
    "data_solucao_manual": 0,
    "data_real_resposta": "2025-10-21 15:09:00",
    "data_real_solucao": "2025-11-18 12:09:56",
    "data_ultima_resposta": "2025-11-18 12:09:56",
    "data_ultima_resposta_agente": "2025-11-18 12:09:56",
    "data_ultima_resposta_cliente": "2025-09-25 15:34:46",
    "dados_complementares": "null",
    "urgencia": 2,
    "respostas_pre_analise": [],
    "resposta_solucao": "Mensagem com uma imagem no meio\n",
    "avaliacao": 0,
    "ultima_avaliacao_enviada": null,
    "quantidade_avaliacoes_enviadas": 0,
    "origem": 2,
    "canal": "email",
    "ultima_resposta": "Finalizar este chamado",
    "modo_chat": 0,
    "situacao": "finalizado",
    "whatsapp_data_limite": null,
    "whatsapp_chat_id": null,
    "whatsapp_situacao": null,
    "ativo": 1,
    "data_analise": "2025-10-03 14:39:03",
    "_respondido": true,
    "_finalizado": true
  },
  "user": {
    "id": 2,
    "id_arquivo_foto": null,
    "id_sistema_aplicativo": null,
    "id_chamado_atual": null,
    "created_at": "2025-09-25 09:33:58",
    "updated_at": "2025-11-18 10:41:18",
    "id_usuario": 1,
    "id_usuario_tipo": 1,
    "nome": "Administrador",
    "telefone": null,
    "whatsapp": null,
    "email": "",
    "usuario": "administrador",
    "ultima_atualizacao_senha": "2025-09-25 09:34:57",
    "ip_ultimo_login": "192.168.65.1",
    "ultima_pagina": "",
    "nova_senha_codigo": "",
    "ultimo_login": "2025-11-18 10:41:18",
    "nova_senha_data": "0000-00-00 00:00:00",
    "acesso_admin": 1,
    "remember_token": "",
    "notificacao_email": 0,
    "valor_hora": 0,
    "chamado_setor_notificacoes": 0,
    "usuario_active_directory": 0,
    "origem": null,
    "origem_conf": null,
    "origem_codigo": null,
    "idioma": "pt",
    "ativo": 1
  },
  "request_data": {
    "id_setor": 1,
    "id_chamado_etapa": 5,
    "id_chamado_tipo": 2,
    "id_cliente": 1,
    "id_usuario_solicitante": 3,
    "nome": "Chamado para testar a primeira vez",
    "arquivos": null,
    "urgencia": 2,
    "respostas_pre_analise": [],
    "complementos": [
      {
        "id_complemento": 1,
        "valor": "número"
      },
      {
        "id_complemento": 2,
        "valor": "SAP"
      },
      {
        "id_complemento": 3,
        "valor": "Equipamento 1"
      },
      {
        "id_complemento": 4,
        "valor": "Sim"
      }
    ],
    "canal": "email",
    "ativo": 1
  }
}

Finalizado com resposta e solução

O exemplo abaixo será enviado quando um usuário responder um chamado e finalizar. Neste caso ele irá enviar uma resposta e uma solução para o chamado:

{
  "action": "api/chamados_respostas/gravar",
  "ticket": {
    "id": 2,
    "created_at": "2025-09-25 15:34:46",
    "updated_at": "2025-11-18 17:24:53",
    "id_usuario": 3,
    "id_usuario_solicitante": 3,
    "id_grupo_usuario_solicitante": null,
    "id_usuario_ultima_mensagem": 2,
    "id_chamado_mestre": null,
    "id_chamado_etapa": 4,
    "id_chamado_acordo": 1,
    "id_chamado_tipo": 2,
    "id_setor": 1,
    "id_cliente": 1,
    "resposta_pendente": 0,
    "nome": "Chamado para testar a primeira vez",
    "observacoes": [],
    "nome_publico": "1763478596-SGPX98THPG-DGDCTH0RPR",
    "data_resposta": "2025-09-25 16:04:46",
    "data_solucao": "2025-09-26 15:04:46",
    "data_solucao_manual": 0,
    "data_real_resposta": "2025-10-21 15:09:00",
    "data_real_solucao": "0000-00-00 00:00:00",
    "data_ultima_resposta": "2025-11-18 12:09:56",
    "data_ultima_resposta_agente": "2025-11-18 12:09:56",
    "data_ultima_resposta_cliente": "2025-09-25 15:34:46",
    "dados_complementares": "null",
    "urgencia": 2,
    "respostas_pre_analise": [],
    "resposta_solucao": null,
"avaliacao": 0, "ultima_avaliacao_enviada": null, "quantidade_avaliacoes_enviadas": 0, "origem": 2, "canal": "email", "ultima_resposta": "Finalizar este chamado", "modo_chat": 0, "situacao": "respondido", "whatsapp_data_limite": null, "whatsapp_chat_id": null, "whatsapp_situacao": null, "ativo": 1, "data_analise": "2025-10-03 14:39:03", "_respondido": true, "_finalizado": false }, "user": { "id": 2, "id_arquivo_foto": null, "id_sistema_aplicativo": null, "id_chamado_atual": null, "created_at": "2025-09-25 09:33:58", "updated_at": "2025-11-18 10:41:18", "id_usuario": 1, "id_usuario_tipo": 1, "nome": "Administrador", "telefone": null, "whatsapp": null, "email": "", "usuario": "administrador", "ultima_atualizacao_senha": "2025-09-25 09:34:57", "ip_ultimo_login": "192.168.65.1", "ultima_pagina": "", "nova_senha_codigo": "", "ultimo_login": "2025-11-18 10:41:18", "nova_senha_data": "0000-00-00 00:00:00", "acesso_admin": 1, "remember_token": "", "notificacao_email": 0, "valor_hora": 0, "chamado_setor_notificacoes": 0, "usuario_active_directory": 0, "origem": null, "origem_conf": null, "origem_codigo": null, "idioma": "pt", "ativo": 1 }, "request_data": { "id_chamado": 2, "id_chamado_etapa": 5, "resposta_solucao": "Resposta selecionada como sendo a solução do chamado", "descricao": "Finalizar este chamado com uma solução", "tipo": 0, "origem": 0, "ativo": 1, "arquivos": [], "usuarios": [] } }

Testes com curl

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -d @payload.json \
  https://seu-endpoint/webhook

Resposta esperada

Seu endpoint deve retornar HTTP 200 OK para confirmar que recebeu e processou o evento. Retorne 4xx para erros do cliente (sem retry) e 5xx para falhas temporárias (o remetente pode reenviar).

Boas práticas e segurança

  • Verifique assinatura HMAC (ex: X-Signature: sha256=...) usando um segredo compartilhado.
  • Registre logs (request id, ticket.id, status) para auditoria e troubleshooting.
  • Não processe payloads grandes na requisição síncrona — aceite e processe assincronamente quando necessário.
  • Implemente rate limiting e proteja contra replay attacks (timestamp + nonce).

Seguindo esses passos você terá um webhook seguro e confiável para receber notificações antes da finalização dos chamados.

Alguma dúvida?
Abrir chamado