Slink.Event (Slink v0.6.0)

Copy Markdown View Source

A Slack event, normalised into one shape regardless of transport.

Socket Mode wraps events in an envelope (events_api, slash_commands, interactive) and expects an ACK; the Events API delivers the same inner payload over HTTP. Both are reduced here to the same struct so your Slink.handle_event/2 never has to care which transport delivered it.

Fields

  • :type — the type you match on, as an atom for known types. The inner Slack type for event callbacks (:app_mention, :message) and interactions (:block_actions, :view_submission, …), or the envelope kind otherwise (:slash_commands, :url_verification).
  • :subtype — the event subtype, when present (e.g. "bot_message").
  • :payload — the inner event/command/interaction map you'll usually read.
  • :raw — the full original map, if you need something not surfaced above.
  • :transport:socket_mode or :http.
  • :kind:event_callback, :slash_commands, :interactive, or :other.
  • :envelope_id — Socket Mode ACK id (nil over HTTP).

Summary

Functions

The action_id of the first action in a block_actions interaction, or nil.

The value of the first action, or nil.

The list of actions in a block_actions interaction (empty otherwise).

Whether the app itself was mentioned — i.e. an app_mention event.

The callback_id of a shortcut / message action / view, or nil.

The channel the event happened in, or nil.

The text addressed to the bot: the event's text with Slack's link/mention markup reduced to the plain text a human typed, then trimmed.

The slash command name, e.g. "/deploy" (slash commands only), or nil.

Slack's per-event id (event_id) for an event callback, or nil.

Whether this event was produced by a bot (including this app itself).

Normalise a decoded Events API HTTP body.

Normalise a decoded application/x-www-form-urlencoded body.

Normalise a decoded Socket Mode envelope.

Whether this event happened inside a thread.

User IDs mentioned in the event's text, in order (e.g. ["U0123", "U0456"]).

Whether user_id is mentioned in the event's text.

The atom for a known Slack type string, or the string itself if unknown.

The thread_ts to reply into so a reply lands in this event's thread.

The short-lived response_url a slash command or interaction carries, or nil.

Whether Slack flagged this as a retry of an earlier delivery.

Slack's retry attempt number for this delivery (0 for a first delivery).

The Slack workspace (team) id this event came from, or nil.

The event's text, or an empty string.

The thread this event belongs to, or nil if it's not in a thread.

The trigger_id needed to open a modal in response to this event, or nil.

The event's own message timestamp (ts), or nil.

The user who produced the event, or nil.

The view map of a view_submission / view_closed interaction, or nil.

A modal's submitted input values (view.state.values), or %{}.

Types

t()

@type t() :: %Slink.Event{
  envelope_id: String.t() | nil,
  kind: :event_callback | :slash_commands | :interactive | :other,
  payload: map(),
  raw: map(),
  subtype: String.t() | nil,
  transport: :socket_mode | :http,
  type: atom() | String.t() | nil
}

Functions

action_id(event)

The action_id of the first action in a block_actions interaction, or nil.

action_value(event)

The value of the first action, or nil.

Handles a button's value and a select menu's selected_option.value.

actions(event)

The list of actions in a block_actions interaction (empty otherwise).

app_mention?(event)

Whether the app itself was mentioned — i.e. an app_mention event.

This is the "someone @-mentioned the bot" signal. To see who else is mentioned in the text, use mentions/1 (note the plural).

callback_id(event)

The callback_id of a shortcut / message action / view, or nil.

channel(event)

The channel the event happened in, or nil.

For block_actions interactions the channel is nested (and payload["channel"] is a map), so it's read from the interaction's channel/container instead.

command(event)

The text addressed to the bot: the event's text with Slack's link/mention markup reduced to the plain text a human typed, then trimmed.

