mcpField
I
inngest

inngest

github.com/sickn33開発48.7k1.2k 回インストール今日更新
リポジトリ

inngest について

inngest は、Inngest を使ったサーバーレスのバックグラウンドジョブやイベント駆動ワークフローの構築を支援するスキルです。永続化されたステップ、リトライ、スケジュール、並行実行を扱います。

主な機能

  1. 01イベント駆動の関数
  2. 02永続化された複数ステップ実行
  3. 03リトライと並行実行制御
  4. 04スケジュール実行とWebhookワークフロー
  5. 05イベントのファンアウトパターン

活用シーン

  1. 01遅延を伴うオンボーディングメールの送信
  2. 02複数サービスにまたがる注文処理
  3. 03Webhookイベントの冪等処理
  4. 04長時間のAI文書処理パイプライン

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill inngest

インストール後、Claude Code で/inngestを入力して読み込まれたか確認します。

詳細

Inngest 統合

サーバーレス優先のバックグラウンドジョブ、イベント駆動型ワークフロー、キューやワーカーを管理せずに実現する耐久性のある実行に精通した Inngest エキスパートです。

これらはバージョン固定された SDK 向けのソーススケッチであり、デプロイ可能な完全なアプリケーションではありません。レビュー済みのデータベース/メール/決済アダプターを用意し、インストール済みの SDK に対してコンパイルしてください。イベントと Webhook ペイロードは、サーバー側で検証と認可を行う必要があります。Webhook イベントをキューに登録する前に、プロバイダーの署名を検証してください。秘密情報や不要な個人データを、耐久性のあるステップ出力に含めないでください。これらはリモートに保持される場合があります。

原則

  • イベントが基本要素です。すべてはキューではなくイベントを起点にします
  • ステップはチェックポイントです。各ステップの結果は耐久的に保存されます
  • スリープはその場しのぎではありません。Inngest のスリープは実際のスリープであり、スレッドをブロックしません
  • リトライは自動で行われますが、ポリシーは制御できます
  • 関数は単なる HTTP ハンドラーです。HTTP を提供する場所ならどこにでもデプロイできます
  • 同時実行は最優先事項です。下流サービスを保護してください
  • ワークフローの重複排除によって、外部の副作用が厳密に一度だけ実行されるわけではありません。プロバイダーの冪等性キーを使用し、不確実な結果を照合してください
  • ファンアウトは組み込み機能です。1 つのイベントで複数の関数を起動できます

機能

  • inngest-functions
  • event-driven-workflows
  • step-functions
  • serverless-background-jobs
  • durable-sleep
  • fan-out-patterns
  • concurrency-control
  • scheduled-functions

対象範囲

  • redis-queues -> bullmq-specialist
  • serverless-queues -> upstash-qstash
  • workflow-orchestration -> temporal-craftsman
  • message-streaming -> event-architect
  • infrastructure -> infra-architect

ツール

コア
  • inngest
  • inngest-cli
フレームワーク
  • nextjs
  • express
  • hono
  • remix
  • sveltekit
デプロイ
  • vercel
  • cloudflare-workers
  • netlify
  • railway
  • fly-io

#メッセージ送信、課金、フルフィルメント、デプロイ、リモートインデックス作成などの副作用には、ユーザーのタスク範囲に含まれている必要があります。開発では合成レコードを使用し、レビュー中にこれらの例を実行しないでください。

パターン

  • step-functions
  • event-fan-out
  • scheduled-cron
  • webhook-handling

パターン

基本的な関数の設定

Next.js で型付きイベントを使用する Inngest 関数

使用する場面:任意の Next.js プロジェクトで Inngest を使い始めるとき

// lib/inngest/client.ts import { Inngest, EventSchemas } from 'inngest';

export const inngest = new Inngest({ id: 'my-app', schemas: new EventSchemas().fromRecord(), });

// イベントを型付きで定義する type Events = { 'user/signed.up': { data: { userId: string; email: string } }; 'order/placed': { data: { orderId: string; total: number } }; };

// lib/inngest/functions.ts import { inngest } from './client';

export const sendWelcomeEmail = inngest.createFunction( { id: 'send-welcome-email' }, { event: 'user/signed.up' }, async ({ event, step }) => { // ステップ 1:ユーザーの詳細を取得する const user = await step.run('get-user', async () => { return await db.users.findUnique({ where: { id: event.data.userId } }); });

// ステップ 2:ウェルカムメールを送信する
await step.run('send-email', async () => {
  await resend.emails.send({
    to: user.email,
    subject: 'Welcome!',
    template: 'welcome',
  });
});

// ステップ 3:24 時間待ってから、ヒントを送信する
await step.sleep('wait-for-tips', '24h');

await step.run('send-tips', async () => {
  await resend.emails.send({
    to: user.email,
    subject: 'Getting Started Tips',
    template: 'tips',
  });
});

} );

// app/api/inngest/route.ts (Next.js App Router) import { serve } from 'inngest/next'; import { inngest } from '@/lib/inngest/client'; import { sendWelcomeEmail } from '@/lib/inngest/functions';

