Workflow が起動されると、任意のイベントを受け取れます。このイベントには、Workflow が処理するデータを含められます。リクエストの詳細、データベース(D1 や KV など)や webhook から取得したユーザーデータ、Queue コンシューマーからのメッセージなどです。
イベントは Workflow の強力な要素です。多くの場合、Workflow にはデータに対して処理をさせたいからです。Workflow インスタンスは耐久的に実行されるため、イベントは、不変(変化しない)であるべきデータや、その時点で Workflow が扱う必要があるデータを渡すのに適しています。
Workflow へパラメーターを渡す方法は 3 つあります。
- Worker から Workflow を起動するとき、Workflow バインディング の
createメソッドへ任意の引数として渡す。 wranglerCLI で Workflow を起動するとき、--paramsフラグで渡す。step.waitForEventAPI で渡す。実行中の 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 つです。
- Workers API バインディング:
instance.sendEventを呼び出し、特定の Workflow インスタンスへイベントを送ります。 - REST API(HTTP API)の Events エンドポイント を使う。
waitForEvent は WorkflowStep 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
}
}上の例では次を行います。
typeがstripe-webhookのwaitForEventを呼び出します。対応するsendEventはawait 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 日まで指定できます。
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の例と同様に、waitForEventとsendEventのtypeプロパティは一致させる必要があります。 waitForEventを複数回呼ぶ Workflow へ複数のイベントを送るには、対応するtypeプロパティを指定してsendEventを呼び出します(最大 100 文字 1)。- イベントは、REST API(HTTP API)の Events エンドポイント からも送れます。
デフォルトでは、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>;
}YourEventType を WorkflowEvent の型パラメーターとして渡すと、Workflow 定義全体で event.payload の型が YourEventType になります。
// 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 API の create メソッドで Workflow インスタンスを作成(トリガー)するときにも、Workflows 型に型パラメーターを渡せます。ただし、型情報は Workflow 本体には伝播しません。TypeScript の型はビルド時の構成だからです。