Workflows are the combination of functions, executed in order. Remember:
Depending on your use case, you'll want to acquant yourself with either built-in functions, custom functions, or both. Then continue here to learn how to implement them in a workflow.
Workflows are defined in their own files within your app's /workflows
directory and implemented in your app's manifest.
Before defining your workflow, import DefineWorkflow
at the top of your workflow file:
// say_hello_workflow.ts
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
Then, create a workflow definition. This is where you set, at a minimum, the workflow's title and its unique callback ID:
// say_hello_workflow.ts
export const SayHelloWorkflow = DefineWorkflow({
callback_id: "say_hello_workflow",
title: "Say Hello",
});
Definition properties | Description |
---|---|
callback_id |
A unique string that identifies this particular component of your app |
title |
The display name of the workflow that shows up in slugs, unfurl cards, and certain end-user modals. |
description |
(Optional) A string description of this workflow. |
input_parameters |
(Optional) See Defining input parameters. |
output_parameters |
(Optional) See Defining output parameters. |
Once you've defined your workflow, you can then add functionality by calling built-in and custom functions. This is done with the addStep
method, which takes two arguments:
We'll see examples of how to call both types of functions in the following sections.
Built-in functions are essentially Slack-native actions, like creating a channel or sending a message.
To use a built-in function, like SendMessage
:
Schema
from the SDK is imported in your workflow source file:import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
addStep
method:export const SomeWorkflow = DefineWorkflow({
callback_id: "some-workflow",
title: "Some workflow",
input_parameters: {
properties: {
channelId: { type: Schema.slack.types.channel_id },
someString: { type: Schema.types.string },
},
required: [],
},
});
// Example: taking the string output from a function and passing it to SendMessage
SomeWorkflow.addStep(Schema.slack.functions.SendMessage, {
channel_id: SomeWorkflow.inputs.channelId,
message: SomeWorkflow.inputs.someString,
});
// manifest.ts
import { Manifest } from "deno-slack-sdk/mod.ts";
import { SayHelloWorkflow } from "./workflows/say_hello_workflow.ts";
export default Manifest({
name: "sayhello",
description: "A deno app with an example workflow",
icon: "assets/icon.png",
workflows: [SayHelloWorkflow], // Add your workflow here
botScopes: ["commands", "chat:write", "chat:write.public"],
});
Workflows can be configured to run without any user input, or they can wait for input via form before continuing.
The only built-in function that has an additional requirement is OpenForm
. When creating a workflow that will have a step to open a form, your workflow needs to:
interactivity
input parameterOpenForm
be its first stepHere's an example of a basic workflow definition using interactivity
:
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
export const SayHelloWorkflow = DefineWorkflow({
callback_id: "say_hello_workflow",
title: "Say Hello to a user",
input_parameters: {
properties: { interactivity: { type: Schema.slack.types.interactivity } },
required: ["interactivity"],
},
});
✨ Visit the forms section for more details and code examples of using OpenForm
in your app.
Custom functions are reusuable building blocks of automation of your own design.
To use a custom function that you have already defined:
import { SomeFunction } from "../functions/some_function.ts";
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
import { SomeFunction } from "../functions/some_function.ts";
export const SomeWorkflow = DefineWorkflow({
callback_id: "some_workflow",
title: "Some Workflow",
input_parameters: {
properties: {
someString: {
type: Schema.types.string,
description: "Some string",
},
channelId: {
type: Schema.slack.types.channel_id,
description: "Target channel",
default: "C1234567",
},
},
required: [],
},
});
const myFunctionResult = SomeWorkflow.addStep(SomeFunction, {
// ... Pass along workflow inputs via SomeWorkflow.inputs
// ... For example, SomeWorkflow.inputs.someString
});
// Example: taking the string output from a function and passing it to SendMessage
SomeWorkflow.addStep(Schema.slack.functions.SendMessage, {
channel_id: SomeWorkflow.inputs.channelId,
message: SomeFunction.outputs.exampleOutput, // This comes from your function definition
});
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 its 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 providedproperties
, where you can list the specific parameters that your workflow accounts for. Any built-in type or custom type can be used.Input parameters are listed in the properties
sub-property. Each input parameter must include a type
and a description
, and can optionally include a default
value.
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
// Workflow definition
export const SomeWorkflow = DefineWorkflow({
callback_id: "some_workflow",
title: "Some 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:
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
// Workflow definition
export const SomeWorkflow = DefineWorkflow({
callback_id: "some_workflow",
title: "Some 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.
Because workflows are comprised of functions, a workflow's output_parameters
can be the same types as a function's output_parameters
. They can be any built-in type or a custom type.
Output parameters are listed in the properties
sub-property of output_parameters
.
An output parameter with a built-in type must include a type
. An output parameter with a custom type must also include name
. We also recommend you include a description
for every parameter.
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
// Workflow definiton
export const SantaWorkflow = DefineWorkflow({
callback_id: "santa_workflow",
title: "Santa Workflow",
input_parameters: {
properties: {
elfId: {
type: Schema.slack.types.user_id,
description: "Unique Id for each elf.",
},
},
required: ["elfId"],
},
output_parameters: {
properties: {
elfStatus: {
type: Schema.types.string,
description: "The elf's toymaking status.",
},
},
required: [],
},
});
Please note that input_parameters
and output_parameters
are used when defining a function or workflow, whereas retrieving values will use inputs
and outputs
, respectively. inputs
and outputs
are also used when implementing the logic of a custom function.
➡️ To keep building your app, head to the triggers section to learn how to create a trigger that invokes a defined workflow.
You can also learn about creating a datastore to store and retrieve information, or building custom types for your data.
Have 2 minutes to provide some feedback?
We'd love to hear about your experience building modular Slack apps. Please complete our short survey so we can use your feedback to improve.