En esta sección
Guías / Webhooks entrantes

Webhooks entrantes

Registra endpoints que disparan tareas o emiten eventos, con firma HMAC.

Actualizada el Ver .md

Un webhook entrante es un endpoint que Meteor expone para que un tercero le haga POST. Cuando llega un evento, Meteor puede disparar una tarea o emitir un evento interno. Necesita el scope webhooks:manage.

Estos son webhooks entrantes (tercero → Meteor). Si lo que quieres es que Meteor te avise cuando pasa algo (run.completed, etc.), salta a Eventos salientes más abajo.

Crear un webhook

const wh = await met.webhooks.create({
  name: 'Entrada de leads',
  binding_type: 'generic',        // 'task' ejecuta una tarea; 'generic' solo emite evento
  verifier_type: 'hmac_sha256',   // 'none' para sin firma
});

console.log(wh.url);      // la URL a la que apunta el tercero
console.log(wh.secret);   // ⚠️ se muestra UNA sola vez

Guarda el secret apenas lo recibes: no se vuelve a mostrar. Con él verificas que cada entrega vino realmente de tu integración.

Verificar la firma

El tercero firma el cuerpo con el secret (HMAC-SHA256) y manda la firma en un header. Del lado de Meteor, la verificación es automática si el webhook es hmac_sha256.

Rotar el secret

Si sospechas que se filtró:

const rotated = await met.webhooks.rotateSecret(wh.id);
console.log(rotated.secret);   // nuevo secret; invalida el anterior

Ver entregas

const events = await met.webhooks.events(wh.id, { limit: 20 });
const sample = await met.webhooks.sample(wh.id);   // último payload recibido

sample es útil para configurar el mapeo de campos del payload.

Conectar un flujo

Un webhook generic puede disparar un flujo cuando recibe un evento (connectFlow en la API). Así, un POST externo arranca una automatización completa en Meteor.

Eventos salientes (Meteor → tu servidor)

Un evento saliente es Meteor haciéndote POST a *ti* cuando algo pasa en tu workspace — por ejemplo, cuando un Run termina. Registras un endpoint, eliges qué eventos quieres, y Meteor entrega cada uno firmado con HMAC para que puedas verificar que vino de Meteor.

Registrar un endpoint

Registras el endpoint desde tu panel: Desarrolladores → Actividad → Webhooks. Eliges la URL de tu servidor y qué eventos quieres (o * para todos). Al crearlo, Meteor te muestra el secreto de firma (whsec_...) una sola vez — guárdalo, lo necesitas para verificar cada entrega.

Catálogo de eventos

Son 17. La columna scope es el permiso que la key debe portar para recibir ese evento: el mismo con el que leerías ese recurso por la API.

EventoCuándo disparaScope
run.completedUn Run terminó con éxito.runs:read
run.failedUn Run falló.runs:read
channel.run.completedEl Met respondió un mensaje de canal.runs:read
channel.run.failedEl Met falló al responder un mensaje de canal.runs:read
contact.createdSe creó un contacto.contacts:read
contact.updatedSe actualizó un contacto.contacts:read
contact.message.receivedEntró un mensaje de un contacto por un canal (WhatsApp, etc.).conversations:read
conversation.handoffUna conversación pasó a operador humano.conversations:read
task.completedUna tarea agéntica terminó.tasks:read
billing.thresholdEl gasto de Energía de una API key cruzó un umbral de su presupuesto (50/80/100%).billing:read
app.authorizedUn workspace autorizó tu app OAuth (nuevo grant).integrations:read
app.revokedUn workspace revocó el acceso de tu app OAuth (grant revocado).integrations:read
snapshot.publishedUna plantilla propia fue aprobada y publicada al marketplace.snapshots:read
snapshot.install.completedLa instalación de una plantilla terminó.snapshots:read
snapshot.install.failedLa instalación de una plantilla falló.snapshots:read
conversion.sentUna conversión se emitió con éxito a Meta (CAPI).conversions:read
conversion.discardedUna conversión propuesta fue descartada por la compuerta (incluye la razón).conversions:read

* no es un evento: es el comodín «todos los del catálogo», y cubre también los que agreguemos después. Si prefieres enterarte de un evento nuevo antes de empezar a recibirlo, suscríbete a la lista explícita.

Tres cosas que ahorran una depuración:

Esta misma tabla la devuelve la API, siempre al día:

const { data } = await met.webhooks.subscriptions.eventTypes();
// [{ type: 'run.completed', description: '…', scope: 'runs:read' }, …]

Verificar la firma

Cada entrega trae el header X-Met-Signature: t=<ts>,v1=<hmac>. Nunca proceses un evento sin verificarlo — usa el helper del SDK, que hace la verificación timing-safe y chequea el timestamp (anti-replay):

import Met from '@meteor.ia/sdk';
const met = new Met(process.env.MET_API_KEY!);

app.post('/webhooks/met', (req, res) => {
  let event;
  try {
    event = met.webhooks.constructEvent(req.rawBody, req.headers['x-met-signature'], WHSEC);
  } catch {
    return res.status(400).send('firma inválida');
  }
  if (event.type === 'run.completed') { /* ... */ }
  res.sendStatus(200);   // responde 2xx rápido; Meteor reintenta si no.
});

Necesitas el cuerpo crudo (raw body) para verificar la firma — configura tu framework para no re-serializar el JSON antes de constructEvent.

Reintentos

Si tu endpoint no responde 2xx, Meteor reintenta con backoff exponencial (1 min → 5 min → 30 min → 2 h → 6 h → 24 h) hasta 6 intentos. Después marca la entrega como failed. El log de intentos por endpoint está en tu Workbench (sección Desarrolladores).