Slink.Event (Slink v0.2.1)

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

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.

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

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

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.

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.

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.

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.

text(event)

The event's text, or an empty string.

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.

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.

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 %{}.