Ir al contenido

Eventos (webhooks)

Con los eventos, Catita avisa a tu bot cuando pasa algo en el servidor, sin que tenga que preguntar.

En /settings > API > Añadir webhook, pon la URL de tu bot (tiene que ser https y pública). Catita te enseña una vez el secreto de firma (whsec_…): guárdalo. Hasta 3 webhooks por servidor.

En la pantalla del webhook eliges los eventos, lo pruebas con Probar (envía un ping), cambias el secreto o lo apagas.

Evento Cuándo data
level.up Alguien sube de nivel userId, instance, level, oldLevel
level.rebirth Alguien hace rebirth userId, instance, rebirths, level
streak.updated Alguien avanza su racha userId, instance, current, best
customrole.key_redeemed Alguien canjea una llave de rol propio userId, key, days
economy.wallet_changed La API cambia una cartera userId, instance, amount, wallet, keyId

Un POST con JSON:

{
"id": "6f1c…",
"type": "level.up",
"guildId": "111111111111111111",
"createdAt": "2026-11-04T18:00:00.000Z",
"data": { "userId": "123456789012345678", "instance": "1", "level": 12, "oldLevel": 11 }
}

Y estas cabeceras:

  • Catita-Event: el tipo.
  • Catita-Delivery: el id del evento (si llega dos veces, ignora el repetido).
  • Catita-Timestamp: segundos Unix del envío.
  • Catita-Signature: v1= y el HMAC-SHA256 en hexadecimal de <timestamp>.<cuerpo> con tu secreto.

Responde con un 2xx en menos de 5 segundos. Si falla, Catita lo reintenta 5 veces más con espera creciente (10 s, 20 s, 40 s…). Tras 25 fallos seguidos, apaga el webhook y avisa en el canal de registros. No sigue redirecciones.

Comprueba siempre la firma y que la hora no sea vieja, para saber que el aviso es de Catita:

const crypto = require('node:crypto');
const express = require('express');
const app = express();
app.post('/catita', express.raw({ type: 'application/json' }), (req, res) => {
const timestamp = req.get('Catita-Timestamp');
const given = req.get('Catita-Signature') || '';
const expected = 'v1=' + crypto
.createHmac('sha256', process.env.CATITA_WEBHOOK_SECRET)
.update(`${timestamp}.${req.body}`)
.digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300;
const valid = given.length === expected.length && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
if (!fresh || !valid) return res.sendStatus(401);
const event = JSON.parse(req.body);
if (event.type === 'level.up') {
console.log(`${event.data.userId} llegó al nivel ${event.data.level}`);
}
res.sendStatus(204);
});
app.listen(3000);

Usa el cuerpo tal cual llega (sin volver a convertirlo a JSON), o la firma no coincidirá.

Catita es un proyecto de Random Dev, estudio de desarrollo de ZENU GROUP LLC. catita.gg