Slack wraps links and mentions in angle brackets — <@U123|alice> (user), <#C1|general> (channel), <!here> (special), <mailto:a@b.com|a@b.com>, <https://x|label> (url). Each is unwrapped so the command reads naturally: a user/channel becomes its name, a mailto: becomes the bare address (so an email address "picks up" as plain text), a url stays the url, and a bare <@U123> — such as the bot's own mention at the start of an app_mention — drops out. So "@bot deploy now" → "deploy now" and a linkified "@bot <mailto:a@b.com|a@b.com>" → "a@b.com".

command_name(event)

The slash command name, e.g. "/deploy" (slash commands only), or nil.

event_id(event)

Slack's per-event id (event_id) for an event callback, or nil.

Stable across Slack's retries of the same event, so it's the dedup key (see Slink.Dedup). Only event callbacks carry one — slash commands and interactions return nil.

from_bot?(event)

Whether this event was produced by a bot (including this app itself).

Slack tags bot-authored messages with a bot_id. Handlers use this to skip the bot's own posts so an auto-reply never triggers itself in a loop. Message subtypes that nest the real message (message_changed — e.g. an edit or a link unfurl on the bot's own post — and message_deleted) carry the bot_id one level down, so that's checked too.

from_http(body)

Normalise a decoded Events API HTTP body.

from_http_form(params)

Normalise a decoded application/x-www-form-urlencoded body.

Slack delivers slash commands and interactions over HTTP as a form, not JSON. Interactions carry a single "payload" field holding JSON (decoded here); anything else is a slash command whose form fields are the payload.

from_socket_mode(env)

Normalise a decoded Socket Mode envelope.

in_thread?(event)

Whether this event happened inside a thread.

mentions(event)

User IDs mentioned in the event's text, in order (e.g. ["U0123", "U0456"]).

Empty when nobody is mentioned.

mentions?(event, user_id)

Whether user_id is mentioned in the event's text.

normalize_type(type)

The atom for a known Slack type string, or the string itself if unknown.

reply_thread(event)

The thread_ts to reply into so a reply lands in this event's thread.

If the event is already in a thread, that thread; otherwise the event's own ts, so replying starts a thread on it. nil if there's no timestamp.

response_url(event)

The short-lived response_url a slash command or interaction carries, or nil.

Valid for ~30 minutes and up to 5 posts; use it with Slink.API.respond/2 (or just reply/3, which routes there automatically for these events).

retry?(event)

Whether Slack flagged this as a retry of an earlier delivery.

retry_attempt(event)

Slack's retry attempt number for this delivery (0 for a first delivery).

Socket Mode carries it on the envelope; over HTTP the plug stashes the X-Slack-Retry-Num header into the body so it's visible here too.

team_id(event)

The Slack workspace (team) id this event came from, or nil.

For a multi-workspace app, use it to pick the bot token for that team — see the per-request :bot_token resolver in Slink.EventsApi.Plug.

text(event)

The event's text, or an empty string.

For message_changed / message_deleted subtypes this is the nested message's text (the edited / deleted content), not the wrapper's.

thread_ts(event)

The thread this event belongs to, or nil if it's not in a thread.

This is Slack's thread_ts — the ts of the thread's root message. For block_actions interactions it's read from the message the component is on, so a click in a thread threads and a click on a top-level message does not. For message_changed / message_deleted subtypes it's the nested message's.

trigger_id(event)

The trigger_id needed to open a modal in response to this event, or nil.

Present on slash commands and most interactions; valid for only ~3 seconds.

ts(event)

The event's own message timestamp (ts), or nil.

For block_actions interactions this is the ts of the message the component is on (from the interaction's message/container). For reaction_added/ reaction_removed it's the ts of the reacted-to item.

user(event)

The user who produced the event, or nil.

Interactions nest the user as a map (user.id) and slash commands carry a flat user_id; both are surfaced here as the plain user id, like message events. For message_changed / message_deleted subtypes this is the nested message's author.

view(event)

The view map of a view_submission / view_closed interaction, or nil.

view_values(event)

A modal's submitted input values (view.state.values), or %{}.