跳轉到主要內容
自動化是應用程式中自行執行的部分 — 按照排程執行,或當外部服務傳送事件時執行。 您在 kazzle.config.ts 的 process 元件上宣告它們。一個元件可以包含任意數量的觸發器。

結構

{
  name: 'events',
  type: 'process',
  path: './components/events/index.ts',
  processMode: 'persistent', // or 'triggered'
  triggers: [
    { name: 'daily-digest', kind: 'schedule', schedule: '0 9 * * *', path: '/cron/daily-digest' },
    { name: 'stripe',       kind: 'webhook',                          path: '/webhook/stripe' },
  ],
}
這裡發生了兩件事:
  • processMode 選擇生命週期 — 長期執行的伺服器,或每個觸發器執行一次。
  • triggers[] 列出應該觸發此元件的事件
這兩個部分是獨立的。持久伺服器可以有 cron。臨時程序可以有 webhook。選擇適合工作負載的生命週期,然後附加任意數量的觸發器。

processMode

模式執行內容何時使用
persistent(預設)長期執行的 HTTP 伺服器。觸發器被 POST 到其中。元件已經提供 HTTP 服務,或在記憶體中保持狀態(佇列、websocket、快取)。
triggered每個觸發器都會產生入口指令碼並退出。純背景工作 — 夜間清理、單一 Stripe webhook 處理器等。無閒置伺服器。

觸發器

每個觸發器都有一個 name(在元件內唯一)、一個 kind,以及 — 根據模式 — 一個 schedule 和/或 path
欄位何時必需備註
name總是用作 webhook URL 段和日誌中。使用 kebab-case。
kind總是'schedule''webhook'
schedulekind: 'schedule'5 欄位 cron 表達式。分鐘解析度是最低限度。
pathprocessMode: 'persistent'觸發器到達的伺服器上的 HTTP 路由。

持久模式 — HTTP 進入伺服器

當持久元件的觸發器觸發時,Kazzle 會 POST 到您在宣告的 path 上的伺服器。請求包含:
標頭它告訴您什麼
Authorization: Bearer ${KAZZLE_TRIGGER_SECRET}驗證此項。拒絕不匹配的呼叫。
x-kazzle-trigger-name清單中觸發器的 name
x-kazzle-trigger-run-id用於日誌關聯的不透明 ID。
x-kazzle-triggered-bycron | webhook | manual
對於 webhook 觸發器,原始請求本文會作為 POST 本文轉發。對於排程觸發器,本文為空。
// 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 });
  },
});

觸發模式 — 每個觸發器執行一次

triggered 元件的觸發器觸發時,Kazzle 會重新產生入口指令碼並等待它退出。沒有 path;指令碼從環境變數中了解哪個觸發器觸發。
環境變數
TRIGGER_NAME清單中觸發器的 name
TRIGGERED_BYcron | webhook | manual
RUN_ID用於日誌關聯的不透明 ID。
WEBHOOK_PAYLOADJSON 本文(僅限 webhook 觸發器)。
// 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`);
觸發元件在生產環境中沒有閒置機器 — 它們按呼叫產生並在退出時關閉。

Webhook URL

POST https://api.kazzle.app/webhooks/{spaceId}/{appId}/{componentName}/{triggerName}
triggerName 段必須與該元件 triggers[] 中的 kind: 'webhook' 項目相符。未知的觸發器名稱會傳回 404。

排程解析度

Cron 表達式是 5 欄位(分鐘、小時、月份日期、月份、週份日期),分鐘解析度是最低限度。子分鐘排程在清單驗證時被拒絕。

如何記錄執行

每個觸發器觸發都會寫入一個 process_runs 列,包含 trigger_nametriggered_byrun_id 和執行的退出狀態。您可以從自己的程式碼查詢這些,或在應用程式的執行檢視中檢查它們。

信用額度用盡

失敗的執行會被記錄和記載,但排程會按其正常節奏繼續執行 — 不穩定的執行永遠不會停用觸發器。停止執行的唯一因素是信用額度:每個觸發器觸發都會根據空間的餘額進行檢查,當空間信用額度用盡(或未設定帳單)時,執行會以 402 跳過。這是自我恢復的 — 排程保持啟用,補充後的下一次觸發會正常執行,無需手動恢復。

稍後新增自動化

簡單的應用程式可以不使用觸發器開始,稍後再新增它們 — 新增每日摘要、連接 Stripe、執行清理。元件的生命週期(processMode)和觸發器(triggers[])是獨立的,因此您可以在不重寫應用程式其餘部分的情況下變更它們。