Slack Automation: No More Hardcoding channel_ids for Event Triggers!
Published: 2024-04-17 04:40:51

We're excited to share a significant improvement to event triggers on Slack's automation platform has been deployed!

## What's the Slack Automation Platform?

For those who may be asking, "What's the Slack Automation Platform?" please start here:

* The official documents: https://api.slack.com/automation
* Tutorials I wrote: https://dev.to/seratch/series/21161

Among the numerous ways to invoke workflows on this platform, one is known as "Event Triggers." This article elaborates on the most recent updates to these triggers.

## Types of Event Triggers

There are two types of event triggers available:

* **(A)** Events that occur within an existing channel
* **(B)** Events not tied to a specific existing channel

For **(A)**, examples include events like `message_posted`, which is triggered by a new message posting, and `reaction_added`, which occurs when a reaction is added to a message.

For **(B)**, examples include `user_joined_team`, which is triggered when a new member joins the workspace, and `channel_created`, which occurs when a new channel is created.

For a tutorial on setting up the simplest event triggers, I would recommend reading the following article, particularly if you're new to this concept:

https://dev.to/seratch/slack-next-gen-platform-reactionadded-event-trigger-54i

## What Has Changed?

For **(A)**, it used to be required to **hard-code an array of channel IDs** where the workflow will be enabled within the trigger's definition, as demonstrated below:

```typescript
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
export const workflow = DefineWorkflow({
  callback_id: "example-workflow",
  ...
});

import { Trigger } from "deno-slack-api/types.ts";

const trigger: Trigger<typeof workflow.definition> = {
  type: "event",
  name: "A sample trigger",
  workflow: `#/workflows/${workflow.definition.callback_id}`,
  event: {
    event_type: "slack#/events/reaction_added",
    channel_ids: ["C12345", "C23456"], // This was mandatory!
    filter: { version: 1, root: { statement: "{{data.reaction}} == eyes" } },
  },
  inputs: {
    channel_id: { value: "{{data.channel_id}}" },
    user_id: { value: "{{data.user_id}}" },
    message_ts: { value: "{{data.message_ts}}" },
  },
};
export default trigger;
```

The part to highlight here is:

```typescript
    channel_ids: ["C12345", "C23456"], // This was mandatory!
```

This requirement has been posing challenges for users seeking to enable workflows in various channels. To update the list of channels, a developer had to delete the existing trigger by `slack trigger delete` first, then edit `event.channel_ids` within the code and create the trigger again with `slack trigger create`. Alternatively, a fresh trigger definition could be created and added using `slack trigger create`.

As a workaround to this issue, I've invented a little creative approach to have a separate workflow for configuring event triggers within the same app. This entails having a primary workflow requiring an event trigger and an associated sub workflow. The sub workflow helps an end-user to easily configure `channel_ids` through modal dialog interactions, and the sub workflow invites the bot user to those channels.

Here are the links to examples of the implementation:

* [Link trigger to launch the configuration workflow](https://github.com/slack-samples/deno-message-translator/blob/main/triggers/configurator.ts)
* [Definition of the configuration workflow](https://github.com/slack-samples/deno-message-translator/blob/main/workflows/configurator.ts)
* [Custom function providing the configuration modal dialog](https://github.com/slack-samples/deno-message-translator/blob/main/functions/configure.ts)
* [Process for setting triggers using the workflows.triggers.create|update API](https://github.com/slack-samples/deno-message-translator/blob/main/functions/internals/trigger_operations.ts)

This approach is widely used not only in the above-mentioned deno-message-translator but also in many sample apps under https://github.com/slack-samples and in custom app codes developed by our customers.

Nonetheless, if it's possible to avoid writing such code, it would indeed be more advantageous...


## No Need for `channel_ids` with `all_resources: true`!

With deno-slack-sdk 2.10.0 / deno-slack-api v2.4.0 or newer, `event.channel_ids` has become unnecessary (of course, it's still available for backward compatibility!). Please make sure to update your `import_map.json` to these versions or a later one:

```json
{
  "imports": {
    "deno-slack-sdk/": "https://deno.land/x/deno_slack_sdk@2.10.0/",
    "deno-slack-api/": "https://deno.land/x/deno_slack_api@2.4.0/"
  }
}
```

The newly added option is `all_resources: boolean`. When you set the flag to true, the `channel_ids` are no longer needed.

```typescript
const trigger: Trigger<typeof workflow.definition> = {
  type: "event",
  name: "A sample trigger",
  workflow: `#/workflows/${workflow.definition.callback_id}`,
  event: {
    event_type: "slack#/events/reaction_added",
    all_resources: true, // Just this!
    filter: { version: 1, root: { statement: "{{data.reaction}} == eyes" } },
  },
  inputs: {
    channel_id: { value: "{{data.channel_id}}" },
    user_id: { value: "{{data.user_id}}" },
    message_ts: { value: "{{data.message_ts}}" },
  },
};
export default trigger;
```

When creating an event trigger using this option, there is no need to maintain the trigger definition afterward. The subsequent step is simply to invite the bot user to the channels where you want this workflow to be triggered.

In the example above, once the bot user is invited to a channel, the workflow will start invoke the workflow whenever a message in the channel receives an `:eyes:` reaction.

## Migrating Existing Workflows

Existing triggers can be deleted using the following steps:

* Display a list of configured triggers for the target app with `slack trigger list`.
* Remove unnecessary triggers by executing `slack trigger delete --trigger-id (ID starting with Ft)`.

Next, run `slack trigger create --trigger-def (path to source file)` to create a new trigger with `all_resources: true`.

Usually, the bot user should already be invited to the relevant channels. If this isn't the case, please proceed to manually invite the bot as necessary. After this, the triggers should respond to events as intended.

## Reminder: Make Sure Your import_map.json Settings Are Correct!

As a reminder, the `all_resources` option will not work unless the versions of deno-slack-sdk / deno-slack-api specified in `import_map.json` are as follows or newer:

```json
{
  "imports": {
    "deno-slack-sdk/": "https://deno.land/x/deno_slack_sdk@2.10.0/",
    "deno-slack-api/": "https://deno.land/x/deno_slack_api@2.4.0/"
  }
}
```

Always update to the latest versions, which can also be done using the `slack upgrade` command.

## Wrap Up

We've finally streamlined a more user-friendly setup process! If you've tried it before and found it challenging, we encourage you to give it another try!