The new Slack platform and the features described below are in beta and under active development.

Message metadata events

When integrating message metadata into your app, you may want some additional type safety. Custom message metadata event types provide a way for Apps to validate message metadata against a schema that you define.

To create and use a custom message metadata event type, define the event type, register the event type, then use the event type in a trigger or function.

Define a custom event type

Create a new file to house your custom event type's definition. In this example, we'll create event_types/incident.ts.

The first thing we'll do in that file is import DefineEvent and Schema from the SDK:

// event_types/incident.ts

import { DefineEvent, Schema } from "deno-slack-sdk/mod.ts";

Next, use DefineEvent to create our event's definition. The following is an example of an event with its metadata event schema defined inline:

// event_types/incident.ts

import { DefineEvent, Schema } from "deno-slack-sdk/mod.ts";

const IncidentEvent = DefineEvent({
  name: "my_incident_event",
  title: "Incident",
  type: Schema.types.object,
  properties: {
    id: { type: Schema.types.string },
    title: { type: Schema.types.string },
    summary: { type: Schema.types.string },
    severity: { type: Schema.types.string },
    date_created: { type: Schema.types.number },
  },
  required: ["id", "title", "summary", "severity"],
  additionalProperties: false
});

export default IncidentEvent;

Events can be one of two types: the built-in Schema.types.object type, or a custom type that you define.

If you wanted to use a custom type for the event type, you can do that by setting the type to be your custom type (don't forget to import the type definition!).

const IncidentEvent = DefineEvent({
  name: "my_incident_event",
  title: "Incident",

  type: Schema.types.object,
  properties: {
    id: { type: Schema.types.string },
    title: { type: Schema.types.string },
    summary: { type: Schema.types.string },
    severity: { type: Schema.types.string },
    date_created: { type: Schema.types.number },
  },
  required: ["id", "title", "summary", "severity"],
  additionalProperties: false, // Setting this to false forces the validation to catch any additional properties
});

export default IncidentEvent;

Register a custom event type

Before your app can use your custom event type, you'll need to register it with the app's manifest. To register the newly defined event, add it to events array parameter of the manifest definition:

import IncidentEvent from "./event_types/incident.ts";

Manifest({
  ...
  events: [IncidentEvent],
});

Use a custom event type

There are two places where you can use your custom event type: *. Posting a message to Slack *. Creating a message metadata trigger

Posting a message to Slack

When you post a message to Slack using the metadata parameter, if the event_type matches the name of a custom event type specified in your app's manifest, our servers will validate that all required parameters are provided. If they're not, a warning will be returned in the response, and the message will still be posted—but without the message metadata since it didn't pass validation.

You can post a message to Slack either from within a custom function or while implementing your workflow.

Here's an example of using your event type while calling client.chat.postMessage() from within a custom function:

// This example assumes all required values are passed to the function's inputs
await client.chat.postMessage({
  channel_id: inputs.channel_id,
  message: "We have an incident!",
  metadata: {
    event_type: IncidentEvent,
    event_payload: {
      id: inputs.incident_id,
      title: inputs.incident_title,
      summary: inputs.incident_summary,
      severity: inputs.incident_severity,

      // Since this isn't required, it doesn't need to exist to pass validation
      date_created: inputs.incident_date, 
    }
  }
});

Another way to send a message with metadata using your custom event type is by using the built-in function SendMessage as one of your workflow's steps:

// This example assumes all required values are passed to the workflow's inputs
MyWorkflow.addStep(Schema.slack.functions.SendMessage, {
  channel_id: MyWorkflow.inputs.channel_id,
  message: "We have an incident!",
  metadata: {
    event_type: IncidentEvent,
    event_payload: {
      id: MyWorkflow.inputs.incident_id,
      title: MyWorkflow.inputs.incident_title,
      summary: MyWorkflow.inputs.incident_summary,
      severity: MyWorkflow.inputs.incident_severity,
      date_created: MyWorkflow.inputs.incident_date, // Since this isn't required, it doesn't need to exist to pass validation
    }
  }
});

Creating a message metadata trigger

A trigger can be created to watch for any message posted with a metadata event type matching your custom event type. When a match is found, that trigger will execute its configured workflow.

// triggers/incident_metadata_posted.ts

// A trigger definition file for the CLI
import { Trigger } from "deno-slack-api/types.ts";
import MyWorkflow from "../workflows/my_workflow.ts";
import IncidentEvent from "../event_types/incident.ts";

const trigger: Trigger<typeof MyWorkflow.definition> = {
  type: "event",
  name: "Incident Metadata Posted",
  inputs: {
    incident_id: { value: "{{data.metadata.event_payload.id}}" },
    incident_title: { value: "{{data.metadata.event_payload.title}}" },
    incident_summary: { value: "{{data.metadata.event_payload.summary}}" },
    incident_severity: { value: "{{data.metadata.event_payload.severity}}" },
    incident_date: { value: "{{data.metadata.event_payload.incident_date}}" },
  },
  // This is the workflow that will be started
  workflow: "#/workflows/start_incident",
  event: {
    event_type: "slack#/events/message_metadata_posted",

    // Note how we're using a custom metadata event type here
    metadata_event_type: IncidentEvent,
    channel_ids: ["C123ABC456"] // The channel that needs to be watched for message metadata being posted
  },
};

export default trigger;

Note that event triggers like the one above that listen for message metadata require the metadata.message:read scope added to the botScopes property of your manifest definition.

Have 2 minutes to provide some feedback?

We'd love to hear about your experience with the new Slack platform. Please complete our short survey so we can use your feedback to improve.