glyde/attachment
A file attached to a message: what arrives with one, and what goes up on a
send or an edit. Attachment is the received record with its CDN URLs;
File is bytes to upload, paired with the attachments array by position.
The Clips-only fields, clip_participants, clip_created_at and
application, are not modelled.
Types
pub type Attachment {
Attachment(
id: id.Id(id.Attachment),
filename: String,
title: option.Option(String),
description: option.Option(String),
content_type: option.Option(String),
size: Int,
url: String,
proxy_url: String,
dimensions: option.Option(Dimensions),
placeholder: option.Option(Placeholder),
ephemeral: Bool,
duration_secs: option.Option(Float),
waveform: option.Option(String),
flags: flags.Flags(AttachmentFlag),
)
}
Constructors
-
Attachment( id: id.Id(id.Attachment), filename: String, title: option.Option(String), description: option.Option(String), content_type: option.Option(String), size: Int, url: String, proxy_url: String, dimensions: option.Option(Dimensions), placeholder: option.Option(Placeholder), ephemeral: Bool, duration_secs: option.Option(Float), waveform: option.Option(String), flags: flags.Flags(AttachmentFlag), )Arguments
- description
-
Alt text, up to 1024 characters.
- size
-
Bytes.
- url
-
A signed CDN URL that expires. Re-fetch the message, do not store it.
- proxy_url
-
The same URL through Discord’s media proxy, and it expires too.
- dimensions
-
Absent for anything that is not an image or a video. Discord sends both sides or neither, so one value carries both.
- placeholder
-
A thumbhash: a blurred preview to paint while the image loads. The version only says how the hash is encoded, so one value carries both.
- ephemeral
-
Garbage collected, so the URL dies before its signature expires.
- duration_secs
-
Voice messages and videos. Discord sends a whole number of seconds as
3, not3.0. - waveform
-
Base64 waveform preview for a voice message.
pub type AttachmentFlag {
IsClip
IsThumbnail
IsRemix
IsSpoiler
IsAnimated
}
Constructors
-
IsClip -
IsThumbnail -
IsRemixDiscord deprecated this one and still sends it.
-
IsSpoiler -
IsAnimated
pub type AttachmentFlags =
flags.Flags(AttachmentFlag)
Pixels. An image or a video has both, anything else has neither.
pub type Dimensions {
Dimensions(width: Int, height: Int)
}
Constructors
-
Dimensions(width: Int, height: Int)
What a message’s attachments should look like after an edit. Every route that edits a message takes one of these: the rule is the same wherever the field appears.
pub type EditAttachments {
KeepAttachments
SetAttachments(keep: List(KeptAttachment), add: List(File))
}
Constructors
-
KeepAttachmentsLeave them exactly as they are, and upload nothing.
-
SetAttachments(keep: List(KeptAttachment), add: List(File))The complete resulting set:
keepplusadd. Anything not listed is removed, soSetAttachments(keep: [], add: [])strips them all.
A file to upload.
pub type File {
File(
filename: String,
content_type: String,
data: BitArray,
description: option.Option(String),
title: option.Option(String),
spoiler: Bool,
voice: option.Option(Voice),
)
}
Constructors
-
File( filename: String, content_type: String, data: BitArray, description: option.Option(String), title: option.Option(String), spoiler: Bool, voice: option.Option(Voice), )Arguments
- content_type
-
Discord answers 500 on some endpoints when a part carries no content type. Use
application/octet-streamwhen you do not know. - description
-
Alt text, max 1024 characters.
- spoiler
-
The one place the spoiler lives.
filenamenever carries the prefix:filemoves it here andwire_filenameputs it back. - voice
-
Set by
voice_message. Discord needs both halves or neither, so they are one value.
pub type KeptAttachment {
KeptAttachment(
id: id.Id(id.Attachment),
description: option.Option(String),
title: option.Option(String),
)
}
Constructors
-
KeptAttachment( id: id.Id(id.Attachment), description: option.Option(String), title: option.Option(String), )Arguments
- description
-
Noneleaves the value Discord already has. It is not a clear.
A thumbhash and the layout it is encoded in. Discord documents 1 as the only version so far, so a hash that arrives without one reads as 1.
pub type Placeholder {
Placeholder(hash: String, version: Int)
}
Constructors
-
Placeholder(hash: String, version: Int)
Values
pub fn added_files(edit: EditAttachments) -> List(File)
The files an edit uploads, in files[n] order.
pub fn attachments_field(
edit: EditAttachments,
) -> field.Field(json.Json)
The attachments field of an edit. An empty array removes every
attachment, so SetAttachments always writes the key.
pub fn decoder() -> decode.Decoder(Attachment)
pub fn dimensions_field(
next: fn(option.Option(Dimensions)) -> decode.Decoder(a),
) -> decode.Decoder(a)
Read width and height and pair them. Discord sends both or neither on
an attachment and on embed media, so one helper decodes both places.
pub fn file(
filename filename: String,
content_type content_type: String,
data data: BitArray,
) -> File
A SPOILER_ prefix on filename is read as asking for a spoiler and moved
onto the boolean, so the two never say different things.
pub fn has_flag(
bits: flags.Flags(AttachmentFlag),
flag: AttachmentFlag,
) -> Bool
pub fn keep(id: id.Id(id.Attachment)) -> KeptAttachment
pub fn new_attachments_field(
files: List(File),
) -> field.Field(json.Json)
The attachments field of a create, where the array is only the uploads
and no array at all means no uploads.
pub fn parts(files: List(File)) -> List(body.File)
In files[n] order, the same order the attachments array numbers, so
part n points at entry n.
pub fn placeholder_field(
next: fn(option.Option(Placeholder)) -> decode.Decoder(a),
) -> decode.Decoder(a)
Read placeholder and placeholder_version and pair them. Shared by
attachments and embed media.
pub fn voice_message(
a_file: File,
duration_secs duration_secs: Float,
waveform waveform: String,
) -> File
Send it as a voice message. Discord also wants the IS_VOICE_MESSAGE flag on the message and an audio content type on the part.
pub fn wire_filename(a_file: File) -> String
The filename as it goes on the wire, spoiler prefix included. spoiler
decides, not the name: a record built by hand with a prefixed filename
gets stripped rather than prefixed twice.