Claude Code Plugins

Community-maintained marketplace

Feedback

|

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name inngest
description このスキルは、ユーザーが「Inngest 関数を作成」「バックグラウンドジョブを実装」「ステップ関数を書く」「Inngest をセットアップ」「イベント駆動処理を実装」「耐久実行を実装」「Cron ジョブを作成」「Fan-out パターンを実装」「サガパターン」「ワークフローオーケストレーション」「step.run」「step.waitForEvent」「step.invoke」「Inngest テスト」と言った場合に使用する。

Inngest 開発ガイド

Inngest はイベント駆動型の耐久実行プラットフォームで、キュー管理やインフラなしで信頼性の高いバックグラウンドジョブとワークフローを構築できる。Next.js との統合により、App Router と Pages Router の両方でサーバーレス環境での堅牢なバックグラウンド処理が実現する。

コア概念

イベント(Events)

イベントは関数をトリガーする JSON ペイロード。namedataプロパティを持つ。

{
  name: "app/user.signup",
  data: {
    userId: "12345",
    email: "user@example.com"
  },
  id?: string,      // 冪等性ID(24時間重複防止)
  ts?: number       // タイムスタンプ(ミリ秒)
}

関数(Functions)

Inngest 関数は 3 つの主要部分で構成される:

  • Triggers - イベントまたは Cron
  • Configuration - id、concurrency 等
  • Handler - ビジネスロジック

ステップ(Steps)

ステップは独立して再試行可能な作業単位。各ステップは個別の HTTP リクエストとして実行され、成功した結果はメモ化される。失敗時に成功済みステップを再実行せずに済む。

重要: 各ステップは単一の副作用にすべき。複数の副作用を 1 つのステップに入れると、再試行時に問題が発生する。

// ❌ 悪い例:複数の副作用
await step.run("create-alert", async () => {
  const alertId = await createAlert(); // 成功
  await sendAlertToSlack(alertId); // 失敗→再試行でalertが重複
});

// ✅ 良い例:1ステップ1副作用
const alertId = await step.run("create-alert", () => createAlert());
await step.run("send-to-slack", () => sendAlertToSlack(alertId));

セットアップ

パッケージインストール

npm install inngest

クライアント作成

// src/inngest/client.ts
import { EventSchemas, Inngest } from "inngest";

export const inngest = new Inngest({
  id: "my-app",
  schemas: new EventSchemas().fromRecord<{
    "app/user.created": { data: { userId: string; email: string } };
    "app/order.completed": { data: { orderId: string; total: number } };
  }>(),
});

基本的な関数定義

// src/inngest/functions.ts
import { inngest } from "./client";

export const helloWorld = inngest.createFunction(
  { id: "hello-world" }, // 設定
  { event: "test/hello.world" }, // トリガー
  async ({ event, step }) => {
    // ハンドラー
    await step.sleep("wait", "1s");
    return { message: "Hello " + event.data.email };
  }
);

Next.js App Router 統合

// src/app/api/inngest/route.ts
import { serve } from "inngest/next";
import { inngest } from "@/inngest/client";
import { helloWorld, processOrder } from "@/inngest/functions";

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

イベント送信

// APIルートから
await inngest.send({
  name: "app/user.signup",
  data: { userId: body.userId, email: body.email },
});

主要な Steps API

step.run() - コード実行

再試行可能なコードブロックを実行する。

const result = await step.run("fetch-data", async () => {
  return fetch("https://api.example.com/data").then((r) => r.json());
});

// 並列実行
const [users, orders] = await Promise.all([
  step.run("fetch-users", () => fetchUsers()),
  step.run("fetch-orders", () => fetchOrders()),
]);

step.sleep() / step.sleepUntil() - 遅延

await step.sleep("wait-30-min", "30m");
await step.sleepUntil("wait-date", new Date(event.data.remind_at));

最大スリープ時間: 1 年間(無料プランは 7 日間)

step.waitForEvent() - 外部イベント待機

const approval = await step.waitForEvent("wait-for-approval", {
  event: "app/invoice.approved",
  timeout: "7d",
  match: "data.invoiceId", // イベント間でマッチング
});

