@hemia/workflow-node-wait-for-webhook
v0.0.3
Published
Nodo de workflow de Hemia para esperar un webhook.
Downloads
6
Readme
@hemia/workflow-node-wait-for-webhook
Nodo para pausar un workflow hasta recibir un webhook externo. Diseñado para integrarse con @hemia/workflow-engine y permitir flujos de aprobación, formularios, pasos manuales, etc.
Instalación
npm install @hemia/workflow-node-wait-for-webhookRequiere Node.js >= 18.
Qué exporta
waitForWebhookNode: instancia lista para registrar en el engine.WaitForWebhookNode: clase por si prefieres instanciar manualmente.
Nota: Asegúrate de que el paquete exporte estos símbolos desde su
index.ts.
Uso con hemia-workflow-engine
1) Registrar el nodo y ejecutar el workflow
import { WorkflowEngine, NodeRegistry } from "@hemia/workflow-engine";
import { waitForWebhookNode } from "@hemia/workflow-node-wait-for-webhook";
import type { Workflow } from "@hemia/workflow-core";
// Persistencia (implementación propia)
const saveContext = async (_ctx: any, _status?: string) => {};
const loadContext = async (_executionId: string) => undefined;
const registry = new NodeRegistry();
registry.register("wait-for-webhook", waitForWebhookNode);
const workflow: Workflow = {
id: "order-approval",
name: "Aprobación de pedido",
steps: [
// ... pasos previos
{
id: "pause-for-approval",
type: "wait-for-webhook",
params: {
stepId: "pause-for-approval",
reason: "approval",
metadata: { entity: "order", id: "123" }
}
},
// ... pasos siguientes que se ejecutarán tras reanudar
]
};
// La ejecución se identifica por executionId (guárdalo en tu BD)
const engine = new WorkflowEngine(
workflow,
"exec-001",
registry,
saveContext,
loadContext
);
await engine.run(); // Se pausará con estado WAITING en el paso wait-for-webhook2) Reanudar tras recibir el webhook
Ejemplo con Express:
import express from "express";
import { WorkflowEngine, NodeRegistry } from "@hemia/workflow-engine";
import { waitForWebhookNode } from "@hemia/workflow-node-wait-for-webhook";
const app = express();
app.use(express.json());
const registry = new NodeRegistry();
registry.register("wait-for-webhook", waitForWebhookNode);
app.post("/webhooks/order-approved", async (req, res) => {
const { executionId, stepId, payload } = req.body; // envía estos datos desde el emisor del webhook
// Tus funciones deben cargar/guardar el contexto por executionId
const saveContext = async (_ctx: any, _status?: string) => {};
const loadContext = async (_executionId: string) => ({ /* contexto previo */ payload });
const engine = new WorkflowEngine(
/* mismo workflow */,
executionId,
registry,
saveContext,
loadContext
);
await engine.resume(stepId); // Continúa el flujo a partir del paso indicado
res.sendStatus(202);
});
app.listen(3000);Configuración del nodo
Parámetros (params) aceptados por wait-for-webhook:
stepId(string, requerido): identificador del paso donde se espera.reason("form" | "approval" | "manual" | "external", opcional): motivo de la espera.timeout(number | string, opcional): tiempo máximo de espera. Preferido en milisegundos (number). Si es string, se admitems,s,m,h(p.ej."30s","1h"). Si no se define, se usaconfig.timeouts.approval(si está disponible en el contexto).formId(string, opcional): id de formulario asociado.metadata(object, opcional): datos adicionales relevantes al negocio.
Esquema simplificado:
{
"type": "object",
"required": ["stepId"],
"properties": {
"stepId": { "type": "string" },
"reason": { "type": "string", "enum": ["form", "approval", "manual", "external"] },
"timeout": { "type": ["number", "string"] },
"formId": { "type": "string" },
"metadata": { "type": "object" }
}
}Comportamiento de ejecución
- El nodo devuelve
success: falseconerror.code = "WAITING"y elWorkflowEnginelo interpreta como pausa. - Timeout efectivo: si
params.timeoutno está presente, se intenta resolver desdevariables.config.timeouts.approval. Internamente se calculatimeoutMs(milisegundos) si hay valor. - Estados típicos que guardará el engine mediante
saveContext:WAITING: pausado esperando webhookRUNNING: en ejecución al reanudarFAILED: errorCOMPLETED: finalizado
Ejemplo de resultado del nodo:
{
"success": false,
"error": {
"code": "WAITING",
"message": "Esperando webhook para paso 'pause-for-approval'",
"details": {
"stepId": "pause-for-approval",
"reason": "approval",
"formId": null,
"metadata": { "entity": "order", "id": "123" },
"timeout": "72h",
"timeoutMs": 259200000
}
}
}Scripts útiles
npm run build– compila adist/npm test– ejecuta tests
Licencia
MIT
