EDA.Attachment (EDA v0.5.0-beta.2)

Copy Markdown View Source

Represents a Discord message attachment.

Attachments are read off a message:

for attachment <- message.attachments do
  if EDA.Attachment.spoiler?(attachment), do: IO.puts("blurred: " <> attachment.filename)
end

and written back through the :attachments array of a message edit — see keep/2.

Editing a message's attachments is destructive

Discord treats the attachments array as the complete list the message should end up with. Anything you leave out is deleted. Uploading one new file to a message that already has three therefore removes those three unless you name them:

{:ok, message} = EDA.Message.fetch_message(channel_id, message_id)

EDA.Message.edit(message,
  attachments: Enum.map(message.attachments, &EDA.Attachment.keep/1),
  files: [EDA.File.from_path("extra.png")]
)

EDA.Message.edit/2 accepts attachments: :keep as shorthand for that first line, which costs nothing because the struct already carries them.

Summary

Types

An attachment flag name.

t()

Functions

Every flag name EDA knows about.

Returns true if this attachment is an animated image.

Returns true if this attachment is a Clip from a stream.

This attachment is an animated image (1 <<< 5).

This attachment is a Clip from a stream (1 <<< 0).

Returns the set flags as a list of names, ignoring bits EDA does not know.

This attachment was edited with the remix feature on mobile (1 <<< 2).

This attachment is blurred until clicked (1 <<< 3).

This attachment is the thumbnail of a thread in a media channel (1 <<< 1).

Returns true if the given flag is set.

Builds the entry that keeps this attachment on a message being edited.

Returns true if this attachment was edited with the mobile remix feature.

Returns true if this attachment is blurred until clicked.

Returns true if this attachment is a media channel thread's thumbnail.

Types

flag()

@type flag() :: :clip | :thumbnail | :remix | :spoiler | :animated

An attachment flag name.

t()

@type t() :: %EDA.Attachment{
  content_type: String.t() | nil,
  description: String.t() | nil,
  duration_secs: number() | nil,
  ephemeral: boolean() | nil,
  filename: String.t() | nil,
  flags: integer() | nil,
  height: integer() | nil,
  id: String.t() | nil,
  placeholder: String.t() | nil,
  placeholder_version: integer() | nil,
  proxy_url: String.t() | nil,
  size: integer() | nil,
  title: String.t() | nil,
  url: String.t() | nil,
  waveform: String.t() | nil,
  width: integer() | nil
}

Functions

all_flags()

@spec all_flags() :: [flag()]

Every flag name EDA knows about.

animated?(attachment)

@spec animated?(t() | map() | integer() | nil) :: boolean()

Returns true if this attachment is an animated image.

clip?(attachment)

@spec clip?(t() | map() | integer() | nil) :: boolean()

Returns true if this attachment is a Clip from a stream.

flag_animated()

@spec flag_animated() :: integer()

This attachment is an animated image (1 <<< 5).

flag_clip()

@spec flag_clip() :: integer()

This attachment is a Clip from a stream (1 <<< 0).

flag_list(attachment)

@spec flag_list(t() | map() | integer() | nil) :: [flag()]

Returns the set flags as a list of names, ignoring bits EDA does not know.

Examples

iex> EDA.Attachment.flag_list(%EDA.Attachment{flags: (1 <<< 3) + (1 <<< 0)})
[:clip, :spoiler]

iex> EDA.Attachment.flag_list(nil)
[]

flag_remix()

@spec flag_remix() :: integer()

This attachment was edited with the remix feature on mobile (1 <<< 2).

flag_spoiler()

@spec flag_spoiler() :: integer()

This attachment is blurred until clicked (1 <<< 3).

flag_thumbnail()

@spec flag_thumbnail() :: integer()

This attachment is the thumbnail of a thread in a media channel (1 <<< 1).

from_raw(raw)

@spec from_raw(map()) :: t()

has_flag?(attachment, flag)

@spec has_flag?(t() | map() | integer() | nil, flag()) :: boolean()

Returns true if the given flag is set.

Accepts a t/0, a raw attachment map, a bitfield, or nil.

Examples

iex> EDA.Attachment.has_flag?(%EDA.Attachment{flags: 1 <<< 3}, :spoiler)
true

iex> EDA.Attachment.has_flag?(%{"flags" => 0}, :spoiler)
false

iex> EDA.Attachment.has_flag?(nil, :spoiler)
false

keep(attachment, opts \\ [])

@spec keep(
  t() | map() | String.t() | integer(),
  keyword()
) :: map()

Builds the entry that keeps this attachment on a message being edited.

An attachments array that omits an attachment deletes it, so every attachment the message should still have needs one of these. Accepts a t/0, a raw attachment map, or a bare id.

Options

Both are optional; leaving one out keeps the attachment's current value rather than clearing it. Discord accepts no other field for an attachment that already exists.

  • :description - new alt text (max 1024 characters)
  • :is_spoiler - blur it until clicked, or stop blurring it

Examples

iex> EDA.Attachment.keep(%EDA.Attachment{id: "123", filename: "a.png"})
%{id: "123"}

iex> EDA.Attachment.keep("123", is_spoiler: true, description: "A cat")
%{id: "123", description: "A cat", is_spoiler: true}

remix?(attachment)

@spec remix?(t() | map() | integer() | nil) :: boolean()

Returns true if this attachment was edited with the mobile remix feature.

spoiler?(attachment)

@spec spoiler?(t() | map() | integer() | nil) :: boolean()

Returns true if this attachment is blurred until clicked.

Reads the IS_SPOILER flag rather than looking for a SPOILER_ filename prefix. The prefix is the older way of asking for a spoiler; the flag is what Discord actually reports back, and it is set whichever way the attachment was uploaded.

Examples

iex> EDA.Attachment.spoiler?(%EDA.Attachment{flags: 1 <<< 3})
true

iex> EDA.Attachment.spoiler?(%EDA.Attachment{filename: "SPOILER_x.png", flags: 0})
false

thumbnail?(attachment)

@spec thumbnail?(t() | map() | integer() | nil) :: boolean()

Returns true if this attachment is a media channel thread's thumbnail.