Slack can be a busy place, with millions of messages and numerous notifications.
Many messages inside Slack correspond to events outside Slack—the creation of a ticket, a calendar event, a news article.
Messages in Slack are one dimensional - message metadata allows these messages to become two-dimensional. In addition to surface level data we now have additional descriptive metadata that can kickoff a workflow and inform another app of next steps to take.
Message metadata allows your Slack app to link a message inside Slack to a corresponding outside event or pattern.
For example, if we wanted to add metadata about a customer to a message that alerts a channel whenever a new customer is created, we can start with the message object:
{
"channel": "A12345",
"text": "A new customer record has been created."
}
Then, we can attach some metadata to it:
{
"channel": "A12345",
"text": "A new customer record has been created.",
"metadata": {
"event_type": "customer_created",
"event_payload": {
"crm_id": "123456ABCD",
"external_id": "QWERTY12",
"nurture_step": "new_account"
}
}
}
After your message is sent and becomes part of a channel's timeline, your app or another developer's app can respond, react, or do something completely unexpected (but reasonable) in it's own way to your message metadata.
Maybe our CRM will perform some nurturing automations based on this new customer being created. Maybe the folks handling accounts payable use an app to automatically update their systems based on some external ID.
Whatever the case may be, you determine the unique event_type
for your automations as well as the structure of the event_payload
, giving you the opportunity to customize exactly how your apps and external systems communicate with each other.
With metadata, your app can become an event-driven vehicle, delivering information across the Slack platform in a structured way.
This doc will guide you through sending and receiving message metadata, and provide recommendations on how to set up your metadata schema along with additional resources. Read on!
"Metadata is a love note to the future." - Jason Scott
Message metadata consists of structured payloads defined by you that contain additional information beyond a message's obvious contents.
While the structure used for metadata is very close to the JSON schema standard, we have a few conventions and native types that differ. Using the recommended schema will allow your metadata events to be more easily accepted by other Slack apps.
Check out the design guidelines for suggested message metadata event schemas.
Once you have planned out a payload structure to link between messages that your app sends and some outside event, your app can send that metadata any time that it sends messages.
In order to send metadata with a message, include a metadata
parameter. You'll use two keys, event_type
and event_payload
, inside metadata
.
For example, use chat.postMessage
to send message metadata with the metadata
argument. It's easiest to use the method with a HTTP POST and an application/json
body.
POST /api/chat.postMessage
Host: slack.com
Authorization: Bearer xoxb-6050345600-60510457-…
Content-type: application/json; charset=utf-8
{
"channel": "C23456",
"text": "New task Added by @sam - Redesign homepage",
"metadata": {
"event_type": "task_created",
"event_payload": {
"id": "TK-2132",
"summary": "New issue with the display of mobile element",
"description": "An end user has found a problem with the new mobile container for data entry. It was reproduced in the current version of IOS.",
"priority": "HIGH",
"resource_type": "TASK"
}
}
}
Read on to learn how to receive metadata whenever your app gets messages from Slack.
In addition to sending metadata, your app may also receive it. This can be done with either the Web API or the Events API.
Message metadata is received via any way that apps send messages, such as conversations.history
, response urls, and more. If you receive a message by directly calling an API method, you will find a new metadata
parameter in the message object with two keys: event_type
and event_payload
.
Field | Type | Description | |
---|---|---|---|
event_type |
string | The type of the event triggered in your system. For example, task_added . |
|
event_payload |
object | This payload contains the custom properties that you've already defined in your .yaml file for your app. |
conversations.history
can be used to read metadata when you fetch a conversation's history.
Example request
GET /api/conversations.history?channel=C1234224&include_metadata=true
HOST: slack.com
Authorization: Bearer xoxb-12501860787-17163110960-...
Example response
{
"ok": true,
"messages": [
{
"type": "message",
"user": "U012AB3CDE",
"text": "New task Added by @sam - Redesign homepage",
"app_id": "A01234",
"metadata": {
"event_type": "task_added",
"event_payload": {
"id": "11223",
"title": "Redesign homepage",
"creator": "sam@acme-corp.com",
"created_at": "1610561787",
"priority": "high",
"status": "triage"
}
},
"ts": "1512085950.000216"
},
{
"type": "message",
"user": "U061F7AUR",
"text": "I'm going to start working on :point_up: task",
"ts": "1512104434.000490"
}
],
"has_more": true,
"pin_count": 0,
"response_metadata": {
"next_cursor": "bmV4dF90czoxNTEyMDg1ODYxMDAwNTQz"
}
}
Next, you can receive metadata by obtaining messages in an event-driven way. Along with metadata
, you'll see an app_id
in the message payload so that you can identify which app sent the metadata. There are two ways to consume these message objects:
You can receive message metadata when you subscribe to the messages.*
events. If a message has metadata, it will be available in the event payload.
{
"event": {
"type": "message",
"channel": "C024BE91L",
"user": "U2147483697",
"text": "New task Added by @sam - Redesign homepage",
"app_id": "A01234",
"metadata": {
"event_type": "task_added",
"event_payload": {
"id": "11223",
"title": "Redesign homepage",
"creator": "sam@acme-corp.com",
"created_at": "1610561787",
"priority": "high",
"status": "triage"
}
},
"ts": "1355517523.000005",
"event_ts": "1355517523.000005",
"channel_type": "channel"
}
}
Finally, you can subscribe specifically to a set of events that tell you when metadata has been posted, updated, or deleted, without consuming an entire firehose of messages. This requires three steps:
Configure your Slack app to request the message_metadata:read
scope.
Subscribe to the following events, as needed:
Event | Description |
---|---|
message_metadata_deleted |
Message metadata was deleted |
message_metadata_posted |
Message metadata was posted |
message_metadata_updated |
Message metadata was updated |
settings
, add in your metadata_subscriptions
under event_subscriptions
. Each entry requires an app_id
and event_type
pair where either (but not both) can be a wildcard '*'
. Due note that it's best practice to not use the wildcard unless you really need to!settings:
event_subscriptions:
request_url: https://example.ngrok.io/slack/events
bot_events:
- message_metadata_posted
metadata_subscriptions:
- app_id: '*'
event_type: <your-event-name>
- app_id: A1234
event_type: <your-event-name>
These events allow you to be updated on the goings on of the message metadata being consumed by your app.