Inbound message anatomy

The Message shape every platform adapter normalizes to
View as Markdown

An incoming message is a Message. The same shape applies whether it came from Slack, the web chat, or any other adapter.

Message

FieldTypeRequiredNotes
idstringyesUUID assigned by the sidecar.
timestampTimestampyesWhen the platform received the message.
platformstringyes"slack", "web", "discord", etc.
platformContextPlatformContextyesPlatform-native IDs and event metadata.
userUseryesSender identity.
contentstringyesCleaned text. Adapters strip the bot’s @-mention before forwarding.
attachmentsAttachment[]noFiles, images, video, audio, link previews.
conversationIdstringyesStable correlation ID across the message lifecycle. Always echo back on responses.

Timestamp (google.protobuf.Timestamp)

FieldTypeNotes
secondsstringSeconds since UNIX epoch. Encoded as a string (can exceed JS safe int).
nanosnumberNanoseconds within the second.

User

FieldTypeRequiredNotes
idstringyesPlatform-specific user ID.
usernamestringnoDisplay name or handle.
avatarUrlstringnoAvatar URL.
emailstringnoEmail if available.
userData{ [key: string]: string }noPlatform-specific extras (workspace, role, etc.).

Attachment

FieldTypeRequiredNotes
typestringyesOne of the enum values below.
urlstringnoDownload URL when the source provides one. Filesystem-backed web uploads leave this empty.
filenamestringnoOriginal filename.
sizeBytesnumbernoFile size in bytes.
mimeTypestringnoMIME type.
titlestringnoDisplay title (rich attachments).
descriptionstringnoDisplay description.
widthnumbernoFor images/videos.
heightnumbernoFor images/videos.
storageKeystringnoOpaque Files API key for a web-chat upload. Resolve it through AGENT_FILES_DIR; never construct an input path from filename.

Attachment.type values: TYPE_UNSPECIFIED, IMAGE, FILE, VIDEO, AUDIO, LINK.

PlatformContext

FieldTypeRequiredNotes
messageIdstringyesOriginal platform message ID.
channelIdstringyesChannel/room/chat ID.
threadIdstringnoAgent’s reply target. Also set on top-level messages whose response should open a new thread.
threadRootIdstringnoParent thread root timestamp. Set only when this message is a reply inside an existing thread.
channelNamestringnoDisplay channel name.
workspaceIdstringnoSlack workspace, Discord guild, etc.
botUserIdstringnoThe bot’s own user ID in the source platform.
userIdstringnoRaw platform-native sender ID before any cross-platform identity resolution.
eventKindstringyesSee PlatformContextEventKind below.
platformData{ [key: string]: string }noPlatform-specific extras (Slack ts, Discord snowflake, Teams activity ID).

PlatformContextEventKind

ValueWhen the adapter emits it
EVENT_KIND_UNSPECIFIEDFallback. Should not appear in production traffic.
EVENT_KIND_DM1:1 / private chat (Slack DM, web chat session).
EVENT_KIND_APP_MENTIONBot was @-mentioned in a channel or thread.
EVENT_KIND_THREAD_REPLYReply inside an existing thread, no @-mention.
EVENT_KIND_OBSERVEDObserve-channel forward (listen-only).
EVENT_KIND_REACTIONReaction added/removed.
EVENT_KIND_BUTTON_CLICKInteractive button click on a CardAttachment.
EVENT_KIND_SLASH_COMMANDSlash command (Slack/Discord).
EVENT_KIND_ASSISTANT_THREAD_STARTEDSlack assistant thread opened.

For web-chat file input and agent-produced downloads, see Files in chat.

Next steps