glyde/message
Messages: what arrives, what to send, and every endpoint that acts on one.
A Draft builds the create body, an Edit the patch body. send,
reply, edit, delete, react and pin take a whole Message where
they can, so the ids come from the value you already hold; each has an
_id variant for a caller who only has ids.
content, embeds, attachments and components arrive EMPTY, not
absent, without the MESSAGE_CONTENT intent. Nothing tells that apart from a
genuinely empty message.
MESSAGE_UPDATE does not carry a Message, whatever the docs say. Use
update_decoder, never decoder, on that event.
Types
pub type ChannelMention {
ChannelMention(
id: id.Id(id.Channel),
guild_id: id.Id(id.Guild),
type_: channel.ChannelType,
name: String,
)
}
Constructors
-
ChannelMention( id: id.Id(id.Channel), guild_id: id.Id(id.Guild), type_: channel.ChannelType, name: String, )
POST /channels/{c}/messages. Discord needs at least one of content,
embeds, sticker_ids, components, a file or a poll, unless it is a
forward. Not checked here: Discord’s 400 names the bad fields.
pub type Draft {
Draft(
content: option.Option(String),
embeds: List(embed.Embed),
components: List(component.Component),
sticker_ids: List(id.Id(id.Sticker)),
files: List(attachment.File),
allowed_mentions: option.Option(mentions.AllowedMentions),
reference: option.Option(Reference),
tts: Bool,
nonce: NoncePolicy,
flags: flags.Flags(MessageFlag),
)
}
Constructors
-
Draft( content: option.Option(String), embeds: List(embed.Embed), components: List(component.Component), sticker_ids: List(id.Id(id.Sticker)), files: List(attachment.File), allowed_mentions: option.Option(mentions.AllowedMentions), reference: option.Option(Reference), tts: Bool, nonce: NoncePolicy, flags: flags.Flags(MessageFlag), )Arguments
- content
-
Max 2000 characters.
- embeds
-
Max 10, and 6000 characters across all of them.
- sticker_ids
-
Max 3.
- files
-
Drives both the
attachmentsarray and thefiles[n]parts. - allowed_mentions
-
Noneis Discord’s default: parse and deliver every mention in the content. A decision, not an absence. - nonce
-
Discord ignores
enforce_noncewithout a nonce, so the two are one value and the inert combination cannot be built. - flags
-
Only SUPPRESS_EMBEDS, SUPPRESS_NOTIFICATIONS, IS_VOICE_MESSAGE and IS_COMPONENTS_V2 can be set on a create.
PATCH /channels/{c}/messages/{m}. The attachments array has to name
every attachment that survives the edit, so it and the uploads are one
field.
pub type Edit {
Edit(
content: field.Field(String),
embeds: field.Field(List(embed.Embed)),
components: field.Field(List(component.Component)),
flags: field.Field(flags.Flags(MessageFlag)),
allowed_mentions: mentions.AllowedMentions,
attachments: attachment.EditAttachments,
)
}
Constructors
-
Edit( content: field.Field(String), embeds: field.Field(List(embed.Embed)), components: field.Field(List(component.Component)), flags: field.Field(flags.Flags(MessageFlag)), allowed_mentions: mentions.AllowedMentions, attachments: attachment.EditAttachments, )Arguments
- embeds
-
Nullsendsnull.Present([])empties the list, which is what IS_COMPONENTS_V2 requires: it wants[]specifically, notnull. - flags
-
SUPPRESS_EMBEDS can be set and unset. IS_COMPONENTS_V2 can only be set, and never comes off that message again.
- allowed_mentions
-
Not optional. An edit that leaves it out re-parses the content with Discord’s defaults, whatever the message was sent with.
Discord splices member into each element of mentions.
pub type Mention {
Mention(
user: user.User,
member: option.Option(member.GuildMember),
)
}
Constructors
-
Mention( user: user.User, member: option.Option(member.GuildMember), )
pub type Message {
Message(
id: id.Id(id.Message),
channel_id: id.Id(id.Channel),
guild_id: option.Option(id.Id(id.Guild)),
author: user.User,
member: option.Option(member.GuildMember),
content: String,
timestamp: String,
edited_timestamp: option.Option(String),
tts: Bool,
mention_everyone: Bool,
mentions: List(Mention),
mention_roles: List(id.Id(id.Role)),
mention_channels: List(ChannelMention),
attachments: List(attachment.Attachment),
embeds: List(embed.Embed),
reactions: List(Reaction),
nonce: option.Option(Nonce),
pinned: Bool,
webhook_id: option.Option(id.Id(id.Webhook)),
type_: MessageType,
application_id: option.Option(id.Id(id.Application)),
flags: flags.Flags(MessageFlag),
message_reference: option.Option(MessageReference),
referenced_message: field.Field(Message),
thread: option.Option(channel.Channel),
components: List(component.Component),
sticker_items: List(StickerItem),
position: option.Option(Int),
)
}
Constructors
-
Message( id: id.Id(id.Message), channel_id: id.Id(id.Channel), guild_id: option.Option(id.Id(id.Guild)), author: user.User, member: option.Option(member.GuildMember), content: String, timestamp: String, edited_timestamp: option.Option(String), tts: Bool, mention_everyone: Bool, mentions: List(Mention), mention_roles: List(id.Id(id.Role)), mention_channels: List(ChannelMention), attachments: List(attachment.Attachment), embeds: List(embed.Embed), reactions: List(Reaction), nonce: option.Option(Nonce), pinned: Bool, webhook_id: option.Option(id.Id(id.Webhook)), type_: MessageType, application_id: option.Option(id.Id(id.Application)), flags: flags.Flags(MessageFlag), message_reference: option.Option(MessageReference), referenced_message: field.Field(Message), thread: option.Option(channel.Channel), components: List(component.Component), sticker_items: List(StickerItem), position: option.Option(Int), )Arguments
- guild_id
-
A gateway extra. Absent in DMs and on ephemeral messages.
- author
-
Not a real user when
webhook_idis set: id, username and avatar only. - member
-
A gateway extra with no
userkey: the author is the field above. - content
-
EMPTY, not absent, when the app lacks the MESSAGE_CONTENT intent.
- timestamp
-
ISO-8601.
- edited_timestamp
-
Null means never edited.
- tts
-
Always false on MESSAGE_UPDATE, whatever the original message was.
- mention_channels
-
Crossposted messages only, and only from public text channels.
- reactions
-
Absent when there are none, and from message search results.
- nonce
-
Nonewhen there was none, and when the one sent was too big to hold. Always sendStringNonce, whatever arrived here. - webhook_id
-
The only reliable webhook test:
author.botis true of bots too. - referenced_message
-
Absentis never fetched,Nullis deleted, the only signal a reply bot gets. Usereferencedif you do not care which. - position
-
Approximate, with gaps and duplicates. Ordering only.
Where in a channel’s history to read. One value, not three optional fields, because Discord rejects two cursors on one request.
pub type MessageCursor {
Around(id.Id(id.Message))
Before(id.Id(id.Message))
After(id.Id(id.Message))
}
Constructors
-
Around(id.Id(id.Message))Centred on a message, returning the ones either side of it.
-
Before(id.Id(id.Message))Older than a message.
-
After(id.Id(id.Message))Newer than a message.
pub type MessageFlag {
Crossposted
IsCrosspost
SuppressEmbeds
SourceMessageDeleted
Urgent
HasThread
Ephemeral
Loading
FailedToMentionSomeRolesInThread
SuppressNotifications
IsVoiceMessage
HasSnapshot
IsComponentsV2
}
Constructors
-
Crossposted -
IsCrosspost -
SuppressEmbeds -
SourceMessageDeleted -
Urgent -
HasThread -
Ephemeral -
Loading -
FailedToMentionSomeRolesInThread -
SuppressNotifications -
IsVoiceMessage -
HasSnapshot -
IsComponentsV2Once set on a message this can never be removed.
pub type MessageFlags =
flags.Flags(MessageFlag)
pub type MessageReference {
MessageReference(
type_: MessageReferenceType,
message_id: option.Option(id.Id(id.Message)),
channel_id: option.Option(id.Id(id.Channel)),
guild_id: option.Option(id.Id(id.Guild)),
)
}
Constructors
-
MessageReference( type_: MessageReferenceType, message_id: option.Option(id.Id(id.Message)), channel_id: option.Option(id.Id(id.Channel)), guild_id: option.Option(id.Id(id.Guild)), )Arguments
- type_
-
Absent reads as DEFAULT. A value this build has no name for fails the decode.
- message_id
-
Absent on CHANNEL_FOLLOW_ADD and THREAD_CREATED, which reference a channel and not a message.
A value this build has no name for fails the decode.
pub type MessageReferenceType {
DefaultReference
ForwardReference
}
Constructors
-
DefaultReferenceReplies, crossposts, pins and thread starters. Populates
referenced_message. -
ForwardReferenceForwards. Populates
message_snapshots, which is not modelled.
0 to 46, with holes at 13, 30, 33 to 35, 40 to 43 and 45. Never index this by position. A value this build has no name for fails the decode.
pub type MessageType {
DefaultMessage
RecipientAdd
RecipientRemove
Call
ChannelNameChange
ChannelIconChange
ChannelPinnedMessage
UserJoin
GuildBoost
GuildBoostTier1
GuildBoostTier2
GuildBoostTier3
ChannelFollowAdd
GuildDiscoveryDisqualified
GuildDiscoveryRequalified
GuildDiscoveryGracePeriodInitialWarning
GuildDiscoveryGracePeriodFinalWarning
ThreadCreated
ReplyMessage
ChatInputCommand
ThreadStarterMessage
GuildInviteReminder
ContextMenuCommand
AutoModerationAction
RoleSubscriptionPurchase
InteractionPremiumUpsell
StageStart
StageEnd
StageSpeaker
StageTopic
GuildApplicationPremiumSubscription
GuildIncidentAlertModeEnabled
GuildIncidentAlertModeDisabled
GuildIncidentReportRaid
GuildIncidentReportFalseAlarm
PurchaseNotification
PollResult
}
Constructors
-
DefaultMessage -
RecipientAdd -
RecipientRemove -
Call -
ChannelNameChange -
ChannelIconChange -
ChannelPinnedMessage -
UserJoin -
GuildBoost -
GuildBoostTier1 -
GuildBoostTier2 -
GuildBoostTier3 -
ChannelFollowAdd -
GuildDiscoveryDisqualified -
GuildDiscoveryRequalified -
GuildDiscoveryGracePeriodInitialWarning -
GuildDiscoveryGracePeriodFinalWarning -
ThreadCreated -
ReplyMessage -
ChatInputCommand -
ThreadStarterMessage -
GuildInviteReminder -
ContextMenuCommand -
AutoModerationAction -
RoleSubscriptionPurchase -
InteractionPremiumUpsell -
StageStart -
StageEnd -
StageSpeaker -
StageTopic -
GuildApplicationPremiumSubscription -
GuildIncidentAlertModeEnabled -
GuildIncidentAlertModeDisabled -
GuildIncidentReportRaid -
GuildIncidentReportFalseAlarm -
PurchaseNotification -
PollResult
The MESSAGE_UPDATE payload, which is NOT a message object: an embed unfurl
sends four keys. message is Some only when a full object arrived.
pub type MessageUpdate {
MessageUpdate(
id: id.Id(id.Message),
channel_id: id.Id(id.Channel),
guild_id: option.Option(id.Id(id.Guild)),
message: option.Option(Message),
raw: dynamic.Dynamic,
)
}
Constructors
-
MessageUpdate( id: id.Id(id.Message), channel_id: id.Id(id.Channel), guild_id: option.Option(id.Id(id.Guild)), message: option.Option(Message), raw: dynamic.Dynamic, )Arguments
- raw
-
The whole payload, for reaching the partial fields.
Discord echoes back whatever was sent, so both exist for reading. Always
SEND a StringNonce: it is a dedup key, and a number can be reinterpreted.
There is no variant for a nonce too big to hold, because this type is also
what a create sends: a lost value has to read as None and omit the key,
not encode as a null Discord would take for an instruction.
pub type Nonce {
StringNonce(String)
IntNonce(Int)
}
Constructors
-
StringNonce(String) -
IntNonce(Int)
Whether the create carries a nonce, and what Discord should do with it.
pub type NoncePolicy {
NoNonce
UseNonce(value: Nonce, enforce: Bool)
}
Constructors
-
NoNonce -
UseNonce(value: Nonce, enforce: Bool)Max 25 characters. Always send a
StringNonce.enforcemakes the create idempotent for a few minutes: a second POST with the same nonce returns the first message instead of posting twice.
pub type PinList {
PinList(items: List(PinnedMessage), has_more: Bool)
}
Constructors
-
PinList(items: List(PinnedMessage), has_more: Bool)
pub type Reaction {
Reaction(
count: Int,
count_details: ReactionCountDetails,
me: Bool,
me_burst: Bool,
emoji: emoji.Emoji,
burst_colors: List(String),
)
}
Constructors
-
Reaction( count: Int, count_details: ReactionCountDetails, me: Bool, me_burst: Bool, emoji: emoji.Emoji, burst_colors: List(String), )Arguments
- count
-
Normal and super reactions added together.
- emoji
-
A PARTIAL emoji, with a null
idfor a unicode reaction. - burst_colors
-
Hex colours for the super-reaction burst, with no leading
#.
pub type ReactionCountDetails {
ReactionCountDetails(burst: Int, normal: Int)
}
Constructors
-
ReactionCountDetails(burst: Int, normal: Int)
The {emoji} in a reaction path. Only ever decoded text, so a value that
is already percent-encoded cannot be handed in and encoded twice.
pub opaque type ReactionEmoji
Discord’s two kinds of reaction, one type for both the gateway events and
the type query parameter on the reactions route. A burst reaction is the
animated “super reaction” a Nitro subscriber can send. A value this build
has no name for fails the decode.
pub type ReactionType {
NormalReaction
BurstReaction
}
Constructors
-
NormalReaction -
BurstReaction
A reply or a forward, sent as message_reference.
pub type Reference {
Reply(
message_id: id.Id(id.Message),
channel_id: option.Option(id.Id(id.Channel)),
guild_id: option.Option(id.Id(id.Guild)),
fail_if_not_exists: Bool,
)
Forward(
message_id: id.Id(id.Message),
channel_id: id.Id(id.Channel),
guild_id: option.Option(id.Id(id.Guild)),
)
}
Constructors
-
Reply( message_id: id.Id(id.Message), channel_id: option.Option(id.Id(id.Channel)), guild_id: option.Option(id.Id(id.Guild)), fail_if_not_exists: Bool, )Arguments
- channel_id
-
Discord infers the current channel when this is
None. - fail_if_not_exists
-
False turns a reply to a deleted message into a plain message rather than a 400. Discord’s own default is true.
-
Forward( message_id: id.Id(id.Message), channel_id: id.Id(id.Channel), guild_id: option.Option(id.Id(id.Guild)), )Only DEFAULT, REPLY, CHAT_INPUT_COMMAND and CONTEXT_MENU_COMMAND messages can be forwarded, and the app has to be able to read the content or Discord answers error code 160014.
Discord’s sticker format table. A value this build has no name for fails the decode.
pub type StickerFormat {
PngSticker
ApngSticker
LottieSticker
GifSticker
}
Constructors
-
PngSticker -
ApngSticker -
LottieSticker -
GifSticker
pub type StickerItem {
StickerItem(
id: id.Id(id.Sticker),
name: String,
format_type: StickerFormat,
)
}
Constructors
-
StickerItem( id: id.Id(id.Sticker), name: String, format_type: StickerFormat, )
Values
pub fn allowed_mentions(
draft: Draft,
policy: mentions.AllowedMentions,
) -> Draft
Without this Discord pings every mention in the content.
pub fn attach(draft: Draft, file: attachment.File) -> Draft
to_body writes the matching attachments entry, so an embed can point
at it with attachment://{filename}.
pub fn bulk_delete(
api: api.Api,
channel: id.Id(id.Channel),
messages: List(id.Id(id.Message)),
) -> Result(Nil, api.CallFailure)
POST /channels/{channel.id}/messages/bulk-delete, as Bulk Delete
Messages. Discord takes 2 to 100 ids and rejects the whole request if any
message is over two weeks old.
pub fn bulk_delete_body(
messages: List(id.Id(id.Message)),
) -> body.Body
POST /channels/{c}/messages/bulk-delete. Two to 100 ids, none older than
14 days, or Discord rejects the whole batch.
pub fn bulk_delete_call(
channel: id.Id(id.Channel),
messages: List(id.Id(id.Message)),
) -> rest.Call(Nil)
The Call for [bulk_delete], for building the request without sending it.
pub fn channel_mention_decoder() -> decode.Decoder(ChannelMention)
pub fn clear_emoji_reactions(
api: api.Api,
msg: Message,
emoji: ReactionEmoji,
) -> Result(Nil, api.CallFailure)
DELETE .../reactions/{emoji}, as Delete All Reactions For Emoji.
pub fn clear_emoji_reactions_call(
msg: Message,
emoji: ReactionEmoji,
) -> rest.Call(Nil)
The Call for [clear_emoji_reactions], for building the request without
sending it.
pub fn clear_emoji_reactions_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
) -> Result(Nil, api.CallFailure)
clear_emoji_reactions for a caller who only has the ids.
pub fn clear_emoji_reactions_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
) -> rest.Call(Nil)
The Call for [clear_emoji_reactions_id], for building the request
without sending it.
pub fn clear_reactions(
api: api.Api,
msg: Message,
) -> Result(Nil, api.CallFailure)
DELETE .../reactions, as Delete All Reactions.
pub fn clear_reactions_call(msg: Message) -> rest.Call(Nil)
The Call for [clear_reactions], for building the request without sending
it.
pub fn clear_reactions_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> Result(Nil, api.CallFailure)
clear_reactions for a caller who only has the ids. Its own bucket, having
no emoji to collapse at.
pub fn clear_reactions_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> rest.Call(Nil)
The Call for [clear_reactions_id], for building the request without
sending it.
pub fn component(
draft: Draft,
component: component.Component,
) -> Draft
One top-level component, so an action row at a time.
pub fn custom_emoji(
emoji: id.Id(id.Emoji),
name: String,
) -> ReactionEmoji
A custom guild emoji, which Discord wants as name:id. The colon is
percent-encoded on the way out, which Discord accepts.
pub fn custom_emoji_by_id(
emoji: id.Id(id.Emoji),
) -> ReactionEmoji
A custom emoji whose name you do not have. Discord reads only the id, so
the name goes out as the literal e.
pub fn decoder() -> decode.Decoder(Message)
pub fn delete(
api: api.Api,
msg: Message,
) -> Result(Nil, api.CallFailure)
DELETE /channels/{channel.id}/messages/{message.id}, as Delete Message.
pub fn delete_call(msg: Message) -> rest.Call(Nil)
The Call for [delete], for building the request without sending it.
pub fn delete_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> Result(Nil, api.CallFailure)
delete for a caller who only has the ids. Discord splits this route into
three buckets by the target’s age and reports none of it in the headers
(discord-api-docs#1092, #1295), so route.Aged carries the age.
pub fn delete_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> rest.Call(Nil)
The Call for [delete_id], for building the request without sending it.
pub fn edit(
api: api.Api,
msg: Message,
edit: Edit,
) -> Result(Message, api.CallFailure)
PATCH /channels/{channel.id}/messages/{message.id}, as Edit Message.
pub fn edit_call(msg: Message, edit: Edit) -> rest.Call(Message)
The Call for edit, for building the request without sending it.
pub fn edit_entries(
edit: Edit,
) -> List(#(String, field.Field(json.Json)))
The edit keys before the absent ones are dropped. Public because the
interaction callback nests the same six keys under data.
pub fn edit_files(edit: Edit) -> List(attachment.File)
The files the multipart body has to carry, in files[n] order.
pub fn edit_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
edit: Edit,
) -> Result(Message, api.CallFailure)
edit for a caller who only has the ids.
pub fn edit_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
edit: Edit,
) -> rest.Call(Message)
The bare Call, for driving glyde/rest yourself.
pub fn embed(draft: Draft, embed: embed.Embed) -> Draft
pub fn flags_field(
value: flags.Flags(MessageFlag),
) -> field.Field(json.Json)
No flags set is an absence, not a zero. Public because a create and an interaction callback both write the key this way.
pub fn forward_of(
draft: Draft,
message_id: id.Id(id.Message),
from channel_id: id.Id(id.Channel),
) -> Draft
Make it a forward. Discord accepts new() |> forward_of(..) on its own: a
forward needs no content.
pub fn get(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> Result(Message, api.CallFailure)
GET /channels/{channel.id}/messages/{message.id}, as Get Channel Message.
pub fn get_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> rest.Call(Message)
The Call for [get], for building the request without sending it.
pub fn has_flag(
bits: flags.Flags(MessageFlag),
flag: MessageFlag,
) -> Bool
pub fn is_deletable(value: MessageType) -> Bool
Whether DELETE /channels/{id}/messages/{id} accepts this message.
pub fn is_from_webhook(message: Message) -> Bool
author.bot is true of ordinary bots too, so it is a different question.
pub fn list(
api: api.Api,
channel: id.Id(id.Channel),
cursor cursor: option.Option(MessageCursor),
limit limit: option.Option(Int),
) -> Result(List(Message), api.CallFailure)
GET /channels/{channel.id}/messages, as Get Channel Messages. None is
no cursor, which Discord reads as the newest messages. Discord caps limit
at 100 and defaults it to 50.
pub fn list_call(
channel: id.Id(id.Channel),
cursor cursor: option.Option(MessageCursor),
limit limit: option.Option(Int),
) -> rest.Call(List(Message))
The Call for [list], for building the request without sending it.
pub fn mention_decoder() -> decode.Decoder(Mention)
The user object is not nested: the spliced member sits beside its keys.
pub fn message_flags(
of chosen: List(MessageFlag),
) -> flags.Flags(MessageFlag)
pub fn message_reference_decoder() -> decode.Decoder(
MessageReference,
)
pub fn message_reference_type_decoder() -> decode.Decoder(
MessageReferenceType,
)
pub fn message_reference_type_from_int(
value: Int,
) -> option.Option(MessageReferenceType)
pub fn message_reference_type_to_int(
value: MessageReferenceType,
) -> Int
pub fn message_reference_type_to_json(
value: MessageReferenceType,
) -> json.Json
pub fn message_type_decoder() -> decode.Decoder(MessageType)
pub fn message_type_from_int(
value: Int,
) -> option.Option(MessageType)
pub fn message_type_to_int(value: MessageType) -> Int
pub fn message_type_to_json(value: MessageType) -> json.Json
pub fn new_edit(mentions: mentions.AllowedMentions) -> Edit
The only Edit constructor: the mention policy is not optional.
pub const no_flags: flags.Flags(MessageFlag)
pub fn nonce_decoder() -> decode.Decoder(option.Option(Nonce))
Total on purpose. wire.integer rejects a number too big to hold exactly,
and decode.optional_field passes that failure up, so without the last
alternative an oversized nonce would sink the whole message. Past 2^53-1
the low digits are already gone, so None is all there is to hand back.
pub fn pin(
api: api.Api,
msg: Message,
) -> Result(Nil, api.CallFailure)
PUT /channels/{channel.id}/messages/pins/{message.id}, as Pin Message.
pub fn pin_call(msg: Message) -> rest.Call(Nil)
The Call for [pin], for building the request without sending it.
pub fn pin_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> Result(Nil, api.CallFailure)
pin for a caller who only has the ids.
pub fn pin_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> rest.Call(Nil)
The Call for [pin_id], for building the request without sending it.
pub fn pin_list_decoder() -> decode.Decoder(PinList)
pub fn pinned_at(pin: PinnedMessage) -> channel.TimeCursor
When a message was pinned. Page on with the oldest entry you just read.
pub fn pinned_message_decoder() -> decode.Decoder(PinnedMessage)
pub fn pins(
api: api.Api,
channel: id.Id(id.Channel),
before before: option.Option(channel.TimeCursor),
limit limit: option.Option(Int),
) -> Result(PinList, api.CallFailure)
GET /channels/{channel.id}/messages/pins, as Get Channel Pins. Each
message wrapped in its pin time; pages backwards through the order they
were pinned in.
pub fn pins_call(
channel: id.Id(id.Channel),
before before: option.Option(channel.TimeCursor),
limit limit: option.Option(Int),
) -> rest.Call(PinList)
The Call for [pins], for building the request without sending it.
pub fn react(
api: api.Api,
msg: Message,
emoji: ReactionEmoji,
) -> Result(Nil, api.CallFailure)
PUT .../reactions/{emoji}/@me, as Create Reaction.
pub fn react_call(
msg: Message,
emoji: ReactionEmoji,
) -> rest.Call(Nil)
The Call for [react], for building the request without sending it.
pub fn react_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
) -> Result(Nil, api.CallFailure)
react for a caller who only has the ids.
pub fn react_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
) -> rest.Call(Nil)
The Call for [react_id], for building the request without sending it.
pub fn reaction_count_details_decoder() -> decode.Decoder(
ReactionCountDetails,
)
pub fn reaction_decoder() -> decode.Decoder(Reaction)
The super-reaction fields are documented as required and are missing from cached or replayed payloads, so they default.
pub fn reaction_emoji(emoji: emoji.Emoji) -> ReactionEmoji
An emoji that came off the wire, from a reaction event or a component.
pub fn reaction_type_decoder() -> decode.Decoder(ReactionType)
pub fn reaction_type_from_int(
value: Int,
) -> option.Option(ReactionType)
pub fn reaction_type_to_int(value: ReactionType) -> Int
pub fn reactions(
api: api.Api,
msg: Message,
emoji: ReactionEmoji,
type_ type_: option.Option(ReactionType),
after after: option.Option(id.Id(id.User)),
limit limit: option.Option(Int),
) -> Result(List(user.User), api.CallFailure)
GET .../reactions/{emoji}, as Get Reactions: the users who reacted.
pub fn reactions_call(
msg: Message,
emoji: ReactionEmoji,
type_ type_: option.Option(ReactionType),
after after: option.Option(id.Id(id.User)),
limit limit: option.Option(Int),
) -> rest.Call(List(user.User))
The Call for [reactions], for building the request without sending it.
pub fn reactions_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
type_ type_: option.Option(ReactionType),
after after: option.Option(id.Id(id.User)),
limit limit: option.Option(Int),
) -> Result(List(user.User), api.CallFailure)
reactions for a caller who only has the ids.
pub fn reactions_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
type_ type_: option.Option(ReactionType),
after after: option.Option(id.Id(id.User)),
limit limit: option.Option(Int),
) -> rest.Call(List(user.User))
The Call for [reactions_id], for building the request without sending it.
pub fn redraft(message: Message) -> Draft
A draft with this message’s content, embeds, components, stickers and
the flags a create may set. Attachments do not carry: a received one is a
URL, a draft’s is bytes. The receive-only parts of an embed (type,
provider, video, proxy urls) come along and are dropped by embed.to_json.
pub fn referenced(message: Message) -> option.Option(Message)
referenced_message collapsed to an Option.
pub fn remove_reaction(
api: api.Api,
msg: Message,
emoji: ReactionEmoji,
user: id.Id(id.User),
) -> Result(Nil, api.CallFailure)
DELETE .../reactions/{emoji}/{user.id}, as Delete User Reaction.
pub fn remove_reaction_call(
msg: Message,
emoji: ReactionEmoji,
user: id.Id(id.User),
) -> rest.Call(Nil)
The Call for [remove_reaction], for building the request without sending
it.
pub fn remove_reaction_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
user: id.Id(id.User),
) -> Result(Nil, api.CallFailure)
remove_reaction for a caller who only has the ids.
pub fn remove_reaction_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
user: id.Id(id.User),
) -> rest.Call(Nil)
The Call for [remove_reaction_id], for building the request without
sending it.
pub fn reply(
api: api.Api,
to: Message,
draft: Draft,
) -> Result(Message, api.CallFailure)
send(api, to.channel_id, draft |> reply_to(to.id)), so Discord shows it
attached to the message rather than as a bare post.
pub fn reply_call(
to: Message,
draft: Draft,
) -> rest.Call(Message)
The Call for reply, for building the request without sending it.
pub fn reply_to(
draft: Draft,
message_id: id.Id(id.Message),
) -> Draft
Make it a reply. fail_if_not_exists stays at Discord’s default, so
replying to a message that has since been deleted is a 400.
pub fn send(
api: api.Api,
channel: id.Id(id.Channel),
draft: Draft,
) -> Result(Message, api.CallFailure)
POST /channels/{channel.id}/messages, as Create Message.
pub fn send_call(
channel: id.Id(id.Channel),
draft: Draft,
) -> rest.Call(Message)
The bare Call, for driving glyde/rest yourself.
pub fn silent(draft: Draft) -> Draft
Delivered without a push or desktop notification, mentions included.
pub fn sticker(draft: Draft, sticker: id.Id(id.Sticker)) -> Draft
Discord takes at most 3.
pub fn sticker_format_from_int(
value: Int,
) -> option.Option(StickerFormat)
pub fn sticker_format_to_int(value: StickerFormat) -> Int
pub fn sticker_item_decoder() -> decode.Decoder(StickerItem)
pub fn suppress_embeds(draft: Draft) -> Draft
No link previews. The other create-time flags are IS_VOICE_MESSAGE and
IS_COMPONENTS_V2; set those on flags directly.
pub fn text(content: String) -> Draft
new() |> content(content), since most messages start with words.
pub fn to_body(draft: Draft) -> body.Body
A ready-to-send body, files already paired to their attachments entries.
pub fn unicode_emoji(text: String) -> ReactionEmoji
A standard emoji, written as the characters themselves: "🔥".
pub fn unpin(
api: api.Api,
msg: Message,
) -> Result(Nil, api.CallFailure)
DELETE /channels/{channel.id}/messages/pins/{message.id}, as Unpin
Message.
pub fn unpin_call(msg: Message) -> rest.Call(Nil)
The Call for [unpin], for building the request without sending it.
pub fn unpin_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> Result(Nil, api.CallFailure)
unpin for a caller who only has the ids.
pub fn unpin_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
) -> rest.Call(Nil)
The Call for [unpin_id], for building the request without sending it.
pub fn unreact(
api: api.Api,
msg: Message,
emoji: ReactionEmoji,
) -> Result(Nil, api.CallFailure)
DELETE .../reactions/{emoji}/@me, as Delete Own Reaction.
pub fn unreact_call(
msg: Message,
emoji: ReactionEmoji,
) -> rest.Call(Nil)
The Call for [unreact], for building the request without sending it.
pub fn unreact_id(
api: api.Api,
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
) -> Result(Nil, api.CallFailure)
unreact for a caller who only has the ids.
pub fn unreact_id_call(
channel: id.Id(id.Channel),
message: id.Id(id.Message),
emoji: ReactionEmoji,
) -> rest.Call(Nil)
The Call for [unreact_id], for building the request without sending it.
pub fn update_decoder() -> decode.Decoder(MessageUpdate)
pub fn with_correlation_nonce(
draft: Draft,
value: Nonce,
) -> Draft
A nonce only for correlating MESSAGE_CREATE back to the create. Discord does not dedupe on it, so a retried POST posts a second message.
pub fn with_flag(
bits: flags.Flags(MessageFlag),
flag: MessageFlag,
) -> flags.Flags(MessageFlag)
pub fn with_nonce(draft: Draft, value: Nonce) -> Draft
A nonce Discord echoes back on MESSAGE_CREATE, enforced, so a retried POST returns the first message rather than posting twice. The safe one is the short name on purpose: a retry is the reason to reach for a nonce at all.
pub fn without_flag(
bits: flags.Flags(MessageFlag),
flag: MessageFlag,
) -> flags.Flags(MessageFlag)