Scheduled triggers

Developing automations requires a paid plan. Don't have a paid plan? Join the Developer Program and provision a sandbox with access to all Slack features for free.

Invoke a workflow at specific time intervals

Scheduled triggers are an automatic type of trigger. This means that once the trigger is created, they do not require any user input.

Use a scheduled trigger if you need a workflow to kick off after a delay or on an hourly, daily, weekly, or annual cadence.

Create a scheduled trigger

Triggers can be added to workflows in two ways:

  • You can add triggers with the CLI. These static triggers are created only once. You create them with the Slack CLI, attach them to your app's workflow, and that's that. The trigger is defined within a trigger file.

  • You can add triggers at runtime. These dynamic triggers are created at any step of a workflow so they can incorporate data acquired from other workflow steps. The trigger is defined within a function file.

Slack CLI built-in documentation
Use slack trigger --help to easily access information on the trigger command's flags and subcommands.

The triggers you create when running locally (with the slack run command) will not work when you deploy your app in production (with the slack deploy command). You'll need to create any triggers again with the CLI.

Create the trigger file

To create a scheduled trigger with the CLI, you'll need to create a trigger file. The trigger file contains the payload you used to define your trigger.

Create a TypeScript trigger file within your app's folder with the following form:

import { Trigger } from "deno-slack-api/types.ts";
import { ExampleWorkflow } from "../workflows/example_workflow.ts";
import { TriggerTypes } from "deno-slack-api/mod.ts";

const trigger: Trigger<typeof ExampleWorkflow.definition> = {
  // your TypeScript payload
};

export default trigger;

Your TypeScript payload consists of the parameters needed for your own use case. Below is the trigger file from the Message Translator app:

// triggers/daily_maintenance_job.ts
import { Trigger } from "deno-slack-sdk/types.ts";
import workflowDef from "../workflows/maintenance_job.ts";
import { TriggerTypes } from "deno-slack-api/mod.ts";

/**
 * A trigger that periodically starts the "maintenance-job" workflow.
 */
const trigger: Trigger<typeof workflowDef.definition> = {
  type: TriggerTypes.Scheduled,
  name: "Trigger a scheduled maintenance job",
  workflow: `#/workflows/${workflowDef.definition.callback_id}`,
  inputs: {},
  schedule: {
    // Schedule the first execution 60 seconds from when the trigger is created
    start_time: new Date(new Date().getTime() + 60000).toISOString(),
    end_time: "2037-12-31T23:59:59Z",
    frequency: { type: "daily", repeats_every: 1 },
  },
};

export default trigger;

Use the trigger create command

Once you have created a trigger file, use the following command to create the scheduled trigger:

slack trigger create --trigger-def "path/to/trigger.ts"

If you have not used slack triggers create to create a trigger prior to running slack run, you will receive a prompt in the CLI to do so.

Your app needs to have the triggers:write scope to use a trigger at runtime. Include the scope within your app's manifest.

The logic of a runtime trigger lies within a function's TypeScript code. Within your functions folder, you'll have the functions that are the steps making up your workflow. Within this folder is where you can create a trigger within the relevant <function>.ts file.

When you create a runtime trigger, you can leverage inputs acquired from functions within the workflow. Provide the workflow definition to get additional typing for the workflow and inputs fields.

Create a scheduled trigger at runtime using the client.workflows.triggers.create method within the relevant function file.

const triggerResponse = await client.workflows.triggers.create<typeof ExampleWorkflow.definition>({
  // your TypeScript payload
});

Your TypeScript payload consists of the parameters needed for your own use case. Below is the function file with a TypeScript payload for a scheduled trigger from the Daily Channel Topic app:

// functions/create_scheduled_trigger.ts
import { SlackAPI } from "deno-slack-api/mod.ts";
import { DefineFunction, Schema, SlackFunction } from "deno-slack-sdk/mod.ts";
import { TriggerTypes } from "deno-slack-api/mod.ts";

export const CreateScheduledTrigger = DefineFunction({
  title: "Create a scheduled trigger",
  callback_id: "create_scheduled_trigger",
  source_file: "functions/create_scheduled_trigger.ts",
  input_parameters: {
    properties: {
      channel_id: {
        description: "The ID of the Channel to create a schedule for",
        type: Schema.slack.types.channel_id,
      },
    },
    required: ["channel_id"],
  },
  output_parameters: {
    properties: {
      trigger_id: {
        description: "The ID of the trigger created by the Slack API",
        type: Schema.types.string,
      },
    },
    required: ["trigger_id"],
  },
});

