///|
/// A message sent to a Discord channel.
#derive(ToJson(fields(typ(rename="type"))), FromJson(fields(typ(rename="type"))), Debug)
pub(all) struct Message {
id : MessageId
channel_id : ChannelId
author : User
content : String
timestamp : Timestamp
edited_timestamp : Nullable[Timestamp]
tts : Bool
mention_everyone : Bool
mentions : Array[User]
mention_roles : Array[RoleId]
mention_channels : Array[ChannelMention]?
attachments : Array[Attachment]
embeds : Array[Embed]
reactions : Array[Reaction]?
nonce : Nonce?
pinned : Bool
webhook_id : WebhookId?
typ : MessageType
activity : MessageActivity?
application_id : ApplicationId?
message_reference : MessageReference?
flags : MessageFlags?
referenced_message : Nullable[Message]?
thread : Channel?
components : Array[Component]?
sticker_items : Array[StickerItem]?
position : Int32?
role_subscription_data : RoleSubscriptionData?
poll : Poll?
call : MessageCall?
application : Application?
interaction_metadata : MessageInteractionMetadata?
// Not modeled: the legacy message interaction field is deprecated in favor of interaction_metadata.
resolved : ResolvedData?
message_snapshots : Array[MessageSnapshot]?
// Not modeled: message soundboard_sounds is not in the public documentation.
// Not modeled: full message stickers are deprecated in favor of sticker_items.
shared_client_theme : SharedClientTheme?
}
///|
/// A guild message search response. All fields are optional because Discord
/// returns either completed results or an HTTP 202 indexing response. When
/// `retry_after` is `Some`, the search index was not ready and the caller
/// should retry after that many seconds.
#derive(ToJson, FromJson, Debug)
pub(all) struct GuildMessageSearchResults {
doing_deep_historical_index : Bool?
documents_indexed : Int32?
total_results : Int32?
messages : Array[Array[Message]]?
threads : Array[Channel]?
members : Array[ThreadMember]?
retry_after : Int32?
code : Int32?
message : String?
}
///|
/// Metadata identifying the interaction that produced a message.
///
/// The optional fields cover the documented command, component, and modal
/// variants. `type` determines which subset is present.
#derive(ToJson(fields(typ(rename="type"))), FromJson(fields(typ(rename="type"))), Debug)
pub(all) struct MessageInteractionMetadata {
id : InteractionId
typ : InteractionType
user : User
authorizing_integration_owners : Map[String, String]
original_response_message_id : MessageId?
target_user : User?
target_message_id : MessageId?
interacted_message_id : MessageId?
triggering_interaction_metadata : MessageInteractionMetadata?
}
///|
/// A forwarded message snapshot.
#derive(ToJson, FromJson, Debug)
pub(all) struct MessageSnapshot {
message : MessageSnapshotContent
}
///|
/// The documented subset of a message retained in a forwarded snapshot.
#derive(ToJson(fields(typ(rename="type"))), FromJson(fields(typ(rename="type"))), Debug)
pub(all) struct MessageSnapshotContent {
typ : MessageType?
content : String?
embeds : Array[Embed]?
attachments : Array[Attachment]?
timestamp : Timestamp?
edited_timestamp : Nullable[Timestamp]?
flags : MessageFlags?
mentions : Array[User]?
mention_roles : Array[RoleId]?
sticker_items : Array[StickerItem]?
components : Array[Component]?
}
///|
/// Theme colors shared by an activity-card message.
#derive(ToJson, FromJson, Debug)
pub(all) struct SharedClientTheme {
colors : Array[String]
gradient_angle : Int32
base_mix : Int32
base_theme : Nullable[BaseTheme]?
}
///|
/// The base client theme a `SharedClientTheme` gradient is mixed against.
#derive(Eq, Debug)
#non_exhaustive
pub(all) enum BaseTheme {
Unset
Dark
Light
Darker
Midnight
Unknown(Int32)
}
///|
/// The Discord integer value of this `BaseTheme`.
pub fn BaseTheme::to_int(self : BaseTheme) -> Int32 {
match self {
Unset => 0
Dark => 1
Light => 2
Darker => 3
Midnight => 4
Unknown(value) => value
}
}
///|
/// One entry returned by the paginated channel-pins endpoint.
#derive(ToJson, FromJson, Debug)
pub(all) struct MessagePin {
pinned_at : Timestamp
message : Message
}
///|
/// One page from `GET /channels/{channel.id}/messages/pins`.
#derive(ToJson, FromJson, Debug)
pub(all) struct ChannelPins {
items : Array[MessagePin]
has_more : Bool
}
///|
/// The `BaseTheme` for its Discord integer value; unknown values become `Unknown(n)`.
pub fn BaseTheme::from_int(value : Int32) -> BaseTheme {
match value {
0 => Unset
1 => Dark
2 => Light
3 => Darker
4 => Midnight
value => Unknown(value)
}
}
///|
/// Encodes the `BaseTheme` as its Discord integer value.
pub impl ToJson for BaseTheme with fn to_json(self) {
Json::number(self.to_int().to_double())
}
///|
/// Decodes the `BaseTheme` from a JSON number; unknown values become `Unknown(n)`.
pub impl @json.FromJson for BaseTheme with fn from_json(json, path) {
match json {
Number(value, ..) => BaseTheme::from_int(value.to_int())
_ => raise JsonDecodeError((path, "expected base theme (number)"))
}
}
///|
/// A client nonce represented as either its string or integer wire form.
#derive(Eq, Debug)
pub(all) enum Nonce {
Str(String)
Num(Int64)
}
///|
/// Encodes the nonce as a JSON string or integer, matching its variant.
pub impl ToJson for Nonce with fn to_json(self) {
match self {
Str(value) => Json::string(value)
Num(value) => Json::number(value.to_double(), repr=value.to_string())
}
}
///|
/// Decodes a nonce from a JSON string or integer.
pub impl @json.FromJson for Nonce with fn from_json(json, path) {
match json {
String(value) => Str(value)
Number(_, repr=Some(repr)) =>
Num(
@string.parse_int64(repr.to_string()) catch {
_ =>
raise JsonDecodeError(
(path, "expected a message nonce (integer), got \{repr}"),
)
},
)
Number(value, repr=None) => Num(value.to_int64())
_ =>
raise JsonDecodeError(
(path, "expected a message nonce (string or integer)"),
)
}
}
///|
/// A channel referenced directly in message content.
#derive(ToJson(fields(typ(rename="type"))), FromJson(fields(typ(rename="type"))), Debug)
pub(all) struct ChannelMention {
id : ChannelId
guild_id : GuildId
typ : ChannelType
name : String
}
///|
/// Aggregate reaction state for one emoji on a message.
#derive(ToJson, FromJson, Debug)
pub(all) struct Reaction {
count : Int32
count_details : ReactionCountDetails
me : Bool
me_burst : Bool
emoji : Emoji
burst_colors : Array[String]
}
///|
/// Normal and burst reaction counts for a reaction.
#derive(ToJson, FromJson, Debug)
pub(all) struct ReactionCountDetails {
burst : Int32
normal : Int32
}
///|
/// Whether a reaction is a normal or a burst (super) reaction, as selected
/// by the `type` query parameter of the reaction endpoints.
#derive(Eq, Debug)
#non_exhaustive
pub(all) enum ReactionType {
Normal
Burst
Unknown(Int32)
}
///|
/// The Discord integer value of this `ReactionType`.
pub fn ReactionType::to_int(self : ReactionType) -> Int32 {
match self {
Normal => 0
Burst => 1
Unknown(value) => value
}
}
///|
/// The `ReactionType` for its Discord integer value; unknown values become `Unknown(n)`.
pub fn ReactionType::from_int(value : Int32) -> ReactionType {
match value {
0 => Normal
1 => Burst
value => Unknown(value)
}
}
///|
/// Encodes the `ReactionType` as its Discord integer value.
pub impl ToJson for ReactionType with fn to_json(self) {
Json::number(self.to_int().to_double())
}
///|
/// Decodes the `ReactionType` from a JSON number; unknown values become `Unknown(n)`.
pub impl @json.FromJson for ReactionType with fn from_json(json, path) {
match json {
Number(value, ..) => ReactionType::from_int(value.to_int())
_ => raise JsonDecodeError((path, "expected a reaction type (number)"))
}
}
///|
/// Rich Presence activity metadata attached to a message.
#derive(ToJson(fields(typ(rename="type"))), FromJson(fields(typ(rename="type"))), Debug)
pub(all) struct MessageActivity {
typ : MessageActivityType
party_id : String?
}
///|
/// Origin identifiers and delivery behavior for a message reference.
#derive(ToJson(fields(typ(rename="type"))), FromJson(fields(typ(rename="type"))), Debug)
pub(all) struct MessageReference {
typ : MessageReferenceType?
message_id : MessageId?
channel_id : ChannelId?
guild_id : GuildId?
fail_if_not_exists : Bool?
}
///|
/// Participant and end-time data for a call message.
#derive(ToJson, FromJson, Debug)
pub(all) struct MessageCall {
participants : Array[UserId]
ended_timestamp : Nullable[Timestamp]?
}
///|
/// Subscription tier data attached to a role purchase message.
#derive(ToJson, FromJson, Debug)
pub(all) struct RoleSubscriptionData {
role_subscription_listing_id : SkuId
tier_name : String
total_months_subscribed : Int32
is_renewal : Bool
}
///|
/// The system or user event category represented by a message.
#derive(Eq, Debug)
#non_exhaustive
pub(all) enum MessageType {
Default
RecipientAdd
RecipientRemove
Call
ChannelNameChange
ChannelIconChange
ChannelPinnedMessage
UserJoin
GuildBoost
GuildBoostTier1
GuildBoostTier2
GuildBoostTier3
ChannelFollowAdd
GuildDiscoveryDisqualified
GuildDiscoveryRequalified
GuildDiscoveryGracePeriodInitialWarning
GuildDiscoveryGracePeriodFinalWarning
ThreadCreated
Reply
ChatInputCommand
ThreadStarterMessage
GuildInviteReminder
ContextMenuCommand
AutoModerationAction
RoleSubscriptionPurchase
InteractionPremiumUpsell
StageStart
StageEnd
StageSpeaker
StageRaiseHand
StageTopic
GuildApplicationPremiumSubscription
GuildIncidentAlertModeEnabled
GuildIncidentAlertModeDisabled
GuildIncidentReportRaid
GuildIncidentReportFalseAlarm
PurchaseNotification
PollResult
Unknown(Int32)
}
///|
/// The Discord integer value of this `MessageType`.
pub fn MessageType::to_int(self : MessageType) -> Int32 {
match self {
Default => 0
RecipientAdd => 1
RecipientRemove => 2
Call => 3
ChannelNameChange => 4
ChannelIconChange => 5
ChannelPinnedMessage => 6
UserJoin => 7
GuildBoost => 8
GuildBoostTier1 => 9
GuildBoostTier2 => 10
GuildBoostTier3 => 11
ChannelFollowAdd => 12
GuildDiscoveryDisqualified => 14
GuildDiscoveryRequalified => 15
GuildDiscoveryGracePeriodInitialWarning => 16
GuildDiscoveryGracePeriodFinalWarning => 17
ThreadCreated => 18
Reply => 19
ChatInputCommand => 20
ThreadStarterMessage => 21
GuildInviteReminder => 22
ContextMenuCommand => 23
AutoModerationAction => 24
RoleSubscriptionPurchase => 25
InteractionPremiumUpsell => 26
StageStart => 27
StageEnd => 28
StageSpeaker => 29
StageRaiseHand => 30
StageTopic => 31
GuildApplicationPremiumSubscription => 32
GuildIncidentAlertModeEnabled => 36
GuildIncidentAlertModeDisabled => 37
GuildIncidentReportRaid => 38
GuildIncidentReportFalseAlarm => 39
PurchaseNotification => 44
PollResult => 46
Unknown(value) => value
}
}
///|
/// The `MessageType` for its Discord integer value; unknown values become `Unknown(n)`.
pub fn MessageType::from_int(value : Int32) -> MessageType {
match value {
0 => Default
1 => RecipientAdd
2 => RecipientRemove
3 => Call
4 => ChannelNameChange
5 => ChannelIconChange
6 => ChannelPinnedMessage
7 => UserJoin
8 => GuildBoost
9 => GuildBoostTier1
10 => GuildBoostTier2
11 => GuildBoostTier3
12 => ChannelFollowAdd
14 => GuildDiscoveryDisqualified
15 => GuildDiscoveryRequalified
16 => GuildDiscoveryGracePeriodInitialWarning
17 => GuildDiscoveryGracePeriodFinalWarning
18 => ThreadCreated
19 => Reply
20 => ChatInputCommand
21 => ThreadStarterMessage
22 => GuildInviteReminder
23 => ContextMenuCommand
24 => AutoModerationAction
25 => RoleSubscriptionPurchase
26 => InteractionPremiumUpsell
27 => StageStart
28 => StageEnd
29 => StageSpeaker
30 => StageRaiseHand
31 => StageTopic
32 => GuildApplicationPremiumSubscription
36 => GuildIncidentAlertModeEnabled
37 => GuildIncidentAlertModeDisabled
38 => GuildIncidentReportRaid
39 => GuildIncidentReportFalseAlarm
44 => PurchaseNotification
46 => PollResult
value => Unknown(value)
}
}
///|
/// Encodes the `MessageType` as its Discord integer value.
pub impl ToJson for MessageType with fn to_json(self) {
Json::number(self.to_int().to_double())
}
///|
/// Decodes the `MessageType` from a JSON number; unknown values become `Unknown(n)`.
pub impl @json.FromJson for MessageType with fn from_json(json, path) {
match json {
Number(value, ..) => MessageType::from_int(value.to_int())
_ => raise JsonDecodeError((path, "expected a message type (number)"))
}
}
///|
/// The Rich Presence action represented by a message activity.
#derive(Eq, Debug)
#non_exhaustive
pub(all) enum MessageActivityType {
Join
Spectate
Listen
JoinRequest
StreamRequest
Unknown(Int32)
}
///|
/// The Discord integer value of this `MessageActivityType`.
pub fn MessageActivityType::to_int(self : MessageActivityType) -> Int32 {
match self {
Join => 1
Spectate => 2
Listen => 3
JoinRequest => 5
StreamRequest => 6
Unknown(value) => value
}
}
///|
/// The `MessageActivityType` for its Discord integer value; unknown values become `Unknown(n)`.
pub fn MessageActivityType::from_int(value : Int32) -> MessageActivityType {
match value {
1 => Join
2 => Spectate
3 => Listen
5 => JoinRequest
6 => StreamRequest
value => Unknown(value)
}
}
///|
/// Encodes the `MessageActivityType` as its Discord integer value.
pub impl ToJson for MessageActivityType with fn to_json(self) {
Json::number(self.to_int().to_double())
}
///|
/// Decodes the `MessageActivityType` from a JSON number; unknown values become `Unknown(n)`.
pub impl @json.FromJson for MessageActivityType with fn from_json(json, path) {
match json {
Number(value, ..) => MessageActivityType::from_int(value.to_int())
_ => raise JsonDecodeError((path, "expected a message activity (number)"))
}
}
///|
/// The reference mode used for a reply or forwarded message.
#derive(Eq, Debug)
#non_exhaustive
pub(all) enum MessageReferenceType {
Default
Forward
Unknown(Int32)
}
///|
/// The Discord integer value of this `MessageReferenceType`.
pub fn MessageReferenceType::to_int(self : MessageReferenceType) -> Int32 {
match self {
Default => 0
Forward => 1
Unknown(value) => value
}
}
///|
/// The `MessageReferenceType` for its Discord integer value; unknown values become `Unknown(n)`.
pub fn MessageReferenceType::from_int(value : Int32) -> MessageReferenceType {
match value {
0 => Default
1 => Forward
value => Unknown(value)
}
}
///|
/// Encodes the `MessageReferenceType` as its Discord integer value.
pub impl ToJson for MessageReferenceType with fn to_json(self) {
Json::number(self.to_int().to_double())
}
///|
/// Decodes the `MessageReferenceType` from a JSON number; unknown values become `Unknown(n)`.
pub impl @json.FromJson for MessageReferenceType with fn from_json(json, path) {
match json {
Number(value, ..) => MessageReferenceType::from_int(value.to_int())
_ => raise JsonDecodeError((path, "expected a message reference (number)"))
}
}
///|
/// Bit flags describing delivery and presentation behavior of a message.
#derive(Eq)
pub(all) struct MessageFlags(UInt64)
///|
/// No flags set.
pub fn MessageFlags::none() -> MessageFlags {
MessageFlags(0)
}
///|
/// Flags from a raw bit field; unknown bits are kept.
pub fn MessageFlags::from_bits(bits : UInt64) -> MessageFlags {
MessageFlags(bits)
}
///|
/// The raw bit field.
pub fn MessageFlags::bits(self : MessageFlags) -> UInt64 {
self.0
}
///|
/// Whether every flag in `other` is set.
pub fn MessageFlags::contains(
self : MessageFlags,
other : MessageFlags,
) -> Bool {
(self.0 & other.0) == other.0
}
///|
/// Combines flags: every flag set in either operand is set.
pub impl BitOr for MessageFlags with fn lor(a, b) {
MessageFlags(a.0 | b.0)
}
///|
/// Keeps the flags set in both operands.
pub impl BitAnd for MessageFlags with fn land(a, b) {
MessageFlags(a.0 & b.0)
}
///|
/// Debug output is the raw bit field.
pub impl Debug for MessageFlags with fn to_repr(self) {
Repr(self.0)
}
///|
/// Encodes the flags as a JSON number.
pub impl ToJson for MessageFlags with fn to_json(self) {
Json::number(self.0.to_double(), repr=self.0.to_string())
}
///|
/// Decodes the flags from a JSON number; unknown bits are kept.
pub impl @json.FromJson for MessageFlags with fn from_json(json, path) {
match json {
Number(_, repr=Some(repr)) =>
MessageFlags(
@string.parse_uint64(repr.to_string()) catch {
_ =>
raise JsonDecodeError(
(path, "expected message flags (number), got \{repr}"),
)
},
)
Number(value, repr=None) => MessageFlags(value.to_uint64())
_ => raise JsonDecodeError((path, "expected message flags (number)"))
}
}
///|
/// The message has been published to subscribed channels.
pub fn MessageFlags::crossposted() -> MessageFlags {
MessageFlags(1UL << 0)
}
///|
/// The message originated from a followed channel's announcement.
pub fn MessageFlags::is_crosspost() -> MessageFlags {
MessageFlags(1UL << 1)
}
///|
/// Do not include any embeds when serializing the message.
pub fn MessageFlags::suppress_embeds() -> MessageFlags {
MessageFlags(1UL << 2)
}
///|
/// The source message of this crosspost has been deleted.
pub fn MessageFlags::source_message_deleted() -> MessageFlags {
MessageFlags(1UL << 3)
}
///|
/// The message came from Discord's urgent message system.
pub fn MessageFlags::urgent() -> MessageFlags {
MessageFlags(1UL << 4)
}
///|
/// The message has an associated thread with the same ID as the message.
pub fn MessageFlags::has_thread() -> MessageFlags {
MessageFlags(1UL << 5)
}
///|
/// The message is only visible to the user who invoked the interaction.
pub fn MessageFlags::ephemeral() -> MessageFlags {
MessageFlags(1UL << 6)
}
///|
/// The message is an interaction response that is still deferred ("thinking").
pub fn MessageFlags::loading() -> MessageFlags {
MessageFlags(1UL << 7)
}
///|
/// Some roles mentioned in the message could not be added to the thread.
pub fn MessageFlags::failed_to_mention_some_roles_in_thread() -> MessageFlags {
MessageFlags(1UL << 8)
}
///|
/// Bit `1 << 10`, which Discord sets but does not document.
pub fn MessageFlags::should_show_link_not_discord_warning() -> MessageFlags {
MessageFlags(1UL << 10)
}
///|
/// The message does not trigger push or desktop notifications.
pub fn MessageFlags::suppress_notifications() -> MessageFlags {
MessageFlags(1UL << 12)
}
///|
/// The message is a voice message.
pub fn MessageFlags::is_voice_message() -> MessageFlags {
MessageFlags(1UL << 13)
}
///|
/// The message carries a snapshot of a forwarded message.
pub fn MessageFlags::has_snapshot() -> MessageFlags {
MessageFlags(1UL << 14)
}
///|
/// The message uses the components V2 layout instead of content and embeds.
pub fn MessageFlags::is_components_v2() -> MessageFlags {
MessageFlags(1UL << 15)
}