Vai al contenuto principale
Le automazioni sono le parti di un’app che funzionano autonomamente — secondo una pianificazione, o quando un servizio esterno invia un evento. Le dichiari su un componente process in kazzle.config.ts. Un componente può avere tutti i trigger di cui hai bisogno.

La struttura

{
  name: 'events',
  type: 'process',
  path: './components/events/index.ts',
  processMode: 'persistent', // o 'triggered'
  triggers: [
    { name: 'daily-digest', kind: 'schedule', schedule: '0 9 * * *', path: '/cron/daily-digest' },
    { name: 'stripe',       kind: 'webhook',                          path: '/webhook/stripe' },
  ],
}
Due cose stanno accadendo qui:
  • processMode sceglie il ciclo di vita — server long-running, o esecuzione una tantum per trigger.
  • triggers[] elenca gli eventi che devono attivare questo componente.
I due elementi sono indipendenti. Un server persistente può avere un cron. Un processo effimero può avere un webhook. Scegli il ciclo di vita che si adatta al carico di lavoro, poi allega tutti i trigger che vuoi.

processMode

ModalitàCosa viene eseguitoQuando usare
persistent (predefinito)Un server HTTP long-running. I trigger vengono POSTati al suo interno.Il componente già serve HTTP, o mantiene lo stato in memoria (code, websocket, cache).
triggeredLo script di entry viene generato per trigger ed esce.Job di background puri — pulizia notturna, singolo handler webhook Stripe, ecc. Nessun server inattivo.

Trigger

Ogni trigger ha un name (univoco all’interno del componente), un kind, e — a seconda della modalità — uno schedule e/o un path.
CampoQuando richiestoNote
namesempreUsato come segmento URL webhook e nei log. Kebab-case.
kindsempre'schedule' o 'webhook'.
schedulequando kind: 'schedule'Espressione cron a 5 campi. La risoluzione al minuto è il minimo.
pathquando processMode: 'persistent'Rotta HTTP sul tuo server dove il trigger arriva.

Modalità persistente — HTTP nel server

Quando un trigger si attiva per un componente persistente, Kazzle POSTa al tuo server al path dichiarato. La richiesta contiene:
HeaderCosa ti dice
Authorization: Bearer ${KAZZLE_TRIGGER_SECRET}Convalidalo. Rifiuta le chiamate che non corrispondono.
x-kazzle-trigger-nameIl name del trigger dal manifest.
x-kazzle-trigger-run-idID opaco per la correlazione dei log.
x-kazzle-triggered-bycron | webhook | manual.
Per i trigger webhook, il corpo della richiesta originale viene inoltrato come corpo POST. Per i trigger di pianificazione il corpo è vuoto.
// components/events/index.ts (modalità persistente)
const TRIGGER_SECRET = process.env.KAZZLE_TRIGGER_SECRET ?? '';

Bun.serve({
  port: Number(process.env.PORT),
  hostname: process.env.HOST,
  async fetch(req) {
    const url = new URL(req.url);

    if (req.method === 'POST' && url.pathname === '/cron/daily-digest') {
      if (req.headers.get('authorization') !== `Bearer ${TRIGGER_SECRET}`) {
        return new Response('Unauthorized', { status: 401 });
      }
      await sendDigest();
      return Response.json({ ok: true });
    }

    if (req.method === 'POST' && url.pathname === '/webhook/stripe') {
      if (req.headers.get('authorization') !== `Bearer ${TRIGGER_SECRET}`) {
        return new Response('Unauthorized', { status: 401 });
      }
      const event = await req.json();
      await handleStripe(event);
      return Response.json({ ok: true });
    }

    return new Response('not found', { status: 404 });
  },
});

Modalità triggered — una tantum per trigger

Quando un trigger si attiva per un componente triggered, Kazzle genera lo script di entry da zero e attende che esca. Non c’è path; lo script apprende quale trigger si è attivato dalle variabili d’ambiente.
Variabile d’ambienteValore
TRIGGER_NAMEIl name del trigger dal manifest.
TRIGGERED_BYcron | webhook | manual.
RUN_IDID opaco per la correlazione dei log.
WEBHOOK_PAYLOADCorpo JSON (solo trigger webhook).
// components/events/index.ts (modalità triggered)
const trigger = process.env.TRIGGER_NAME;
const runId = process.env.RUN_ID;

if (trigger === 'daily-digest') {
  await sendDigest();
} else if (trigger === 'stripe') {
  const event = JSON.parse(process.env.WEBHOOK_PAYLOAD ?? '{}');
  await handleStripe(event);
}

console.log(`run ${runId} done`);
I componenti triggered non hanno macchine inattive in produzione — si avviano per chiamata e si spengono all’uscita.

URL dei webhook

POST https://api.kazzle.app/webhooks/{spaceId}/{appId}/{componentName}/{triggerName}
Il segmento triggerName deve corrispondere a una voce kind: 'webhook' in triggers[] di quel componente. I nomi di trigger sconosciuti restituiscono 404.

Risoluzione della pianificazione

Le espressioni cron sono a 5 campi (minuto, ora, giorno del mese, mese, giorno della settimana) e la risoluzione al minuto è il minimo. Le pianificazioni sub-minuto vengono rifiutate al momento della convalida del manifest.

Come vengono registrate le esecuzioni

Ogni attivazione di trigger scrive una riga process_runs con trigger_name, triggered_by, run_id, e lo stato di uscita dell’esecuzione. Puoi interrogarle dal tuo codice o ispezionarle nella vista esecuzioni dell’app.

Esaurimento dei crediti

Un’esecuzione non riuscita viene registrata e registrata, ma la pianificazione continua al suo ritmo normale — un’esecuzione instabile non disabilita mai il trigger. L’unica cosa che ferma un’esecuzione è il credito: ogni attivazione di trigger viene controllata rispetto al saldo dello spazio, e mentre lo spazio è senza crediti (o non ha alcuna fatturazione configurata) le esecuzioni vengono saltate con un 402. Questo è auto-recuperabile — la pianificazione rimane armata e l’attivazione successiva dopo il rifornimento viene eseguita normalmente, senza ripresa manuale.

Aggiunta di automazioni in seguito

Un’app semplice può iniziare senza trigger e acquisirli in seguito — aggiungi un riepilogo giornaliero, connetti Stripe, esegui la pulizia. Il ciclo di vita del componente (processMode) e i trigger (triggers[]) sono indipendenti, quindi puoi modificarli senza riscrivere il resto dell’app.