> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kazzle.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ऑटोमेशन

> Kazzle ऐप के अंदर से जॉब शेड्यूल करें और वेबहुक का जवाब दें।

ऑटोमेशन ऐप के वे हिस्से हैं जो अपने आप चलते हैं — शेड्यूल के अनुसार, या जब कोई बाहरी सेवा कोई इवेंट भेजती है।

आप उन्हें `kazzle.config.ts` में एक process कंपोनेंट पर घोषित करते हैं। एक कंपोनेंट जितने ट्रिगर चाहें उतने रख सकता है।

## आकार

```ts theme={"theme":"material-theme-darker"}
{
  name: 'events',
  type: 'process',
  path: './components/events/index.ts',
  processMode: 'persistent', // या 'triggered'
  triggers: [
    { name: 'daily-digest', kind: 'schedule', schedule: '0 9 * * *', path: '/cron/daily-digest' },
    { name: 'stripe',       kind: 'webhook',                          path: '/webhook/stripe' },
  ],
}
```

यहाँ दो चीजें हो रही हैं:

* `processMode` **लाइफसाइकल** चुनता है — लंबे समय तक चलने वाला सर्वर, या प्रति ट्रिगर एक बार चलना।
* `triggers[]` **इवेंट** की सूची देता है जो इस कंपोनेंट को फायर करने चाहिए।

ये दोनों अलग-अलग हैं। एक persistent सर्वर के पास cron हो सकता है। एक ephemeral प्रक्रिया के पास webhook हो सकता है। वह लाइफसाइकल चुनें जो आपके काम के लिए सही हो, फिर जितने ट्रिगर चाहें जोड़ें।

## `processMode`

| मोड                     | क्या चलता है                                                         | कब उपयोग करें                                                                                 |
| ----------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `persistent` (डिफ़ॉल्ट) | एक लंबे समय तक चलने वाला HTTP सर्वर। ट्रिगर इसमें POST किए जाते हैं। | कंपोनेंट पहले से HTTP सर्व करता है, या मेमोरी में स्टेट रखता है (कतारें, websockets, कैश)।    |
| `triggered`             | एंट्री स्क्रिप्ट प्रति ट्रिगर स्पॉन होती है और बंद हो जाती है।       | शुद्ध बैकग्राउंड जॉब — रात की सफाई, एकल Stripe webhook हैंडलर, आदि। कोई निष्क्रिय सर्वर नहीं। |

## ट्रिगर

प्रत्येक ट्रिगर के पास एक `name` (कंपोनेंट के भीतर अद्वितीय), एक `kind`, और — मोड के आधार पर — एक `schedule` और/या `path` होता है।

| फील्ड      | कब आवश्यक है                   | नोट्स                                                         |
| ---------- | ------------------------------ | ------------------------------------------------------------- |
| `name`     | हमेशा                          | वेबहुक URL सेगमेंट और लॉग में उपयोग किया जाता है। Kebab-case। |
| `kind`     | हमेशा                          | `'schedule'` या `'webhook'`।                                  |
| `schedule` | जब `kind: 'schedule'`          | 5-फील्ड cron एक्सप्रेशन। मिनट रेजोल्यूशन न्यूनतम है।          |
| `path`     | जब `processMode: 'persistent'` | आपके सर्वर पर HTTP रूट जहाँ ट्रिगर आता है।                    |

## Persistent मोड — सर्वर में HTTP

जब एक persistent कंपोनेंट के लिए ट्रिगर फायर होता है, Kazzle घोषित `path` पर आपके सर्वर को POST करता है। अनुरोध में ये हेडर होते हैं:

| हेडर                                             | यह क्या बताता है                                      |
| ------------------------------------------------ | ----------------------------------------------------- |
| `Authorization: Bearer ${KAZZLE_TRIGGER_SECRET}` | इसे वैलिडेट करें। जो मेल न खाएं उन्हें अस्वीकार करें। |
| `x-kazzle-trigger-name`                          | मैनिफेस्ट से ट्रिगर का `name`।                        |
| `x-kazzle-trigger-run-id`                        | लॉग सहसंबंध के लिए अपारदर्शी ID।                      |
| `x-kazzle-triggered-by`                          | `cron` \| `webhook` \| `manual`।                      |

वेबहुक ट्रिगर के लिए, मूल अनुरोध बॉडी POST बॉडी के रूप में फॉरवर्ड की जाती है। शेड्यूल ट्रिगर के लिए बॉडी खाली होती है।

```ts theme={"theme":"material-theme-darker"}
// 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 मोड — प्रति ट्रिगर एक बार

जब एक `triggered` कंपोनेंट के लिए ट्रिगर फायर होता है, Kazzle एंट्री स्क्रिप्ट को नई शुरुआत से स्पॉन करता है और इसके बंद होने का इंतजार करता है। कोई `path` नहीं होता; स्क्रिप्ट env vars से सीखती है कि कौन सा ट्रिगर फायर हुआ।

| Env var           | मान                              |
| ----------------- | -------------------------------- |
| `TRIGGER_NAME`    | मैनिफेस्ट से ट्रिगर का `name`।   |
| `TRIGGERED_BY`    | `cron` \| `webhook` \| `manual`। |
| `RUN_ID`          | लॉग सहसंबंध के लिए अपारदर्शी ID। |
| `WEBHOOK_PAYLOAD` | JSON बॉडी (केवल वेबहुक ट्रिगर)।  |

```ts theme={"theme":"material-theme-darker"}
// 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`);
```

Triggered कंपोनेंट के प्रोडक्शन में कोई निष्क्रिय मशीनें नहीं होती — वे प्रति कॉल स्पिन अप होती हैं और बंद होने पर शट डाउन होती हैं।

## वेबहुक URLs

```text theme={"theme":"material-theme-darker"}
POST https://api.kazzle.app/webhooks/{spaceId}/{appId}/{componentName}/{triggerName}
```

`triggerName` सेगमेंट उस कंपोनेंट के `triggers[]` में एक `kind: 'webhook'` एंट्री से मेल खाना चाहिए। अज्ञात ट्रिगर नाम 404 रिटर्न करते हैं।

## शेड्यूल रेजोल्यूशन

Cron एक्सप्रेशन 5-फील्ड (मिनट, घंटा, दिन-का-महीना, महीना, दिन-का-सप्ताह) होते हैं और मिनट रेजोल्यूशन न्यूनतम है। सब-मिनट शेड्यूल मैनिफेस्ट वैलिडेशन समय पर अस्वीकार किए जाते हैं।

## रन कैसे रिकॉर्ड किए जाते हैं

प्रत्येक ट्रिगर फायर एक `process_runs` पंक्ति लिखता है जिसमें `trigger_name`, `triggered_by`, `run_id`, और रन की exit स्थिति होती है। आप इन्हें अपने कोड से क्वेरी कर सकते हैं या ऐप के runs व्यू में देख सकते हैं।

## क्रेडिट खत्म हो जाना

एक विफल रन रिकॉर्ड और लॉग किया जाता है, लेकिन शेड्यूल अपने सामान्य गति पर चलता रहता है — एक अस्थिर रन कभी ट्रिगर को अक्षम नहीं करता। एक चीज जो रन को रोकती है वह है क्रेडिट: हर ट्रिगर फायर को स्पेस के बैलेंस के विरुद्ध चेक किया जाता है, और जब तक स्पेस क्रेडिट से बाहर है (या बिल