export default SlackFunction(
  CreateScheduledTrigger,
  async ({ inputs, token }) => {
    console.log(`Creating scheduled trigger to update daily topic`);

    const client = SlackAPI(token, {});
    const scheduleDate = new Date();
    // Start schedule 1 minute in the future. Start_time must always be in the future.
    scheduleDate.setMinutes(scheduleDate.getMinutes() + 1);

    // triggers/sample_scheduled_update_topic.txt has a JSON example of the payload
    const scheduledTrigger = await client.workflows.triggers.create({
      name: `Channel ${inputs.channel_id} Schedule`,
      workflow: "#/workflows/scheduled_update_topic",
      type: TriggerTypes.Scheduled,
      inputs: {
        channel_id: { value: inputs.channel_id },
      },
      schedule: {
        start_time: scheduleDate.toUTCString(),
        frequency: {
          type: "daily",
          repeats_every: 1,
        },
      },
    });

    if (!scheduledTrigger.trigger) {
      return {
        error: "Trigger could not be created",
      };
    }

    console.log("scheduledTrigger has been created");

    return {
      outputs: { trigger_id: scheduledTrigger.trigger.id },
    };
  },
);

Scheduled trigger parameters

Field Description Required?
type The type of trigger: TriggerTypes.Scheduled Yes
name The name of the trigger Yes
workflow Path to workflow that the trigger initiates Yes
schedule When and how often the trigger will activate. See The schedule object below Yes
description The description of the trigger No
inputs The inputs provided to the workflow. See the inputs object below No

Scheduled triggers are not interactive. Use a link trigger to take advantage of interactivity.

The inputs object

The inputs of a trigger map to the inputs of a workflow. You can pass any value as an input.

There is also a specific input value that contains information about the trigger. Pass this value to provide trigger information to your workflows!

Field How to reference Type Description
data.user_id TriggerContextData.Scheduled.user_id string A unique identifier for the user who created the trigger

The following snippet shows a user_id input being set with a value of TriggerContextData.Scheduled.user_id, representing the user who created the trigger.

...
inputs: {
  user_id: {
    value: TriggerContextData.Scheduled.user_id
  }
},
...

The schedule object

Field Description Required?
start_time ISO date string of the first scheduled trigger Yes
timezone Timezone string to use for scheduling No
frequency Details on what cadence trigger will activate. See The frequency object below No
occurrence_count The maximum number of times trigger will run No
end_time If set, this trigger will not run past the provided ISO date string No

The frequency object

One-time triggers
Field Description Required?
type How often the trigger will activate: once Yes
repeats_every How often the trigger will repeat, respective to frequency.type No
on_week_num The nth week of the month the trigger will repeat No

Example one-time trigger

import { TriggerTypes } from "deno-slack-api/mod.ts";
import { ScheduledTrigger } from "deno-slack-api/typed-method-types/workflows/triggers/scheduled.ts";
import { ExampleWorkflow } from "../workflows/example_workflow.ts";

const schedule: ScheduledTrigger<typeof ExampleWorkflow.definition> = {
  name: "Sample",
  type: TriggerTypes.Scheduled,
  workflow: `#/workflows/${ExampleWorkflow.definition.callback_id}`,
  inputs: {},
  schedule: {
    // Starts 60 seconds after creation
    start_time: new Date(new Date().getTime() + 60000).toISOString(),
    timezone: "asia/kolkata",
    frequency: {
      type: "once",
    },
  },
};
export default schedule;

Hourly triggers
Field Description Required?
type How often the trigger will activate: hourly Yes
repeats_every How often the trigger will repeat, respective to frequency.type Yes
on_week_num The nth week of the month the trigger will repeat No

Example hourly trigger

import { TriggerTypes } from "deno-slack-api/mod.ts";
import { ScheduledTrigger } from "deno-slack-api/typed-method-types/workflows/triggers/scheduled.ts";
import { ExampleWorkflow } from "../workflows/example_workflow.ts";

const schedule: ScheduledTrigger<typeof ExampleWorkflow.definition> = {
  name: "Sample",
  type: TriggerTypes.Scheduled,
  workflow: `#/workflows/${ExampleWorkflow.definition.callback_id}`,
  inputs: {},
  schedule: {
    // Starts 60 seconds after creation
    start_time: new Date(new Date().getTime() + 60000).toISOString(),
    end_time: "2040-05-01T14:00:00Z",
    frequency: {
      type: "hourly",
      repeats_every: 2,
    },
  },
};
export default schedule;

Daily triggers
Field Description Required?
type How often the trigger will activate: daily Yes
repeats_every How often the trigger will repeat, respective to frequency.type Yes
on_week_num The nth week of the month the trigger will repeat No

