Skip to main content

# Webhooks - Krayin CRM v2.1.6

Configuração e uso de webhooks para integração em tempo real.


📋 Índice

  1. Visão Geral
  2. Eventos Disponíveis
  3. Configuração
  4. Payload dos Eventos
  5. Validação de Assinatura
  6. Retry Policy
  7. Exemplos Práticos

Visão Geral

Webhooks permitem que o Krayin CRM notifique sistemas externos quando eventos ocorrem, sem necessidade de polling.

┌─────────────────┐      Evento       ┌─────────────────┐
│   Krayin CRM    │  ─────────────►  │   Seu Sistema   │
│  (Lead criado)  │   POST JSON       │   (N8N, etc)    │
└─────────────────┘                   └─────────────────┘

Eventos Disponíveis

Leads

Evento Trigger
leads.created Novo lead criado
leads.updated Lead modificado
leads.deleted Lead deletado
leads.converted Lead convertido para oportunidade

Contacts

Evento Trigger
contacts.created Novo contato/organização criado
contacts.updated Contato modificado
contacts.deleted Contato deletado

Activities

Evento Trigger
activities.created Nova atividade criada
activities.updated Atividade modificada
activities.completed Atividade marcada como concluída

Quotes

Evento Trigger
quotes.created Nova cotação criada
quotes.updated Cotação modificada
quotes.sent Cotação enviada ao cliente

Configuração

Via Interface Admin

  1. Acesse: Settings → Webhooks
  2. Clique em Criar Webhook
  3. Preencha:
    • Nome: Identificador (ex: "N8N - Novos Leads")
    • Entity Type: Entidade que dispara (Leads, Contacts, etc)
    • Events: Eventos desejados (created, updated, deleted)
    • URL: Endpoint que receberá o webhook
    • Headers: Headers customizados (opcional)
    • Active: Ativar/Desativar

Via API

curl -X POST "https://crm.memudecore.com.br/api/v1/webhooks" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "N8N - Leads Sync",
    "entity_type": "leads",
    "events": ["created", "updated", "converted"],
    "url": "https://n8n.memudecore.com.br/webhook/krayin-leads",
    "headers": {
      "Authorization": "Bearer meu_webhook_secret",
      "X-Source": "krayin-crm"
    },
    "is_active": true
  }'

Payload dos Eventos

Estrutura Geral

{
  "id": "webhook_trigger_abc123",
  "event": "leads.created",
  "entity_type": "leads",
  "timestamp": "2026-01-18T12:30:00Z",
  "data": {
    // Dados completos da entidade
  }
}

Lead Created

{
  "id": "wh_001",
  "event": "leads.created",
  "entity_type": "leads",
  "timestamp": "2026-01-18T12:30:00Z",
  "data": {
    "id": 42,
    "title": "Empresa ABC",
    "source_id": 1,
    "source": {
      "id": 1,
      "name": "WhatsApp"
    },
    "lead_type_id": 2,
    "sales_owner_id": 1,
    "sales_owner": {
      "id": 1,
      "name": "João Vendedor",
      "email": "joao@empresa.com"
    },
    "status_id": 1,
    "value": 5000,
    "expected_close_date": "2026-02-28",
    "description": "Lead interessado no plano premium",
    "contact_person": {
      "id": 5,
      "name": "Maria Silva",
      "email": "maria@abc.com"
    },
    "organization": {
      "id": 3,
      "name": "ABC Ltda"
    },
    "tags": ["whatsapp", "premium"],
    "created_at": "2026-01-18T12:30:00Z",
    "updated_at": "2026-01-18T12:30:00Z"
  }
}

Lead Updated

{
  "id": "wh_002",
  "event": "leads.updated",
  "entity_type": "leads",
  "timestamp": "2026-01-18T14:00:00Z",
  "data": {
    "id": 42,
    "title": "Empresa ABC",
    "value": 7500,
    "status_id": 2,
    "updated_at": "2026-01-18T14:00:00Z"
  },
  "changes": {
    "value": {
      "old": 5000,
      "new": 7500
    },
    "status_id": {
      "old": 1,
      "new": 2
    }
  }
}

Lead Converted

{
  "id": "wh_003",
  "event": "leads.converted",
  "entity_type": "leads",
  "timestamp": "2026-01-20T10:00:00Z",
  "data": {
    "lead_id": 42,
    "contact_created": true,
    "organization_created": false,
    "new_contact_id": 15,
    "converted_by": {
      "id": 1,
      "name": "João Vendedor"
    }
  }
}

Activity Created

{
  "id": "wh_004",
  "event": "activities.created",
  "entity_type": "activities",
  "timestamp": "2026-01-18T15:00:00Z",
  "data": {
    "id": 100,
    "type": "call",
    "title": "Ligação de follow-up",
    "description": "Confirmar interesse",
    "lead_id": 42,
    "lead": {
      "id": 42,
      "title": "Empresa ABC"
    },
    "scheduled_from": "2026-01-20T14:00:00Z",
    "scheduled_to": "2026-01-20T14:30:00Z",
    "is_done": false,
    "user": {
      "id": 1,
      "name": "João Vendedor"
    }
  }
}

