Scheduling
The scheduling service in Flows provides ways to execute code at specified times, either on a recurring schedule or after a specific delay. This enables blocks to perform time-based operations without requiring external triggers or manual intervention.
Timers can be linked with pending events for better observability of asynchronous operations.
Overview
Section titled “Overview”Scheduling in Flows comes in two forms:
- Declarative scheduling - Predefined cron or frequency-based schedules specified in app or block definitions that run on a regular basis
- Imperative scheduling (timers) - Dynamically created one-time timers that trigger after a specified delay
These capabilities enable important patterns such as:
- Polling external APIs for new data
- Performing regular maintenance tasks like refreshing auth tokens
- Implementing delays and timeouts
- Retrying operations after failures
- Checking the status of long-running processes
Declarative scheduling
Section titled “Declarative scheduling”Declarative schedules are defined in the app or block schema and automatically managed by the Flows platform.
Defining schedules
Section titled “Defining schedules”To add scheduled operations to an app or a block, include a schedules object in your block definition:
{ schedules: { generateDailyReport: { description: "Generates the daily summary report", // Run at 8:00 AM every weekday definition: { type: "cron", cron: { expression: "0 8 * * 1-5", location: "America/New_York", }, }, onTrigger: async (input) => { // Your report generation logic here... }, }, },},Customizable schedules
Section titled “Customizable schedules”Schedules can be marked as customizable, which allows them to be configured by users:
{ schedules: { dataSync: { description: "Synchronizes data from the external API", customizable: true, // Users can customize this schedule definition: { type: "frequency", frequency: { interval: 1, unit: "hours" // Default: every hour } }, onTrigger: async (input) => { // Your data synchronization logic here... }, }, },}When a schedule is marked as customizable:
- The default schedule serves as the initial value
- Users can modify the schedule through the block configuration UI
- The schedule becomes part of the block’s configuration
Imperative scheduling (timers)
Section titled “Imperative scheduling (timers)”In addition to declarative schedules, Flows provides an imperative API for setting one-time timers that trigger after a specified delay.
Setting timers
Section titled “Setting timers”To create a timer, use the timers.app.set and timers.block.set functions:
import { timers } from "@slflows/sdk/v1";
// Set a timer to trigger after 30 secondsconst timerId = await timers.app.set(30, { inputPayload: { message: "Don't forget to check the status!" }, description: "Reminder to check operation status",});
console.log(`Timer set with ID: ${timerId}`);The timer set functions take these arguments:
delaySeconds: How long to wait before triggering (in seconds)options: Optional configuration object with:inputPayload: Data to pass to the handler when the timer triggersdescription: A human-readable description for the UIpendingEventId: Optional pending event ID to associate with the timerpromptId: Optional prompt ID to associate with the timer
The function returns a unique ID for the timer, which can be used to unset it if needed.
Unsetting timers
Section titled “Unsetting timers”To cancel a timer before it triggers, use the timers.app.unset and timers.block.unset functions:
import { timers } from "@slflows/sdk/v1";
// Cancel a previously set timerawait timers.block.unset(timerId);Handling timer events
Section titled “Handling timer events”To handle app or block timer events, implement the onTimer handler on the appropriate level:
{ onTimer: async (input) => { const { timer } = input; console.log("Timer triggered with payload:", timer.payload); },};In addition to app and/or block contexts, onTimer handler receives a timer containing information about the timer that fired, including:
timer.payload: The payload data provided when the timer was settimer.pendingEvent: Optional information about an associated pending event, containing:id: The pending event IDbody: The current event body/payload (if any)status: Current status description (if any)