# `Slink.Event`
[🔗](https://github.com/wkirschbaum/slink/blob/v0.6.0/lib/slink/event.ex#L1)

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
`c: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).

# `t`

```elixir
@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
}
```

# `action_id`

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

# `action_value`

The value of the first action, or `nil`.

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

# `actions`

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

# `app_mention?`

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`

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

# `channel`

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`

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`

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

# `event_id`

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?`

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`

Normalise a decoded Events API HTTP body.

# `from_http_form`

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`

Normalise a decoded Socket Mode envelope.

# `in_thread?`

Whether this event happened inside a thread.

# `mentions`

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

Empty when nobody is mentioned.

# `mentions?`

Whether `user_id` is mentioned in the event's text.

# `normalize_type`

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

# `reply_thread`

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`

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?`

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

# `retry_attempt`

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`

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`

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`

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`

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`

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`

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`

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

# `view_values`

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