Validação de Assinatura

O Krayin pode incluir uma assinatura HMAC-SHA256 para validar autenticidade.

Header de Assinatura

X-Krayin-Signature: sha256=abc123...

Validar em PHP

<?php
function validateWebhook($payload, $signature, $secret) {
    $expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
    return hash_equals($expected, $signature);
}

// Uso
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_KRAYIN_SIGNATURE'] ?? '';
$secret = 'seu_webhook_secret';

if (!validateWebhook($payload, $signature, $secret)) {
    http_response_code(401);
    exit('Invalid signature');
}

$data = json_decode($payload, true);
// Processar webhook...

Validar em Node.js

const crypto = require('crypto');

function validateWebhook(payload, signature, secret) {
    const expected = 'sha256=' + 
        crypto.createHmac('sha256', secret)
              .update(payload)
              .digest('hex');
    
    return crypto.timingSafeEqual(
        Buffer.from(expected),
        Buffer.from(signature)
    );
}

// Uso com Express
app.post('/webhook', (req, res) => {
    const signature = req.headers['x-krayin-signature'];
    const payload = JSON.stringify(req.body);
    
    if (!validateWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
        return res.status(401).send('Invalid signature');
    }
    
    // Processar webhook...
    res.status(200).send('OK');
});

Retry Policy

Quando um webhook falha, o Krayin tenta novamente automaticamente.

Política de Retry

Tentativa Delay Total Acumulado
1 Imediato 0
2 1 minuto 1 min
3 5 minutos 6 min
4 15 minutos 21 min
5 1 hora 1h 21min

Códigos de Resposta

Código Comportamento
2xx Sucesso, não retry
4xx Erro do cliente, não retry (exceto 429)
429 Rate limit, retry com backoff
5xx Erro do servidor, retry
Timeout Retry

Resposta Esperada

Seu endpoint deve retornar:

HTTP/1.1 200 OK
Content-Type: application/json

{"status": "received"}

Exemplos Práticos

Webhook para N8N

Configuração no Krayin:

{
  "name": "N8N - Todos os Leads",
  "entity_type": "leads",
  "events": ["created", "updated", "converted"],
  "url": "https://n8n.memudecore.com.br/webhook/abc123",
  "is_active": true
}

Workflow N8N:

1. Webhook Trigger
   - Method: POST
   - Path: /webhook/abc123

2. Switch Node (baseado em event)
   - leads.created → Criar tarefa no Asana
   - leads.updated → Atualizar Google Sheets
   - leads.converted → Enviar email de parabéns

3. HTTP Request para ações

Webhook para Slack

Enviar notificação quando lead é criado:

// Seu endpoint
app.post('/webhook/krayin-to-slack', async (req, res) => {
    const { event, data } = req.body;
    
    if (event === 'leads.created') {
        await fetch(process.env.SLACK_WEBHOOK_URL, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                text: `🎉 Novo Lead: ${data.title}`,
                blocks: [
                    {
                        type: 'section',
                        text: {
                            type: 'mrkdwn',
                            text: `*Novo Lead Criado*\n` +
                                  `*Título:* ${data.title}\n` +
                                  `*Valor:* R$ ${data.value}\n` +
                                  `*Vendedor:* ${data.sales_owner.name}`
                        }
                    }
                ]
            })
        });
    }
    
    res.status(200).json({ status: 'ok' });
});

Webhook para WhatsApp (Evolution API)

Notificar vendedor via WhatsApp quando lead é criado:

app.post('/webhook/krayin-to-whatsapp', async (req, res) => {
    const { event, data } = req.body;
    
    if (event === 'leads.created') {
        // Buscar telefone do vendedor
        const sellerPhone = await getSellerPhone(data.sales_owner_id);
        
        // Enviar mensagem via Evolution API
        await fetch('https://evolution.memudecore.com.br/message/sendText/instance', {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${process.env.EVOLUTION_API_KEY}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                number: sellerPhone,
                text: `🆕 *Novo Lead Atribuído*\n\n` +
                      `*${data.title}*\n` +
                      `Valor: R$ ${data.value || 'Não informado'}\n` +
                      `Fonte: ${data.source?.name || 'Não informada'}\n\n` +
                      `Acesse: https://crm.memudecore.com.br/admin/leads/view/${data.id}`
            })
        });
    }
    
    res.status(200).json({ status: 'ok' });
});

🔧 Debug de Webhooks

Verificar Logs

# Ver logs de webhooks enviados
docker exec krayin grep "webhook" storage/logs/laravel.log | tail -50

Testar Endpoint

# Simular webhook localmente
curl -X POST "http://localhost:3000/webhook/test" \
  -H "Content-Type: application/json" \
  -H "X-Krayin-Signature: sha256=test" \
  -d '{
    "event": "leads.created",
    "data": {"id": 1, "title": "Teste"}
  }'

Ferramentas Úteis

  • webhook.site - Endpoint temporário para debug
  • requestbin.com - Inspecionar payloads
  • ngrok - Expor localhost para testes

Última atualização: Janeiro 2026