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.
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;
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],
});
There are two places where you can use your custom event type: *. Posting a message to Slack *. Creating a message metadata trigger
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
}
}
});
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.