Our future generation platform is in closed beta. Please request to participate. During the beta, expect some rough edges, broken windows overlooking blue sky vistas, and regularly scheduled changes.

Bundling functionality with workflows

A Workflow is a set of processing steps that are executed in order. Each step in a Workflow is either a custom function that you define or a built-in function that comes with slack.

Workflows can be configured to run without any user input, or they can wait for input before continuing. When defining a Workflow, specifying input parameters that are not hidden will cause a modal to open and wait for input from the invoking user when the Workflow is invoked with a Shortcut trigger.

Defining Workflows

Workflows are defined in the /workflows folder of your project. Each file should contain one workflow, and should begin by importing the Slack Cloud SDK:

import { DefineWorkflow, Schema } from "slack-cloud-sdk/mod.ts";

Workflow files have two primary components:

  • the Workflow definition, in which you provide a name, description, and optionally define input parameters, and
  • the Workflow steps, which are invocations of functions (custom or built-in) that happen one after another.

To illustrate both the definition and the steps, let's look at a sample Workflow that accepts no input parameters and calls one built-in function, SendMessage:

// /workflows/say_hello_workflow.ts

// Workflow definition
export const SayHelloWorkflow = DefineWorkflow("say_hello_workflow", {
  title: "My Workflow",   
  description: "A sample workflow.",  
  input_parameters: { 
    required: [],
    properties: {},
  },
});

// Workflow steps
SayHelloWorkflow.addStep(Schema.slack.functions.SendMessage, {
  channel_id: "C1234567",
  message: "Hello, World!"
});

In the above code snippet, we begin by defining a Workflow with the DefineWorkflow function. Here we pass a unique string identifier and then a set of properties.

The title and description of a Workflow are just that. For Shortcut Triggers, these strings become the title and description placed inside the modal that pops up when collecting user input.

The input_parameters property is where you can define the kinds of input your Workflow will receive—and whether that input is required or optional. For the above example, we have not provided any input parameters, so this Workflow does not take any.

In the Workflow steps section, we call the addStep() method on our Workflow to call a function. In this case, we're calling the built-in function SendMessage, which sends a message to channel_id. We can call one or more functions, custom or built-in, in this way; Workflows can have many steps, and even call other Workflows—optionally passing one Workflow's input parameters into the input parameters of another.


Defining input parameters

Workflows can pass information into both Functions and other Workflows that are part of its Workflow steps. To do this, we define what information we want to bring in to the Workflow via the input_parameters property.

A Workflow's input_parameters property has two sub-properties: required, which is how you can ensure that a Workflow only executes if specific input parameters are provided, and properties, where you can list the specific parameters that your Workflow accounts for.

The following types of input parameter properties are supported:

Type Shorthand Full SDK reference Description
String string Schema.types.string UTF-8 encoded string, up to 4000 bytes
Boolean boolean Schema.types.boolean a logical value, must be either true or false
Integer integer Schema.types.integer a whole number, such as -1, 0 or 31415926535
Slack User ID user_id Schema.slack.types.user_id a Slack user ID, e.g. U18675309 or W15556162
Slack Usergroup ID usergroup_id Schema.slack.types.channel_id a Slack user group ID, e.g. S0614TZR7
Slack Channel ID channel_id Schema.slack.types.channel_id a Slack channel ID, e.g. C123ABC45 or D987XYZ65

Adding an input parameter to a workflow

Input parameters are listed in the properties property. Each input parameter must include a type and a description, and can optionally include a default value.

// Workflow definition
export const SayHelloWorkflow = DefineWorkflow("say_hello_workflow", {
  title: "My Workflow",   
  description: "A sample workflow.",  
  input_parameters: { 
    required: [],
    properties: {
        exampleString: {
          type: Schema.types.string,
          description: "Here's an example string.",
        },
        exampleBoolean: {
          type: Schema.types.boolean,
          description: "An example boolean.",
          default: true,
        },
        exampleInteger: {
          type: Schema.types.integer,
          description: "An example integer.",
        },
        exampleChannelId: {
          type: Schema.slack.types.channel_id,
          description: "Example channel ID.",
        },
        exampleUserId: {
          type: Schema.slack.types.user_id,
          description: "Example user ID.",
        },
        exampleUsergroupId: {
          type: Schema.slack.types.usergroup_id,
          description: "Example usergroup ID.",
        },
      }
  }
});

Required parameters can be indicated by listing their names as strings in the required property of input_parameters. For example, here's how we can indicate that a parameter named exampleUserId is required:

// Workflow definition
export const SayHelloWorkflow = DefineWorkflow("say_hello_workflow", {
  title: "My Workflow",   
  description: "A sample workflow.",  
  input_parameters: { 
    required: ["exampleUserId"],
    properties: {
        exampleUserId: {
          type: Schema.slack.types.user_id,
          description: "Example user ID.",
        },
      }
  }
});

If a Workflow is invoked and the required input parameters are not provided, the Workflow will not execute.


Using built-in functions in a workflow

To use a built-in function, like SendMessage:

  1. Ensure that Schema from the SDK is imported in your Workflow file:
import { Schema } from "slack-cloud-sdk/mod.ts";
  1. Use the function in one of your steps:
// Example: taking the string output from a function and passing it to SendMessage
MyWorkflow.addStep(Schema.slack.functions.SendMessage, {
  channel_id: MyWorkflow.inputs.channelId,
  message: MyWorkflow.inputs.someString
});

Using custom functions in a workflow

To use a custom function that you define:

  1. Import the function in the file where the Workflow is defined:
import { MyFunction } from "../functions/myFunction.ts";
  1. Call your function, storing its output in a variable. Here you may also pass input parameters from the Workflow into the Function itself:
import { MyFunction } from "../functions/my_function.ts";

export const MyWorkflow = DefineWorkflow(
  title: "My Workflow",
  description: "A sample workflow.",
  input_parameters: {
    required: [],
    properties: {
      someString: {
        type: Schema.types.string,
        description: "Some string"
      },
      channelId: {
        type: Schema.slack.types.channel_id,
        description: "Target channel.",
        default: "C1234567"
      }
    }
  }
);

const myFunctionResult = MyWorkflow.addStep(MyFunction, {
  // ... Pass along workflow inputs via MyWorkflow.inputs
  // ... For example, MyWorkflow.inputs.someString
});
  1. Use your function in follow-on steps.
// Example: taking the string output from a function and passing it to SendMessage
MyWorkflow.addStep(Schema.slack.functions.SendMessage, {
  channel_id: MyWorkflow.inputs.channelId,
  message: myFunctionResult.outputs.exampleOutput // This comes from your Function definition
});
// Example: invoking a custom function as a step in a workflow
MyWorkflow.addStep(MyFunction, {
  someInputVariable: MyWorkflow.inputs.someInput
});

Onward

Once you have defined a Workflow, you're ready to create a Trigger that invokes it. You can also learn more about creating a table to store data or deploying your app.

Was this page helpful?