if (approval) {
  await step.run("process", () => processApproval(approval));
} else {
  await step.run("remind", () => sendReminder());
}

step.sendEvent() - イベント送信

// Fan-outパターンで使用
await step.sendEvent("trigger-notifications", [
  { name: "notification/email", data: { userId: "123" } },
  { name: "notification/sms", data: { userId: "123" } },
]);

step.invoke() - 他の関数を呼び出し

const result = await step.invoke("compute-square", {
  function: computeSquare,
  data: { number: 4 },
  timeout: "1h",
});

基本的な関数設定

オプション デフォルト 説明
id 必須 関数の一意識別子
retries 4 再試行回数(0-20)
concurrency - 並行実行制限

詳細な設定オプションはreferences/function-config.mdを参照。

エラーハンドリング

NonRetriableError - 即座に失敗

import { NonRetriableError } from "inngest";

await step.run("get-store", async () => {
  try {
    return await database.getStore(event.data.storeId);
  } catch (err) {
    throw new NonRetriableError("Store not found", { cause: err });
  }
});

RetryAfterError - 制御された遅延

import { RetryAfterError } from "inngest";

if (!success && retryAfter) {
  throw new RetryAfterError("Rate limit hit", retryAfter);
}

onFailure コールバック

inngest.createFunction(
  {
    id: "sync-products",
    retries: 5,
    onFailure: async ({ error, event, step }) => {
      await step.run("notify-slack", () =>
        slack.postMessage({
          channel: "alerts",
          text: "Sync failed: " + error.message,
        })
      );
    },
  },
  { event: "shop/sync.requested" },
  async ({ event, step }) => {
    /* ... */
  }
);

Cron スケジュール

// 毎日UTC 0:00
inngest.createFunction(
  { id: "daily-cleanup" },
  { cron: "0 0 * * *" },
  async ({ step }) => {
    /* ... */
  }
);

// タイムゾーン指定(毎週月曜9時 日本時間)
inngest.createFunction(
  { id: "weekly-report" },
  { cron: "TZ=Asia/Tokyo 0 9 * * 1" },
  async ({ step }) => {
    /* ... */
  }
);

冪等性

イベントレベル

await inngest.send({
  id: "checkout-completed-" + cartId, // 冪等性キー
  name: "cart/checkout.completed",
  data: { cartId },
});
// 同じidで24時間以内の重複イベントは無視される

関数レベル

inngest.createFunction(
  {
    id: "send-checkout-email",
    idempotency: "event.data.cartId", // CEL式
  },
  { event: "cart/checkout.completed" },
  async ({ event, step }) => {
    /* ... */
  }
);

注意: 冪等性キーは24 時間のみ有効。

よくある落とし穴

問題 回避方法
ステップ内の複数副作用 1 ステップ 1 副作用を徹底
inngest.send()の await 忘れ サーバーレスは即終了するため必ず await
ループによる大量ステップ 最大 1,000 ステップ/関数、Fan-out を使用
冪等性の 24 時間制限 長期の重複防止は別途実装
ステップ外の Date 生成 step.run()内で Date 生成

推奨プロジェクト構成

src/
├── inngest/
│   ├── client.ts          # Inngestクライアント(型定義含む)
│   ├── functions/
│   │   ├── sendWelcomeEmail.ts
│   │   ├── processOrder.ts
│   │   └── index.ts       # 全関数エクスポート
│   └── schemas/
│       └── events.ts      # イベント型定義
├── app/
│   └── api/
│       └── inngest/
│           └── route.ts   # serveエンドポイント

Dev Server

# 基本コマンド
npx inngest-cli@latest dev

# URLを指定
npx inngest-cli@latest dev -u http://localhost:3000/api/inngest

Dev Server UI: http://localhost:8288

追加リソース

リファレンスファイル

詳細なパターンと設定は以下を参照:

  • references/steps-api.md - Steps API 完全リファレンス
  • references/function-config.md - 関数設定オプション詳細
  • references/patterns.md - 高度なパターン(Fan-out、バッチ、並行制御等)

サンプルファイル

examples/に実装例:

  • basic-function.ts - 基本的な Inngest 関数
  • fan-out-pattern.ts - Fan-out パターン実装
  • error-handling.ts - エラーハンドリング実装