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.

Creating reusable functions

Functions are the building blocks of the next generation of the Slack platform. They are standalone modules of functionality that can be added, by anyone, to workflows in Workflow Builder. Functions define inputs and outputs of a type, such as string for a string of text or channel for a Slack channel, and do some unit of work such as calling an external API or running a database query. Most functions will probably call an API so one way to think of a function is a Slack-specific wrapper for an API or, alternately, a way to make an API method easily available inside of Slack.

By convention, functions are declared in the functions directory at the root of a project, with each function declared as its own TypeScript file.

A function is defined via the DefineFunction method, which is part of the SDK that gets included with every newly created project. The function is exported so that it can be used elsewhere in your app (e.g. in workflows). DefineFunction accepts a name (as a string) and object that defines the input and output parameters as well as an anonymous, asynchronous function that performs that actual work of the function (i.e. taking the input, doing something like calling an API, and then providing an output via a promise).

Sample function

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

export const ReverseString = DefineFunction(
    title: "Reverse",
    description: "Takes a string and reverses it",
    input_parameters: {
      required: [],
      properties: {
        stringToReverse: {
          type: Schema.types.string,
          description: "The string to reverse",
    output_parameters: {
      required: [],
      properties: {
        reverseString: {
          type: Schema.types.string,
          description: "The string in reverse",
  async ({ inputs, env }) => {
    console.log(`reversing ${inputs.stringToReverse}.`);

    const reverseString = inputs.stringToReverse.split("").reverse().join("");
    return await {
      outputs: { reverseString },

Inputs and outputs

Most functions will declare at least one input parameter that it will accept (input_parameters) and at least one output parameter (output_parameters) that it will produce when the function is executed.

The input_parameters and output_parameters must be of one of the following types:

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 such as U18675309 or W15556162
Slack Usergroup ID usergroup_id Schema.slack.types.usergroup_id a Slack usergroup ID such as S0614TZR7
Slack Channel ID channel_id Schema.slack.types.channel_id a Slack channel ID such as C123ABC45 or D987XYZ65

When defining the types of a parameter, you may either use the type values listed above (e.g. string or user_id) or you import the Schema object from the SDK and reference the full defined constant (e.g. Schema.types.string or Schema.slack.types.user_id).

While, strictly speaking, input and output parameters are optional, they are a common and standard way to pass data between functions and nearly any function you write will expect at least one input and pass along an output.

Functions are similar in philosophy to Unix system commands: they should be minimalist, modular, and reusable. Expect the output of one function to become the input of another, with no other frame of reference.


Now that you've written a function, you can bundle functions together with Workflow Functions, create a table to store data, or deploy your app to Slack infrastructure.

Was this page helpful?