Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

イベントとパラメーター

最終更新 Markdown で表示Agent セットアップ

Workflow が起動されると、任意のイベントを受け取れます。このイベントには、Workflow が処理するデータを含められます。リクエストの詳細、データベース(D1 や KV など)や webhook から取得したユーザーデータ、Queue コンシューマーからのメッセージなどです。

イベントは Workflow の強力な要素です。多くの場合、Workflow にはデータに対して処理をさせたいからです。Workflow インスタンスは耐久的に実行されるため、イベントは、不変(変化しない)であるべきデータや、その時点で Workflow が扱う必要があるデータを渡すのに適しています。

Workflow にデータを渡す

Workflow へパラメーターを渡す方法は 3 つあります。

  • Worker から Workflow を起動するとき、Workflow バインディングcreate メソッドへ任意の引数として渡す。
  • wrangler CLI で Workflow を起動するとき、--params フラグで渡す。
  • step.waitForEvent API で渡す。実行中の Workflow インスタンスが、イベント(と任意のデータ)を受け取れるまで待てます。Workflow インスタンスへは、HTTP 経由で外部サービスから、または Workflows の Workers API からイベントを送れます。

JSON としてシリアライズできるオブジェクトなら、パラメーターとして渡せます。

export default {
	async fetch(req, env) {
		let someEvent = { url: req.url, createdTimestamp: Date.now() };
		// Trigger our Workflow
		// Pass our event as the second parameter to the `create` method
		// on our Workflow binding.
		let instance = await env.MY_WORKFLOW.create({
			id: crypto.randomUUID(),
			params: someEvent,
		});

		return Response.json({
			id: instance.id,
			details: await instance.status(),
		});
	},
};
export default {
	async fetch(req: Request, env: Env) {
		let someEvent = { url: req.url, createdTimestamp: Date.now() };
		// Trigger our Workflow
		// Pass our event as the second parameter to the `create` method
		// on our Workflow binding.
		let instance = await env.MY_WORKFLOW.create({
			id: crypto.randomUUID(),
			params: someEvent,
		});

		return Response.json({
			id: instance.id,
			details: await instance.status(),
		});
	},
};

wrangler コマンドラインからパラメーターを渡すには、workflows trigger サブコマンドの第 2 引数に JSON 文字列を渡します。

npx wrangler@latest workflows trigger workflows-starter '{"some":"data"}'
🚀 Workflow instance "57c7913b-8e1d-4a78-a0dd-dce5a0b7aa30" has been queued successfully

イベントを待つ

実行中の Workflow は、Workflow 内で step.waitForEvent を呼び出すことでイベントを待てます。Workflow へイベントを送る方法は次の 2 つです。

  1. Workers API バインディングinstance.sendEvent を呼び出し、特定の Workflow インスタンスへイベントを送ります。
  2. REST API(HTTP API)の Events エンドポイント を使う。

waitForEventWorkflowStep API の一部なので、Workflow 内で複数回呼び出せます。制御フローで、条件付きでイベントを待つこともできます。

waitForEvent を呼ぶときは type(最大 100 文字 1)を指定する必要があります。Workflow インスタンスへイベントを送るときの type と照合するために使います。

たとえば、請求の webhook を待つ場合は次のとおりです。

export class MyWorkflow extends WorkflowEntrypoint {
	async run(event, step) {
		// Other steps in your Workflow
		let stripeEvent = await step.waitForEvent(
			"receive invoice paid webhook from Stripe",
			{ type: "stripe-webhook", timeout: "1 hour" },
		);
		// Rest of your Workflow
	}
}
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
	async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
		// Other steps in your Workflow
		let stripeEvent = await step.waitForEvent<IncomingStripeWebhook>(
			"receive invoice paid webhook from Stripe",
			{ type: "stripe-webhook", timeout: "1 hour" },
		);
		// Rest of your Workflow
	}
}

上の例では次を行います。

  • typestripe-webhookwaitForEvent を呼び出します。対応する sendEventawait instance.sendEvent({type: "stripe-webhook", payload: webhookPayload}) です。
  • TypeScript の 型パラメーター を使い、step.waitForEvent の戻り値を IncomingStripeWebhook として型付けします。
  • その後、Workflow の残りの処理を続けます。

waitForEvent のデフォルトタイムアウトは 24 時間です。変更するには、waitForEvent の第 2 引数に { timeout: WorkflowTimeoutDuration } を渡します。