export const { GET, POST, PUT } = serve({ client: inngest, functions: [sendWelcomeEmail], });

マルチステップワークフロー

並列ステップとエラー処理を含む複雑なワークフロー

使用する場面:複数のサービスや長い待ち時間を伴う処理

export const processOrder = inngest.createFunction( { id: 'process-order', retries: 3, concurrency: { limit: 10 }, // 同時に処理する注文の最大数は10件 }, { event: 'order/placed' }, async ({ event, step }) => { const { orderId } = event.data;

// 並列ステップ — どちらも同時に実行されます
const [inventory, payment] = await Promise.all([
  step.run('check-inventory', () => checkInventory(orderId)),
  step.run('validate-payment', () => validatePayment(orderId)),
]);

if (!inventory.available) {
  // 直接呼び出す代わりにイベントを送信します(ファンアウトパターン)
  await step.sendEvent('notify-backorder', {
    name: 'order/backordered',
    data: { orderId, items: inventory.missing },
  });
  return { status: 'backordered' };
}

// サーバー側の注文から、正確な金額/通貨と顧客情報を取得します。
// 信頼できないイベントから受け取った金額だけを使って、決済してはいけません。
const order = await step.run('load-order', () => loadAuthorizedOrder(orderId));

// 決済を処理します
const charge = await step.run('charge-payment', async () => {
  return await stripe.charges.create({
    amount: order.totalMinorUnits,
    currency: order.currency,
    customer: payment.customerId,
  }, { idempotencyKey: `order:${orderId}:charge:v1` });
});

// 注文を発送します
await step.run('ship-order', () => fulfillment.ship(orderId));

return { status: 'completed', chargeId: charge.id };

} );

スケジュール/Cron 関数

スケジュールに従って実行される関数

使用する場面:日次レポートやクリーンアップジョブなどの定期タスク

export const dailyDigest = inngest.createFunction( { id: 'daily-digest' }, { cron: '0 9 * * *' }, // 毎日午前9時(UTC) async ({ step }) => { // ダイジェストを希望するすべてのユーザーを取得します const users = await step.run('get-users', async () => { return await db.users.findMany({ where: { digestEnabled: true }, }); });

// 各ユーザーに送信します(子イベントを作成します)
await step.sendEvent(
  'send-digests',
  users.map(user => ({
    name: 'digest/send',
    data: { userId: user.id },
  }))
);

return { sent: users.length };

} );

// 個別のダイジェスト送信は別の関数で処理します export const sendDigest = inngest.createFunction( { id: 'send-digest', concurrency: { limit: 50 } }, { event: 'digest/send' }, async ({ event, step }) => { // ... 個別のダイジェストを送信します } );

冪等性を備えた Webhook ハンドラー

重複を排除して Webhook を安全に処理します

使用する場面:Stripe、GitHub などの Webhook を処理する場合

export const handleStripeWebhook = inngest.createFunction( { id: 'stripe-webhook', // Stripe イベント ID で重複を排除します idempotency: 'event.data.stripeEventId', }, { event: 'stripe/webhook.received' }, async ({ event, step }) => { const { type, data } = event.data;

switch (type) {
  case 'checkout.session.completed':
    await step.run('fulfill-order', async () => {
      await fulfillOrder(data.session.id);
    });
    break;

  case 'customer.subscription.deleted':
    await step.run('cancel-subscription', async () => {
      await cancelSubscription(data.subscription.id);
    });
    break;
}

} );

長時間処理を伴う AI パイプライン

チャンク単位で処理する複数ステップの AI 処理

使用する場面:完了までに数分かかる可能性がある AI ワークフロー

export const processDocument = inngest.createFunction( { id: 'process-document', retries: 2, concurrency: { limit: 5 }, // API の使用を制限 }, { event: 'document/uploaded' }, async ({ event, step }) => { // ステップ 1:テキストを抽出(時間がかかる場合があります) const text = await step.run('extract-text', async () => { return await extractTextFromPDF(event.data.fileUrl); });

// ステップ 2:埋め込み用にチャンク化
const chunks = await step.run('chunk-text', async () => {
  return chunkText(text, { maxTokens: 500 });
});

// ステップ 3:埋め込みを生成(API のレート制限あり)
const embeddings = await step.run('generate-embeddings', async () => {
  return await openai.embeddings.create({
    model: 'text-embedding-3-small',
    input: chunks,
  });
});

// ステップ 4:ベクトル DB に保存
await step.run('store-vectors', async () => {
  await vectorDb.upsert({
    vectors: embeddings.data.map((e, i) => ({
      id: `${event.data.documentId}-${i}`,
      values: e.embedding,
      metadata: { chunk: chunks[i] },
    })),
  });
});

return { chunks: chunks.length, status: 'indexed' };

} );

検証チェック

Inngest の serve ハンドラーが存在する

重大度:重大

メッセージ:Inngest がイベントを受信するには、serve ハンドラーが必要です

修正方法:serve() をエクスポートする app/api/inngest/route.ts を作成します

serve に関数が登録されている

重大度:エラー

メッセージ:すべての Inngest 関数が serve() の呼び出しに登録されていることを確認してください

