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

EventoTrigger
leads.createdNovo lead criado
leads.updatedLead modificado
leads.deletedLead deletado
leads.convertedLead convertido para oportunidade

Contacts

EventoTrigger
contacts.createdNovo contato/organização criado
contacts.updatedContato modificado
contacts.deletedContato deletado

Activities

EventoTrigger
activities.createdNova atividade criada
activities.updatedAtividade modificada
activities.completedAtividade marcada como concluída

Quotes

EventoTrigger
quotes.createdNova cotação criada
quotes.updatedCotação modificada
quotes.sentCotaçã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

TentativaDelayTotal Acumulado
1Imediato0
21 minuto1 min
35 minutos6 min
415 minutos21 min
51 hora1h 21min

Códigos de Resposta

CódigoComportamento
2xxSucesso, não retry
4xxErro do cliente, não retry (exceto 429)
429Rate limit, retry com backoff
5xxErro do servidor, retry
TimeoutRetry

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