let event = await step.waitForEvent("wait for human approval", {
	type: "approval-flow",
	timeout: "15 minutes",
});
let event = await step.waitForEvent(
		"wait for human approval",
		{ type: "approval-flow", timeout: "15 minutes" },
	);

タイムアウトは 1 秒から 365 日まで指定できます。

実行中の Workflow へイベントを送る

waitForEvent API でイベントを待っている Workflow インスタンスには、instance.sendEvent API でイベントを送れます。

export default {
	async fetch(req, env) {
		const instanceId = new URL(req.url).searchParams.get("instanceId");
		const webhookPayload = await req.json();

		let instance = await env.MY_WORKFLOW.get(instanceId);
		// Send our event, with `type` matching the event type defined in
		// our step.waitForEvent call
		await instance.sendEvent({
			type: "stripe-webhook",
			payload: webhookPayload,
		});

		return Response.json({
			status: await instance.status(),
		});
	},
};
export default {
	async fetch(req: Request, env: Env) {
		const instanceId = new URL(req.url).searchParams.get("instanceId");
		const webhookPayload = await req.json<Payload>();

		let instance = await env.MY_WORKFLOW.get(instanceId);
		// Send our event, with `type` matching the event type defined in
		// our step.waitForEvent call
		await instance.sendEvent({
			type: "stripe-webhook",
			payload: webhookPayload,
		});

		return Response.json({
			status: await instance.status(),
		});
	},
};
  • このガイドの waitForEvent の例と同様に、waitForEventsendEventtype プロパティは一致させる必要があります。
  • waitForEvent を複数回呼ぶ Workflow へ複数のイベントを送るには、対応する type プロパティを指定して sendEvent を呼び出します(最大 100 文字 1)。
  • イベントは、REST API(HTTP API)の Events エンドポイント からも送れます。

TypeScript と型パラメーター

デフォルトでは、Workflow 定義の run メソッドに渡される WorkflowEvent は、次の型に従います。

export type WorkflowCronSchedule = {
	/** Cron expression that triggered this event. */
	cron: string;
	/** Timestamp of the scheduled trigger, in milliseconds since the Unix epoch. */
	scheduledTime: number;
};

export type WorkflowEvent<T> = {
	/** The data passed as the parameter when the Workflow instance was triggered. */
	payload: Readonly<T>;
	/** The timestamp that the Workflow was triggered. */
	timestamp: Date;
	/** ID of the current Workflow instance. */
	instanceId: string;
	/** Name of the current Workflow. */
	workflowName: string;
	/** Metadata for Workflow instances created by a cron schedule. */
	schedule?: WorkflowCronSchedule;
};

Workflow バインディングに設定した cron スケジュールでインスタンスが作成された場合、event.schedule には、インスタンスを作成した cron 式と、スケジュールされたトリガー時刻が含まれます。

export class MyWorkflow extends WorkflowEntrypoint<Env> {
	async run(event: WorkflowEvent<unknown>, step: WorkflowStep) {
		if (event.schedule) {
			console.log(event.schedule.cron);
			console.log(new Date(event.schedule.scheduledTime));
		}
	}
}

独自の型を定義し、WorkflowEvent型パラメーター として渡すと、これらのイベントに型を付けられます。

// Define a type that conforms to the events your Workflow instance is
// instantiated with
interface YourEventType {
	userEmail: string;
	createdTimestamp: number;
	metadata?: Record<string, string>;
}

YourEventTypeWorkflowEvent の型パラメーターとして渡すと、Workflow 定義全体で event.payload の型が YourEventType になります。

src/index.tsts
// Import the Workflow definition
import { WorkflowEntrypoint, WorkflowStep, WorkflowEvent} from 'cloudflare:workers';

export class MyWorkflow extends WorkflowEntrypoint {
	// Pass your type as a type parameter to WorkflowEvent
	// The 'payload' property will have the type of your parameter.
	async run(event: WorkflowEvent<YourEventType>, step: WorkflowStep) {
		let state = await step.do("my first step", async () => {
			// Access your properties via event.payload
          let userEmail = event.payload.userEmail
          let createdTimestamp = event.payload.createdTimestamp
        })

        await step.do("my second step", async () => { /* your code here */ })
	}
}

Workers APIcreate メソッドで Workflow インスタンスを作成(トリガー)するときにも、Workflows 型に型パラメーターを渡せます。ただし、型情報は Workflow 本体には伝播しません。TypeScript の型はビルド時の構成だからです。

Footnotes

  1. 照合パターン: ^[a-zA-Z0-9_][a-zA-Z0-9-_]*$ 2

役に立ちましたか?