Skip to content
ver .md sin procesar

Reacciona a los cambios en Plan con webhooks

Recibe eventos de Dailybot Plan en tu propio endpoint: los 25 eventos tasks.*, el sobre del payload sin títulos de tareas, la verificación de X-BEARER y la consulta de detalles con tu propia credencial.

Beta

Plan está en beta. Todo lo que está bajo /plan en la aplicación web, los comandos del CLI y de la agent skill para proyectos, objetivos, tableros y tareas, y la API pública /v1/plan/ puede cambiar antes de la disponibilidad general. ¿Quieres probarlo con tu equipo? Escribe a [email protected].

Las consultas periódicas son adecuadas para una pantalla que alguien está mirando. Para un servidor que debe reaccionar a cada cambio (sincronizar con otra herramienta, avisar en un canal, actualizar un informe), suscríbete a los eventos de Plan y deja que Dailybot te llame.

1. Suscríbete desde los webhooks de tu organización

Los eventos de Plan se entregan por los mismos webhooks salientes que cualquier otro evento de Dailybot. No hay un endpoint de webhook aparte bajo /v1/plan/. Crea la suscripción en la aplicación web o con la API de Webhooks, elige los eventos tasks.* que necesitas y define un secreto para el encabezado X-BEARER. Consulta Webhooks y eventos para la configuración.

2. Los 25 eventos de Plan

Objeto Eventos
Tarea tasks.task.created · tasks.task.updated · tasks.task.state_changed · tasks.task.owner_changed · tasks.task.moved · tasks.task.comment_created · tasks.task.archived · tasks.task.participant_added · tasks.task.participant_removed
Tablero tasks.board.created · tasks.board.updated · tasks.board.archived · tasks.board.restored · tasks.board.member_added · tasks.board.member_removed
Proyecto tasks.project.created · tasks.project.updated · tasks.project.member_added · tasks.project.member_removed · tasks.project.archived · tasks.project.restored
Objetivo tasks.goal.created · tasks.goal.updated · tasks.goal.archived · tasks.goal.restored
  • No existe tasks.task.deleted: archivar equivale a eliminar, así que escucha tasks.task.archived.
  • Con el tiempo se agregan eventos nuevos. Ignora los eventos que no reconozcas en lugar de fallar.
  • Algunos cambios aparecen solo en el feed de actividad, no como webhooks (por ejemplo, un hito retirado, que se registra como project.milestone_deleted).

3. Lo que llega: identificadores, nunca títulos

Cada entrega es un POST JSON con el sobre estándar. Para Plan, body es el registro del evento:

{
  "event": "tasks.task.state_changed",
  "event_timestamp": "2026-09-25T10:14:02Z",
  "hook": { "id": "wh-1234-abcd", "name": "Tasks sync" },
  "body": {
    "event": "tasks.task.state_changed",
    "occurred_at": "2026-09-25T10:14:02.113954Z",
    "observed_at": "2026-09-25T10:14:02.113954Z",
    "organization_uuid": "00000000-0000-4000-8000-000000000101",
    "actor": { "kind": "user", "uuid": "00000000-0000-4000-8000-00000000000c" },
    "correlation_id": "00000000-0000-4000-8000-000000000102",
    "entity": { "type": "task", "uuid": "00000000-0000-4000-8000-000000000005", "key": "ENG-142" },
    "data": {
      "from_state_uuid": "00000000-0000-4000-8000-000000000003",
      "to_state_uuid": "00000000-0000-4000-8000-000000000004"
    }
  }
}

Ningún payload incluye títulos, descripciones, texto de comentarios ni nombres de etiquetas. Es a propósito: la URL de un webhook es el lugar menos confiable al que puede ir un evento. La key de la tarea es el único campo legible para una persona. Cuando necesites el contenido, consúltalo con una credencial propia, que se rechaza si no tiene permiso para verlo:

curl -sS "https://api.dailybot.com/v1/plan/tasks/ENG-142/" \
  -H "X-API-KEY: $DAILYBOT_API_KEY" | jq '{key, title, state: .state.name}'

4. Verifica cada entrega

Las entregas no van firmadas. En su lugar, cada solicitud trae un encabezado X-BEARER con el secreto que definiste en la suscripción. Rechaza cualquier otra cosa, compara en tiempo constante y acepta solo HTTPS:

import { timingSafeEqual } from 'node:crypto';

function isFromDailybot(req) {
  const received = Buffer.from(req.headers['x-bearer'] ?? '');
  const expected = Buffer.from(process.env.DAILYBOT_WEBHOOK_SECRET);
  return received.length === expected.length && timingSafeEqual(received, expected);
}

OAuth 2.0 también está disponible para autenticar webhooks; consulta Webhooks y eventos.

5. Procésalo bien

  • Responde rápido con un 2xx y haz el trabajo de forma asíncrona.
  • Haz que el procesamiento sea idempotente: usa como clave el registro del evento (entity.uuid, event, occurred_at) para que una entrega repetida o tu propio reintento no cause daño.
  • Ordena por occurred_at, no por la hora de llegada.
  • Vuelve a leer antes de actuar cuando la decisión depende del estado actual; el evento dice qué cambió y la API dice qué es cierto ahora.

Referencia