Represents a Discord channel.
Channel types
| Constant | Value | Description |
|---|---|---|
type_guild_text/0 | 0 | Text channel in a guild |
type_dm/0 | 1 | Direct message |
type_guild_voice/0 | 2 | Voice channel in a guild |
type_group_dm/0 | 3 | Group DM |
type_guild_category/0 | 4 | Category |
type_guild_news/0 | 5 | News / announcement channel |
type_guild_news_thread/0 | 10 | Thread in a news channel |
type_guild_public_thread/0 | 11 | Public thread |
type_guild_private_thread/0 | 12 | Private thread |
type_guild_stage_voice/0 | 13 | Stage voice channel |
type_guild_forum/0 | 15 | Forum channel |
type_guild_media/0 | 16 | Media channel |
Forum layout types
| Constant | Value | Description |
|---|---|---|
layout_not_set/0 | 0 | Not set |
layout_list_view/0 | 1 | List view |
layout_gallery_view/0 | 2 | Gallery view |
Sort order types
| Constant | Value | Description |
|---|---|---|
sort_latest_activity/0 | 0 | Latest activity |
sort_creation_date/0 | 1 | Creation date |
Summary
Functions
Every flag name EDA knows about.
Applies a changeset to a channel. No-op if the changeset has no changes.
Adds a change to an existing changeset for this entity.
Creates a changeset for batching mutations to this entity.
Deletes a channel.
Fetches a channel by ID. Checks cache first, falls back to REST.
Fetches a channel by ID. Raises on error.
Hides embedded media download options; media channels only (1 <<< 15).
Returns the set flags as a list of names, ignoring bits EDA does not know.
The channel's metadata is obfuscated because the bot cannot view it (1 <<< 17).
Thread pinned in its parent forum or media channel (1 <<< 1).
Threads in this forum or media channel require a tag (1 <<< 4).
The channel requires opt-in viewing (1 <<< 21).
Follows an announcement channel, posting its published messages to target. Returns the
webhook Discord created there, %{"channel_id" => ..., "webhook_id" => ...}.
Returns true if the channel is a forum channel (type 15).
Returns true if the given flag is set.
Returns 2 — Gallery view layout.
Returns 1 — List view layout.
Returns 0 — Forum layout not set.
Returns true if the channel is a media channel (type 16).
Modifies a channel. Accepts a struct or ID, a map of changes, and options.
Returns true if Discord has obfuscated this channel because the bot cannot view it.
The name Discord substitutes for an obfuscated channel.
Asks the gateway for a guild's ephemeral channel data (opcode 43): voice channel statuses and voice session start times, which are not part of the channel object.
Sends a message to a channel. Returns a %EDA.Message{} struct.
Sets a voice channel's status (up to 500 characters, or nil to clear it).
Returns 1 — Sort by creation date.
Returns 0 — Sort by latest activity.
Returns true if the channel is a thread (types 10, 11, 12).
Returns 1 — Direct message.
Returns 3 — Group DM.
Returns 4 — Guild category.
Returns 15 — Forum channel.
Returns 16 — Media channel.
Returns 5 — Guild news/announcement channel.
Returns 10 — Thread in a news channel.
Returns 12 — Private thread.
Returns 11 — Public thread.
Returns 13 — Stage voice channel.
Returns 0 — Guild text channel.
Returns 2 — Guild voice channel.
Types
@type flag() ::
:pinned | :require_tag | :hide_media_download_options | :obfuscated | :spoiler
A channel flag name.
@type t() :: %EDA.Channel{ app_permissions: String.t() | nil, applied_tags: [String.t()] | nil, available_tags: [EDA.ForumTag.t()] | nil, bitrate: integer() | nil, default_auto_archive_duration: integer() | nil, default_forum_layout: integer() | nil, default_reaction_emoji: map() | nil, default_sort_order: integer() | nil, default_thread_rate_limit_per_user: integer() | nil, flags: integer() | nil, guild_id: String.t() | nil, id: String.t() | nil, last_message_id: String.t() | nil, last_pin_timestamp: String.t() | nil, member_count: integer() | nil, message_count: integer() | nil, name: String.t() | nil, nsfw: boolean() | nil, owner_id: String.t() | nil, parent_id: String.t() | nil, permission_overwrites: [EDA.PermissionOverwrite.t()] | nil, permissions: String.t() | nil, position: integer() | nil, rate_limit_per_user: integer() | nil, status: String.t() | nil, thread_metadata: map() | nil, topic: String.t() | nil, total_message_sent: integer() | nil, type: integer() | nil, user_limit: integer() | nil }
Functions
@spec all_flags() :: [flag()]
Every flag name EDA knows about.
@spec apply_changeset( EDA.Entity.Changeset.t(), keyword() ) :: {:ok, t()} | {:error, term()}
Applies a changeset to a channel. No-op if the changeset has no changes.
Options
:reason- Audit log reason
@spec change(EDA.Entity.Changeset.t(), atom(), term()) :: EDA.Entity.Changeset.t()
Adds a change to an existing changeset for this entity.
@spec changeset(t()) :: EDA.Entity.Changeset.t()
Creates a changeset for batching mutations to this entity.
Deletes a channel.
Options
:reason- Audit log reason
Fetches a channel by ID. Checks cache first, falls back to REST.
Fetches a channel by ID. Raises on error.
@spec flag_hide_media_download_options() :: integer()
Hides embedded media download options; media channels only (1 <<< 15).
Returns the set flags as a list of names, ignoring bits EDA does not know.
Examples
iex> EDA.Channel.flag_list(%EDA.Channel{flags: (1 <<< 17) + (1 <<< 1)})
[:obfuscated, :pinned]
iex> EDA.Channel.flag_list(nil)
[]
@spec flag_obfuscated() :: integer()
The channel's metadata is obfuscated because the bot cannot view it (1 <<< 17).
@spec flag_pinned() :: integer()
Thread pinned in its parent forum or media channel (1 <<< 1).
@spec flag_require_tag() :: integer()
Threads in this forum or media channel require a tag (1 <<< 4).
@spec flag_spoiler() :: integer()
The channel requires opt-in viewing (1 <<< 21).
@spec follow(t() | String.t() | integer(), t() | String.t() | integer(), keyword()) :: {:ok, map()} | {:error, term()}
Follows an announcement channel, posting its published messages to target. Returns the
webhook Discord created there, %{"channel_id" => ..., "webhook_id" => ...}.
Options
:reason— audit log reason
Returns true if the channel is a forum channel (type 15).
Examples
iex> EDA.Channel.forum?(%EDA.Channel{type: 15})
true
iex> EDA.Channel.forum?(%EDA.Channel{type: 0})
false
Returns true if the given flag is set.
Accepts a t/0, a raw channel map as the cache stores it, a bitfield, or nil.
Examples
iex> EDA.Channel.has_flag?(%EDA.Channel{flags: 1 <<< 17}, :obfuscated)
true
iex> EDA.Channel.has_flag?(%{"flags" => 0}, :obfuscated)
false
iex> EDA.Channel.has_flag?(nil, :obfuscated)
false
Returns 2 — Gallery view layout.
Returns 1 — List view layout.
Returns 0 — Forum layout not set.
Returns true if the channel is a media channel (type 16).
Examples
iex> EDA.Channel.media?(%EDA.Channel{type: 16})
true
iex> EDA.Channel.media?(%EDA.Channel{type: 0})
false
Modifies a channel. Accepts a struct or ID, a map of changes, and options.
Options
:reason- Audit log reason
Returns true if Discord has obfuscated this channel because the bot cannot view it.
Obfuscated channels are still dispatched over the gateway, but their metadata is
redacted: name becomes ___hidden___, sensitive fields are nulled, and
permission_overwrites holds a single overwrite denying VIEW_CHANNEL to the
guild's @everyone role. Treat them as "exists but invisible" — in particular do
not compute permissions from those overwrites, and consider filtering them out of
channel listings shown to users.
Mandatory for every bot from 2026-11-16; before then it is opt-in via
config :eda, capabilities: [:channel_obfuscation] (see EDA.Gateway.Capabilities).
Examples
iex> EDA.Channel.obfuscated?(%EDA.Channel{flags: 1 <<< 17})
true
iex> EDA.Channel.obfuscated?(%EDA.Channel{flags: 0})
false
iex> EDA.Channel.obfuscated?(%{"flags" => 1 <<< 17})
true
iex> EDA.Channel.obfuscated?(nil)
false
@spec obfuscated_name() :: String.t()
The name Discord substitutes for an obfuscated channel.
Examples
iex> EDA.Channel.obfuscated_name()
"___hidden___"
Asks the gateway for a guild's ephemeral channel data (opcode 43): voice channel statuses and voice session start times, which are not part of the channel object.
The answer arrives as a CHANNEL_INFO event — EDA.Event.ChannelInfo. Returns :ok once the
request is sent; it does not wait for the answer. Changes after that arrive as
VOICE_CHANNEL_STATUS_UPDATE and VOICE_CHANNEL_START_TIME_UPDATE.
EDA.Channel.request_info(guild_id)
EDA.Channel.request_info(guild_id, [:status])
@spec send_message(t() | String.t() | integer(), String.t() | map() | keyword()) :: {:ok, EDA.Message.t()} | {:error, term()}
Sends a message to a channel. Returns a %EDA.Message{} struct.
@spec set_voice_status(t() | String.t() | integer(), String.t() | nil, keyword()) :: :ok | {:error, term()}
Sets a voice channel's status (up to 500 characters, or nil to clear it).
Accepts a channel struct or ID.
Options
:reason- Audit log reason
Returns 1 — Sort by creation date.
Returns 0 — Sort by latest activity.
Returns true if the channel is a thread (types 10, 11, 12).
Examples
iex> EDA.Channel.thread?(%EDA.Channel{type: 11})
true
iex> EDA.Channel.thread?(%EDA.Channel{type: 0})
false
Returns 1 — Direct message.
Returns 3 — Group DM.
Returns 4 — Guild category.
Returns 15 — Forum channel.
Returns 16 — Media channel.
Returns 5 — Guild news/announcement channel.
Returns 10 — Thread in a news channel.
Returns 12 — Private thread.
Returns 11 — Public thread.
Returns 13 — Stage voice channel.
Returns 0 — Guild text channel.
Returns 2 — Guild voice channel.