Example daily trigger

import { TriggerTypes } from "deno-slack-api/mod.ts";
import { ScheduledTrigger } from "deno-slack-api/typed-method-types/workflows/triggers/scheduled.ts";
import { ExampleWorkflow } from "../workflows/example_workflow.ts";

const schedule: ScheduledTrigger<typeof ExampleWorkflow.definition> = {
  name: "Sample",
  type: TriggerTypes.Scheduled,
  workflow: `#/workflows/${ExampleWorkflow.definition.callback_id}`,
  inputs: {},
  schedule: {
    // Starts 60 seconds after creation
    start_time: new Date(new Date().getTime() + 60000).toISOString(),
    end_time: "2040-05-01T14:00:00Z",
    occurrence_count: 3,
    frequency: { type: "daily" },
  },
};
export default schedule;

Weekly triggers
Field Description Required?
type How often the trigger will activate: weekly Yes
on_days The days of the week the trigger should activate on Yes
repeats_every How often the trigger will repeat, respective to frequency.type Yes
on_week_num The nth week of the month the trigger will repeat No

Example weekly trigger

import { TriggerTypes } from "deno-slack-api/mod.ts";
import { ScheduledTrigger } from "deno-slack-api/typed-method-types/workflows/triggers/scheduled.ts";
import { ExampleWorkflow } from "../workflows/example_workflow.ts";

const schedule: ScheduledTrigger<typeof ExampleWorkflow.definition> = {
  name: "Sample",
  type: TriggerTypes.Scheduled,
  workflow: `#/workflows/${ExampleWorkflow.definition.callback_id}`,
  inputs: {},
  schedule: {
    // Starts 60 seconds after creation
    start_time: new Date(new Date().getTime() + 60000).toISOString(),
    frequency: {
      type: "weekly",
      repeats_every: 3,
      on_days: ["Friday", "Monday"],
    },
  },
};
export default schedule;

Monthly triggers
Field Description Required?
type How often the trigger will activate: monthly Yes
on_days The day of the week the trigger should activate on. Provide the on_week_num value along with this field. Yes
repeats_every How often the trigger will repeat, respective to frequency.type Yes
on_week_num The nth week of the month the trigger will repeat No

Example monthly trigger

import { TriggerTypes } from "deno-slack-api/mod.ts";
import { ScheduledTrigger } from "deno-slack-api/typed-method-types/workflows/triggers/scheduled.ts";
import { ExampleWorkflow } from "../workflows/example_workflow.ts";

const schedule: ScheduledTrigger<typeof ExampleWorkflow.definition> = {
  name: "Sample",
  type: TriggerTypes.Scheduled,
  workflow: `#/workflows/${ExampleWorkflow.definition.callback_id}`,
  inputs: {},
  schedule: {
    // Starts 60 seconds after creation
    start_time: new Date(new Date().getTime() + 60000).toISOString(),
    frequency: {
      type: "monthly",
      repeats_every: 3,
      on_days: ["Friday"],
      on_week_num: 1,
    },
  },
};
export default schedule;

Yearly triggers
Field Description Required?
type How often the trigger will activate: yearly Yes
repeats_every How often the trigger will repeat, respective to frequency.type Yes
on_week_num The nth week of the month the trigger will repeat No

Example yearly trigger

import { TriggerTypes } from "deno-slack-api/mod.ts";
import { ScheduledTrigger } from "deno-slack-api/typed-method-types/workflows/triggers/scheduled.ts";
import { ExampleWorkflow } from "../workflows/example_workflow.ts";

const schedule: ScheduledTrigger<typeof ExampleWorkflow.definition> = {
  name: "Sample",
  type: TriggerTypes.Scheduled,
  workflow: `#/workflows/${ExampleWorkflow.definition.callback_id}`,
  inputs: {},
  schedule: {
    // Starts 60 seconds after creation
    start_time: new Date(new Date().getTime() + 60000).toISOString(),
    frequency: {
      type: "yearly",
      repeats_every: 2,
    },
  },
};
export default schedule;

Scheduled trigger response

The response will have a property called ok. If true, then the trigger was created, and the trigger property will be populated.

Your response will include a trigger.id; be sure to store it! You use that to update or delete the trigger if need be. See trigger management.

Onward

➡️ With your trigger created, you can now test your app by running your app locally.

✨ Once your app is active, see trigger management for info on managing your triggers in your workspace.


Have 2 minutes to provide some feedback?

We'd love to hear about your experience building Slack automations. Please complete our short survey so we can use your feedback to improve.