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.
Beginner

Publishing & consuming message metadata

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.

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"
        }
    }
}

Now, when that message is sent, either your or another app's Event Trigger can respond to this new message based on the metadata event_type. 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!


Defining metadata

Message metadata consists of structured payloads defined by you that contain additional information beyond a message's 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.


Sending Metadata

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"
        }
    }
}

If you're sending messages directly from your future generation app, you can invoke the client directly from the SDK in Typescript. In the below custom Function example, client is provided in the async function handler:

export const SendExampleMessage = DefineFunction(
  "send_example_message",
  {
    title: "Send Example Message",
    description: "Sends a message with metadata via chat.postMessage",
    input_parameters: {
      required: ["the_channel_id"],
      properties: {
        the_channel_id: {
          type: Schema.slack.types.channel_id,
          description: "The channel to post the message.",
        },
      },
    },
    output_parameters: {
      required: ["result"],
      properties: {
        result: {
          type: Schema.types.object,
          description: "Result of chat.postMessage",
        },
      },
    },
  },
  async ({ inputs, client, env }) => {
    const result = await client.call("chat.postMessage", {
      channel: inputs.the_channel_id,
      text:
        "The door reluctantly opens to reveal a rickety staircase descending into darkness.",
      metadata: {
        event_type: "door_opened",
        event_payload: {
          id: "ZORK-TRAP-DOOR-1313",
          summary: "The user opened the trap door to reveal a staircase",
          results: [
            "door:reluctant",
            "door:open",
            "staircase:descending",
            "darkness:foreboding",
          ],
          waiting_for: "COMMAND",
        },
      },
    });

    return await {
      outputs: { result },
    };
  },
);

Read on to learn how to receive metadata whenever your app gets messages from Slack.


Receiving metadata

In addition to sending metadata, your app may also receive it.

Directly receive messages with the Web 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 events-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:

Events API

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"
    }
}

Subscribe specifically to metadata via the Events API

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.

Configure your Slack app to request the message_metadata:read scope and subscribe to the following events:

Event Description
message_metadata_deleted Message metadata was deleted
message_metadata_posted Message metadata was posted
message_metadata_updated Message metadata was updated

These events allow you to be updated on the goings on of the message metadata being consumed by your app.

Resources

Ready to get started? Follow along with our hands-on tutorial that shows how to send and receive metadata events.

Was this page helpful?