Chuyển đến nội dung chính
Tự động hóa là những phần của ứng dụng chạy tự động — theo lịch trình hoặc khi một dịch vụ bên ngoài gửi một sự kiện. Bạn khai báo chúng trên một thành phần process trong kazzle.config.ts. Một thành phần có thể có bao nhiêu trigger tùy ý.

Cấu trúc

{
  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' },
  ],
}
Hai điều đang xảy ra ở đây:
  • processMode chọn vòng đời — máy chủ chạy lâu dài hoặc chạy một lần cho mỗi trigger.
  • triggers[] liệt kê các sự kiện sẽ kích hoạt thành phần này.
Hai phần này độc lập với nhau. Một máy chủ persistent có thể có một cron. Một quy trình ephemeral có thể có một webhook. Chọn vòng đời phù hợp với khối lượng công việc, sau đó gắn bao nhiêu trigger tùy ý.

processMode

Chế độChạy gìKhi nào sử dụng
persistent (mặc định)Một máy chủ HTTP chạy lâu dài. Các trigger được POST vào nó.Thành phần đã phục vụ HTTP hoặc giữ trạng thái trong bộ nhớ (hàng đợi, websockets, bộ nhớ cache).
triggeredTập lệnh entry được tạo cho mỗi trigger và thoát.Các công việc nền thuần túy — dọn dẹp hàng đêm, xử lý webhook Stripe đơn lẻ, v.v. Không có máy chủ nhàn rỗi.

Triggers

Mỗi trigger có một name (duy nhất trong thành phần), một kind, và — tùy thuộc vào chế độ — một schedule và/hoặc path.
TrườngKhi bắt buộcGhi chú
nameluôn luônĐược sử dụng làm phân đoạn URL webhook và trong nhật ký. Kebab-case.
kindluôn luôn'schedule' hoặc 'webhook'.
schedulekhi kind: 'schedule'Biểu thức cron 5 trường. Độ phân giải phút là mức tối thiểu.
pathkhi processMode: 'persistent'Tuyến HTTP trên máy chủ của bạn nơi trigger đến.

Chế độ persistent — HTTP vào máy chủ

Khi một trigger kích hoạt cho một thành phần persistent, Kazzle POST đến máy chủ của bạn tại path được khai báo. Yêu cầu mang theo:
HeaderNó cho bạn biết gì
Authorization: Bearer ${KAZZLE_TRIGGER_SECRET}Xác thực điều này. Từ chối các cuộc gọi không khớp.
x-kazzle-trigger-namename của trigger từ manifest.
x-kazzle-trigger-run-idID không rõ ràng để tương quan nhật ký.
x-kazzle-triggered-bycron | webhook | manual.
Đối với webhook triggers, phần thân yêu cầu gốc được chuyển tiếp dưới dạng phần thân POST. Đối với schedule triggers, phần thân trống.
// 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 });
  },
});

Chế độ triggered — một lần cho mỗi trigger

Khi một trigger kích hoạt cho một thành phần triggered, Kazzle tạo tập lệnh entry mới và chờ nó thoát. Không có path; tập lệnh tìm hiểu trigger nào kích hoạt từ các biến môi trường.
Biến môi trườngGiá trị
TRIGGER_NAMEname của trigger từ manifest.
TRIGGERED_BYcron | webhook | manual.
RUN_IDID không rõ ràng để tương quan nhật ký.
WEBHOOK_PAYLOADPhần thân JSON (chỉ webhook triggers).
// 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`);
Các thành phần triggered không có máy nhàn rỗi trên production — chúng khởi động cho mỗi cuộc gọi và tắt khi thoát.

URL Webhook

POST https://api.kazzle.app/webhooks/{spaceId}/{appId}/{componentName}/{triggerName}
Phân đoạn triggerName phải khớp với một mục kind: 'webhook' trong triggers[] của thành phần đó. Các tên trigger không xác định trả về 404.

Độ phân giải lịch trình

Biểu thức cron là 5 trường (phút, giờ, ngày trong tháng, tháng, ngày trong tuần) và độ phân giải phút là mức tối thiểu. Các lịch trình dưới phút bị từ chối tại thời điểm xác thực manifest.

Cách ghi lại các lần chạy

Mỗi lần kích hoạt trigger ghi một hàng process_runs với trigger_name, triggered_by, run_id và trạng thái thoát của lần chạy. Bạn có thể truy vấn những điều này từ mã của riêng bạn hoặc kiểm tra chúng trong chế độ xem chạy của ứng dụng.

Hết tín dụng

Một lần chạy không thành công được ghi lại và ghi nhật ký, nhưng lịch trình tiếp tục chạy theo nhịp độ bình thường — một lần chạy không ổn định không bao giờ vô hiệu hóa trigger. Điều duy nhất dừng một lần chạy là tín dụng: mỗi lần kích hoạt trigger được kiểm tra dựa trên số dư của không gian, và trong khi không gian hết tín dụng (hoặc không có thiết lập thanh toán) các lần chạy bị bỏ qua với 402. Điều này tự khôi phục — lịch trình vẫn được vũ trang và lần kích hoạt tiếp theo sau khi bạn nạp tiền chạy bình thường, không cần tiếp tục thủ công.

Thêm tự động hóa sau

Một ứng dụng đơn giản có thể bắt đầu mà không có trigger và có được chúng sau — thêm bản tóm tắt hàng ngày, kết nối Stripe, chạy dọn dẹp. Vòng đời của thành phần (processMode) và triggers (triggers[]) độc lập, vì vậy bạn có thể thay đổi chúng mà không cần viết lại phần còn lại của ứng dụng.