Langsung ke konten utama
Otomasi adalah bagian dari aplikasi yang berjalan sendiri — sesuai jadwal, atau ketika layanan eksternal mengirim acara. Anda mendeklarasikannya pada komponen process di kazzle.config.ts. Satu komponen dapat memiliki sebanyak trigger yang Anda butuhkan.

Bentuknya

{
  name: 'events',
  type: 'process',
  path: './components/events/index.ts',
  processMode: 'persistent', // atau 'triggered'
  triggers: [
    { name: 'daily-digest', kind: 'schedule', schedule: '0 9 * * *', path: '/cron/daily-digest' },
    { name: 'stripe',       kind: 'webhook',                          path: '/webhook/stripe' },
  ],
}
Dua hal terjadi di sini:
  • processMode memilih siklus hidup — server yang berjalan lama, atau satu kali berjalan per trigger.
  • triggers[] mencantumkan acara yang harus memicu komponen ini.
Kedua bagian tersebut independen. Server yang persisten dapat memiliki cron. Proses yang efemeral dapat memiliki webhook. Pilih siklus hidup yang sesuai dengan beban kerja, kemudian lampirkan sebanyak trigger yang Anda inginkan.

processMode

ModeYang berjalanKapan digunakan
persistent (default)Server HTTP yang berjalan lama. Trigger diPOST ke dalamnya.Komponen sudah melayani HTTP, atau menyimpan status dalam memori (antrian, websocket, cache).
triggeredSkrip entri dijalankan per trigger dan keluar.Pekerjaan latar belakang murni — pembersihan malam hari, penanganan webhook Stripe tunggal, dll. Tidak ada server idle.

Trigger

Setiap trigger memiliki name (unik dalam komponen), kind, dan — tergantung mode — schedule dan/atau path.
FieldKapan diperlukanCatatan
nameselaluDigunakan sebagai segmen URL webhook dan dalam log. Kebab-case.
kindselalu'schedule' atau 'webhook'.
scheduleketika kind: 'schedule'Ekspresi cron 5-field. Resolusi menit adalah batas bawah.
pathketika processMode: 'persistent'Rute HTTP pada server Anda tempat trigger mendarat.

Mode persisten — HTTP ke server

Ketika trigger diaktifkan untuk komponen persisten, Kazzle memPOST ke server Anda di path yang dideklarasikan. Permintaan membawa:
HeaderApa yang diberitahukannya
Authorization: Bearer ${KAZZLE_TRIGGER_SECRET}Validasi ini. Tolak panggilan yang tidak cocok.
x-kazzle-trigger-namename trigger dari manifest.
x-kazzle-trigger-run-idID opak untuk korelasi log.
x-kazzle-triggered-bycron | webhook | manual.
Untuk trigger webhook, badan permintaan asli diteruskan sebagai badan POST. Untuk trigger jadwal, badan kosong.
// components/events/index.ts (persistent mode)
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 });
  },
});

Mode triggered — satu kali per trigger

Ketika trigger diaktifkan untuk komponen triggered, Kazzle menjalankan skrip entri segar dan menunggu hingga keluar. Tidak ada path; skrip mempelajari trigger mana yang diaktifkan dari variabel env.
Variabel EnvNilai
TRIGGER_NAMEname trigger dari manifest.
TRIGGERED_BYcron | webhook | manual.
RUN_IDID opak untuk korelasi log.
WEBHOOK_PAYLOADBadan JSON (webhook trigger saja).
// components/events/index.ts (triggered mode)
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`);
Komponen triggered tidak memiliki mesin idle di produksi — mereka berjalan per panggilan dan mati saat keluar.

URL Webhook

POST https://api.kazzle.app/webhooks/{spaceId}/{appId}/{componentName}/{triggerName}
Segmen triggerName harus cocok dengan entri kind: 'webhook' di triggers[] komponen tersebut. Nama trigger yang tidak dikenal mengembalikan 404.

Resolusi jadwal

Ekspresi cron adalah 5-field (menit, jam, hari-bulan, bulan, hari-minggu) dan resolusi menit adalah batas bawah. Jadwal sub-menit ditolak pada waktu validasi manifest.

Bagaimana run dicatat

Setiap pemicu fire menulis baris process_runs dengan trigger_name, triggered_by, run_id, dan status keluar run. Anda dapat menanyakan ini dari kode Anda sendiri atau memeriksa di tampilan run aplikasi.

Kehabisan kredit

Run yang gagal dicatat dan dicatat, tetapi jadwal terus berjalan sesuai ritme normalnya — run yang tidak stabil tidak pernah menonaktifkan trigger. Satu-satunya hal yang menghentikan run adalah kredit: setiap pemicu fire diperiksa terhadap saldo space, dan sementara space kehabisan kredit (atau tidak memiliki penagihan yang disiapkan) run dilewati dengan 402. Ini self-recovering — jadwal tetap aktif dan fire berikutnya setelah Anda mengisi ulang berjalan normal, tanpa resume manual.

Menambahkan otomasi nanti

Aplikasi sederhana dapat dimulai tanpa trigger dan mendapatkannya nanti — tambahkan ringkasan harian, hubungkan Stripe, jalankan pembersihan. Siklus hidup komponen (processMode) dan trigger (triggers[]) independen, jadi Anda dapat mengubahnya tanpa menulis ulang sisa aplikasi.