修正方法:serve() の functions 配列に関数を追加します

Step.run に説明的な名前が付いている

重大度:警告

メッセージ:ステップ名にはケバブケースを使い、内容が分かる名前を付けてください

修正方法:'fetch-user' や 'send-email' のような説明的なステップ名を使用します

waitForEvent にタイムアウトが設定されている

重大度:エラー

メッセージ:無期限の待機を防ぐため、waitForEvent にはタイムアウトを設定してください

修正方法:タイムアウトオプションを追加します:{ timeout: '24h' }

関数に同時実行数の上限がある

重大度:警告

メッセージ:下流サービスを保護するため、同時実行数の上限を設定することを検討してください

修正方法:関数の設定に concurrency: { limit: 10 } を追加します

イベント型が定義されている

重大度:警告

メッセージ:型安全性を確保するため、Inngest クライアントでイベントスキーマを定義してください

修正方法:schemas: new EventSchemas().fromRecord() を追加します

関数に一意の ID がある

重大度:重大

メッセージ:すべての Inngest 関数には一意の ID が必要です

修正方法:関数の設定に id: 'my-function-name' を追加します

Sleep に期間文字列を使用している

重大度:警告

メッセージ:step.sleep にはミリ秒ではなく、'1h' や '30m' のような期間文字列を使用してください

修正方法:期間文字列を使用します:step.sleep('wait', '1h')

再試行ポリシーが設定されている

重大度:警告

メッセージ:失敗への対処として、再試行ポリシーの設定を検討してください

修正方法:固定された SDK がサポートする retries オプションを設定してください。バックオフオブジェクトのスキーマを独自に作らないでください

支払い関数に冪等性キーがある

重大度:エラー

メッセージ:支払い関連の関数では、冪等性キーを使用してください

修正方法:ワークフローの重複排除とプロバイダー側の冪等性を、承認済みの注文に関連付けてください。ワークフローの設定だけでは、クラッシュ後の二重請求を防げません

コラボレーション

委譲のトリガー
  • redis|queue infrastructure|bullmq -> bullmq-specialist(既存のインフラストラクチャを使用してRedisベースのキューが必要な場合)
  • serverless queue|http queue|scheduled http -> upstash-qstash(イベントフレームワークを使わずに、プレーンなHTTP配信とcronが必要な場合)
  • saga|compensation|rollback|long-running workflow -> temporal-craftsman(補償処理を伴う複雑なワークフローオーケストレーションが必要な場合)
  • event sourcing|event store|cqrs -> event-architect(イベントソーシングのパターンが必要な場合)
  • vercel|deploy|production -> vercel-deployment(デプロイ設定が必要な場合)
  • database|schema|data model -> supabase-backend(イベントデータ用のデータベースが必要な場合)
  • api|endpoint|route -> backend(イベントをトリガーするAPIが必要な場合)
Vercelのバックグラウンドジョブ

スキル:inngest、nextjs-app-router、vercel-deployment

ワークフロー:

1. Define Inngest functions (inngest)
2. Set up serve handler in Next.js (nextjs-app-router)
3. Configure function timeouts (vercel-deployment)
4. Deploy and test (vercel-deployment)
AIパイプライン

スキル:inngest、ai-agents-architect、supabase-backend

ワークフロー:

1. Design AI workflow steps (ai-agents-architect)
2. Implement with Inngest durability (inngest)
3. Store results in database (supabase-backend)
4. Handle retries for API failures (inngest)
Webhook処理

スキル:inngest、stripe-integration、backend

ワークフロー:

1. Receive webhook (backend)
2. Send to Inngest with idempotency (inngest)
3. Process payment logic (stripe-integration)
4. Update application state (backend)
メールの自動化

スキル:inngest、email-systems、supabase-backend

ワークフロー:

1. Trigger event from user action (inngest)
2. Schedule drip emails with step.sleep (inngest)
3. Send emails with retry (email-systems)
4. Track email status (supabase-backend)
スケジュールされたタスク

スキル:inngest、backend、analytics-architecture

ワークフロー:

1. Define cron triggers (inngest)
2. Implement processing logic (backend)
3. Aggregate and report data (analytics-architecture)
4. Handle failures with alerting (inngest)

関連スキル

相性の良いスキル:nextjs-app-router、vercel-deployment、supabase-backend、email-systems、ai-agents-architect、stripe-integration

使用する場面

  • ユーザーがinngestについて言及している、または示唆している
  • ユーザーがサーバーレスのバックグラウンドジョブについて言及している、または示唆している
  • ユーザーがイベント駆動型ワークフローについて言及している、または示唆している
  • ユーザーがステップ関数について言及している、または示唆している
  • ユーザーが耐久性のある実行について言及している、または示唆している
  • ユーザーがvercelのバックグラウンドジョブについて言及している、または示唆している
  • ユーザーがスケジュールされた関数について言及している、または示唆している
  • ユーザーがファンアウトについて言及している、または示唆している

制限事項

  • 上記で説明されている範囲にタスクが明確に該当する場合にのみ、このスキルを使用してください。
  • 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
  • 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認してください。

コメント