glyde/interaction
Interactions: what arrives when someone runs a command, presses a button or types into an autocomplete box.
data is decoded on the envelope’s type, never on the shape of data:
command (2) and autocomplete (4) send identical objects, so shape sniffing
answers an autocomplete keystroke with a message per letter.
A type this build has no name for fails the decode, so it reaches
on_status as Undecodable rather than the handler as an Option to
unwrap. A PING carries five keys, which is why most other “required”
fields are optional here.
Types
One entry of authorizing_integration_owners. A guild install invoked in
the app’s own DM has no guild to name, and Discord says so with a sentinel
rather than by leaving the entry out.
pub type AuthorizingOwner {
OwnedBy(String)
NoOwner
}
Constructors
-
OwnedBy(String)A snowflake: a guild id under
GuildInstall, a user id underUserInstall. -
NoOwner
What the component sent back, one variant per component_type. Discord
writes every submission as the same values array of strings, so this is
what says whether reading it means anything and what the strings are.
pub type ComponentSubmission {
ButtonPress
StringSelect(values: List(String))
UserSelect(users: List(id.Id(id.User)))
RoleSelect(roles: List(id.Id(id.Role)))
MentionableSelect(mentions: List(Mentionable))
ChannelSelect(channels: List(id.Id(id.Channel)))
}
Constructors
-
ButtonPressType 2. A button submits nothing but its
custom_id. -
StringSelect(values: List(String))Type 3. The
valueof each chosen option, not its label. -
Type 5.
-
Type 6.
-
MentionableSelect(mentions: List(Mentionable))Type 7. Users and roles come back in one list. An id in neither
resolvedmap is dropped, since nothing says which it is. -
ChannelSelect(channels: List(id.Id(id.Channel)))Type 8.
A key of authorizing_integration_owners, which arrives as a JSON object
key: the string “0” or “1”. Its own type rather than
ApplicationIntegrationType so an unparseable key never reaches
integration_types on a command create, where it would send garbage.
pub type IntegrationOwnerKey {
KnownIntegration(
application_command.ApplicationIntegrationType,
)
UnparsedIntegrationKey(String)
}
Constructors
-
KnownIntegration(application_command.ApplicationIntegrationType) -
UnparsedIntegrationKey(String)A key that was not a number at all. Keeps the raw text so two of them stay two entries; one shared sentinel would drop every one but the last.
pub type Interaction {
Interaction(
id: id.Id(id.Interaction),
application_id: id.Id(id.Application),
type_: InteractionType,
data: InteractionData,
guild: option.Option(InteractionGuild),
guild_id: option.Option(id.Id(id.Guild)),
channel: option.Option(channel.Channel),
channel_id: option.Option(id.Id(id.Channel)),
member: option.Option(member.GuildMember),
user: option.Option(user.User),
token: InteractionToken,
version: Int,
message: option.Option(message.Message),
app_permissions: option.Option(permissions.Effective),
locale: option.Option(String),
guild_locale: option.Option(String),
authorizing_integration_owners: dict.Dict(
IntegrationOwnerKey,
AuthorizingOwner,
),
context: option.Option(
application_command.InteractionContextType,
),
attachment_size_limit: option.Option(Int),
)
}
Constructors
-
Interaction( id: id.Id(id.Interaction), application_id: id.Id(id.Application), type_: InteractionType, data: InteractionData, guild: option.Option(InteractionGuild), guild_id: option.Option(id.Id(id.Guild)), channel: option.Option(channel.Channel), channel_id: option.Option(id.Id(id.Channel)), member: option.Option(member.GuildMember), user: option.Option(user.User), token: InteractionToken, version: Int, message: option.Option(message.Message), app_permissions: option.Option(permissions.Effective), locale: option.Option(String), guild_locale: option.Option(String), authorizing_integration_owners: dict.Dict( IntegrationOwnerKey, AuthorizingOwner, ), context: option.Option( application_command.InteractionContextType, ), attachment_size_limit: option.Option(Int), )Arguments
- type_
-
Selects which
datavariant you get. Match ondata, not on this. - data
-
NoDatafor a PING, not anOption, so a handler writes onecase. - guild_id
-
Absent, not null, in DMs.
- channel
-
A PARTIAL channel: assume only
idandtype_are populated. - channel_id
-
Absent on a PING.
- member
-
Present only in a guild, where
member.useris the invoking user. - user
-
Present only in a DM. Use
invoking_userto get either. - token
-
Valid 15 minutes, first response due in 3 seconds. Hand it to
responding_torather than reading it out. - version
-
Always 1.
- message
-
The message a component was attached to.
- app_permissions
-
What the APP may do here, not what the user may do. Absent on a PING.
- authorizing_integration_owners
-
Who installed the app, one entry per install type it ran under. Empty on a PING.
authorizing_guild_idandauthorizing_user_idread it as typed ids. - attachment_size_limit
-
Bytes. Absent on a PING.
pub type InteractionCallback {
InteractionCallback(
id: id.Id(id.Interaction),
type_: InteractionType,
response_message_id: option.Option(id.Id(id.Message)),
response_message_loading: option.Option(Bool),
response_message_ephemeral: option.Option(Bool),
)
}
Constructors
-
InteractionCallback( id: id.Id(id.Interaction), type_: InteractionType, response_message_id: option.Option(id.Id(id.Message)), response_message_loading: option.Option(Bool), response_message_ephemeral: option.Option(Bool), )Arguments
- response_message_id
-
The message your response created. Absent for a deferred response and for autocomplete.
pub type InteractionCallbackResource {
InteractionCallbackResource(
type_: InteractionCallbackType,
message: option.Option(message.Message),
)
}
Constructors
-
InteractionCallbackResource( type_: InteractionCallbackType, message: option.Option(message.Message), )Arguments
- message
-
Only for CHANNEL_MESSAGE_WITH_SOURCE and UPDATE_MESSAGE.
The body of POST …/callback?with_response=true. Without that parameter
the route answers 204.
pub type InteractionCallbackResponse {
InteractionCallbackResponse(
interaction: InteractionCallback,
resource: option.Option(InteractionCallbackResource),
)
}
Constructors
-
InteractionCallbackResponse( interaction: InteractionCallback, resource: option.Option(InteractionCallbackResource), )
The numbering skips 11, so never index this by position. A value this build has no name for fails the decode.
pub type InteractionCallbackType {
PongCallback
ChannelMessageWithSourceCallback
DeferredChannelMessageWithSourceCallback
DeferredUpdateMessageCallback
UpdateMessageCallback
AutocompleteResultCallback
ModalCallback
PremiumRequiredCallback
LaunchActivityCallback
}
Constructors
-
PongCallback -
ChannelMessageWithSourceCallback -
DeferredChannelMessageWithSourceCallback -
DeferredUpdateMessageCallback -
UpdateMessageCallback -
AutocompleteResultCallback -
ModalCallback -
PremiumRequiredCallbackDeprecated by Discord.
-
LaunchActivityCallbackActivities.
pub type InteractionData {
CommandData(
id: id.Id(id.Command),
name: String,
type_: application_command.ApplicationCommandType,
resolved: ResolvedData,
options: List(InteractionOption),
guild_id: option.Option(id.Id(id.Guild)),
target_id: option.Option(String),
)
AutocompleteData(
id: id.Id(id.Command),
name: String,
type_: application_command.ApplicationCommandType,
options: List(InteractionOption),
guild_id: option.Option(id.Id(id.Guild)),
)
ComponentData(
custom_id: String,
submission: option.Option(ComponentSubmission),
resolved: ResolvedData,
)
NoData
}
Constructors
-
CommandData( id: id.Id(id.Command), name: String, type_: application_command.ApplicationCommandType, resolved: ResolvedData, options: List(InteractionOption), guild_id: option.Option(id.Id(id.Guild)), target_id: option.Option(String), )Type 2. A slash command or a context-menu command.
Arguments
- name
-
The top-level command name only. Subcommand names live in
options. - resolved
-
Absent
resolveddecodes to an empty one, so noOptionto unwrap. - guild_id
-
Where the command is REGISTERED, not where it was invoked.
- target_id
-
A user id for USER commands, a message id for MESSAGE ones. Read it through
target_user_idandtarget_message_id.
-
AutocompleteData( id: id.Id(id.Command), name: String, type_: application_command.ApplicationCommandType, options: List(InteractionOption), guild_id: option.Option(id.Id(id.Guild)), )Type 4. Byte-identical to
CommandDataon the wire and a different thing to answer.optionsis partial, and the one being typed hasfocused. -
ComponentData( custom_id: String, submission: option.Option(ComponentSubmission), resolved: ResolvedData, )Type 3. A button press or a select submission.
Arguments
- submission
-
What was submitted, tagged by the component that sent it. A button press carries nothing, so there is no empty
valuesto read.Nonefor a component type this build does not model.
-
NoDataType 1 (PING) and type 5 (MODAL_SUBMIT). The envelope’s id and token are still there for a caller to answer “unsupported”.
One parameter of an invoked command. Nests at most three deep: group, subcommand, then the value-bearing options.
pub type InteractionOption {
InteractionOption(
name: String,
type_: option.Option(
application_command.ApplicationCommandOptionType,
),
value: OptionValue,
options: List(InteractionOption),
focused: Bool,
)
}
Constructors
-
InteractionOption( name: String, type_: option.Option( application_command.ApplicationCommandOptionType, ), value: OptionValue, options: List(InteractionOption), focused: Bool, )Arguments
- type_
-
Nonefor a value this build has no name for. - value
-
NoValuefor subcommands and groups, which carryoptionsinstead, and for an autocomplete option not yet typed. - options
-
Empty unless this is a subcommand or a subcommand group.
- focused
-
True on the option the user is typing. Autocomplete only.
Send-only, so no unknown tail.
pub type InteractionResponse {
Pong
ChannelMessageWithSource(MessageCallbackData)
DeferredChannelMessageWithSource(ephemeral: Bool)
DeferredUpdateMessage
UpdateMessage(message.Edit)
AutocompleteResult(
choices: List(
application_command.ApplicationCommandOptionChoice(
application_command.ChoiceValue,
),
),
)
}
Constructors
-
PongACK a PING. A gateway bot never sends this; an HTTP-interactions bot that cannot send it can never register its endpoint.
-
ChannelMessageWithSource(MessageCallbackData)Reply with a new message. Create semantics.
-
DeferredChannelMessageWithSource(ephemeral: Bool)“Thinking…”. Turns the three-second budget into fifteen minutes; finish with
PATCH /webhooks/{app}/{token}/messages/@original. EPHEMERAL is the only flag accepted, henceBool. -
DeferredUpdateMessageComponents only. ACK with no loading state, and no data at all.
-
UpdateMessage(message.Edit)Components only. Edit semantics:
Present([])takes the components off the message. Field for field and key for key this is a message edit, so it carries the same type, built withupdate_data. -
AutocompleteResult( choices: List( application_command.ApplicationCommandOptionChoice( application_command.ChoiceValue, ), ), )Autocomplete only. An empty list is legal and means no suggestions. Max 25.
ChoiceValuebecause the option being typed is only known at runtime, so this response cannot be tied to one value type.
The credential half of an interaction: this plus the id answers as the bot
for fifteen minutes with no Authorization header. Opaque and with no
to_string, so echo interaction cannot spill it. A closure, not a field,
because string.inspect ignores opaqueness.
pub opaque type InteractionToken
A value this build has no name for fails the decode.
pub type InteractionType {
PingInteraction
ApplicationCommandInteraction
MessageComponentInteraction
AutocompleteInteraction
ModalSubmitInteraction
}
Constructors
-
PingInteractionHTTP interactions only. Never arrives over the gateway.
-
ApplicationCommandInteraction -
MessageComponentInteraction -
AutocompleteInteraction -
ModalSubmitInteractionIts data is not modelled, so
datadecodes asNoData.
Callback data for ChannelMessageWithSource. Same shape and rules as
Draft.
pub type MessageCallbackData {
MessageCallbackData(
content: option.Option(String),
tts: Bool,
embeds: List(embed.Embed),
components: List(component.Component),
files: List(attachment.File),
allowed_mentions: option.Option(mentions.AllowedMentions),
flags: flags.Flags(message.MessageFlag),
)
}
Constructors
-
MessageCallbackData( content: option.Option(String), tts: Bool, embeds: List(embed.Embed), components: List(component.Component), files: List(attachment.File), allowed_mentions: option.Option(mentions.AllowedMentions), flags: flags.Flags(message.MessageFlag), )Arguments
- allowed_mentions
-
A decision, never a default: leaving it out lets Discord turn every @mention in the content into a real ping.
- flags
-
Only EPHEMERAL, SUPPRESS_EMBEDS, SUPPRESS_NOTIFICATIONS, IS_VOICE_MESSAGE and IS_COMPONENTS_V2 are accepted. Prefer
ephemeralto assembling this by hand.
The snowflake option types arrive as a StringValue holding the id. Look
it up in resolved, or use the typed accessors below.
pub type OptionValue {
StringValue(String)
IntValue(Int)
FloatValue(Float)
BoolValue(Bool)
NoValue
}
Constructors
-
StringValue(String) -
IntValue(Int) -
FloatValue(Float) -
BoolValue(Bool) -
NoValueThe
valuekey was absent, or was present and not a string, number or bool.
Narrower than Channel except for permissions, the invoking user’s
computed permissions, which a Channel decode would drop.
pub type ResolvedChannel {
ResolvedChannel(
id: id.Id(id.Channel),
type_: channel.ChannelType,
name: option.Option(String),
permissions: option.Option(permissions.Effective),
parent_id: option.Option(id.Id(id.Channel)),
thread_metadata: option.Option(channel.ThreadMetadata),
)
}
Constructors
-
ResolvedChannel( id: id.Id(id.Channel), type_: channel.ChannelType, name: option.Option(String), permissions: option.Option(permissions.Effective), parent_id: option.Option(id.Id(id.Channel)), thread_metadata: option.Option(channel.ThreadMetadata), )Arguments
- thread_metadata
-
Present when the resolved channel is a thread.
Everything the user picked, already fetched. Absent maps decode to empty.
pub type ResolvedData {
ResolvedData(
users: dict.Dict(id.Id(id.User), user.User),
members: dict.Dict(id.Id(id.User), member.GuildMember),
roles: dict.Dict(id.Id(id.Role), role.Role),
channels: dict.Dict(id.Id(id.Channel), ResolvedChannel),
messages: dict.Dict(id.Id(id.Message), message.Message),
attachments: dict.Dict(
id.Id(id.Attachment),
attachment.Attachment,
),
)
}
Constructors
-
ResolvedData( users: dict.Dict(id.Id(id.User), user.User), members: dict.Dict(id.Id(id.User), member.GuildMember), roles: dict.Dict(id.Id(id.Role), role.Role), channels: dict.Dict(id.Id(id.Channel), ResolvedChannel), messages: dict.Dict(id.Id(id.Message), message.Message), attachments: dict.Dict( id.Id(id.Attachment), attachment.Attachment, ), )Arguments
- members
-
Partial: no
user,deaformute. The id is already the map key. - messages
-
Only ever populated for MESSAGE context-menu commands.
- attachments
-
Never populated for message components.
Values
pub fn attachment_option(
options: List(InteractionOption),
name: String,
) -> option.Option(id.Id(id.Attachment))
pub fn authorizing_guild_id(
interaction: Interaction,
) -> option.Option(id.Id(id.Guild))
The guild that installed the app, when the interaction ran under a guild
install. None in a bot DM, where Discord sends the sentinel instead.
pub fn authorizing_user_id(
interaction: Interaction,
) -> option.Option(id.Id(id.User))
The user who installed the app, when the interaction ran under a user install.
pub fn bool_option(
options: List(InteractionOption),
name: String,
) -> option.Option(Bool)
pub fn callback(
api: api.Api,
responder: Responder,
response: InteractionResponse,
) -> Result(Nil, api.CallFailure)
POST /interactions/{interaction.id}/{token}/callback, the first answer.
Answers 204: use callback_with_response if you need the message id.
pub fn callback_call(
responder: Responder,
response: InteractionResponse,
) -> rest.Call(Nil)
The Call for [callback], for building the request without sending it.
pub fn callback_decoder() -> decode.Decoder(InteractionCallback)
pub fn callback_resource_decoder() -> decode.Decoder(
InteractionCallbackResource,
)
pub fn callback_response_decoder() -> decode.Decoder(
InteractionCallbackResponse,
)
pub fn callback_type(
response: InteractionResponse,
) -> InteractionCallbackType
The callback type Discord reads off the envelope. Shares its numbering
with callback_type_from_int, so encode and decode use one table.
pub fn callback_type_decoder() -> decode.Decoder(
InteractionCallbackType,
)
pub fn callback_type_from_int(
value: Int,
) -> option.Option(InteractionCallbackType)
pub fn callback_type_to_int(
value: InteractionCallbackType,
) -> Int
pub fn callback_type_to_json(
value: InteractionCallbackType,
) -> json.Json
pub fn callback_with_response(
api: api.Api,
responder: Responder,
response: InteractionResponse,
) -> Result(InteractionCallbackResponse, api.CallFailure)
POST /interactions/{interaction.id}/{token}/callback?with_response=true,
answering 200 with the callback resource instead of 204.
pub fn callback_with_response_call(
responder: Responder,
response: InteractionResponse,
) -> rest.Call(InteractionCallbackResponse)
The Call for [callback_with_response], for building the request without
sending it.
pub fn channel_option(
options: List(InteractionOption),
name: String,
) -> option.Option(id.Id(id.Channel))
pub fn create_followup(
api: api.Api,
responder: Responder,
body: body.Body,
) -> Result(message.Message, api.CallFailure)
POST /webhooks/{application.id}/{token}?wait=true, an extra message on
the same interaction. Capped at five when the app is user-installed and not
a member of the server, 40094 past that.
pub fn create_followup_call(
responder: Responder,
body: body.Body,
) -> rest.Call(message.Message)
The Call for [create_followup], for building the request without sending
it.
pub fn data_decoder(
interaction_type: InteractionType,
) -> decode.Decoder(InteractionData)
The envelope’s type picks the decoder. A type whose data this build does
not model gives NoData, so the envelope’s id and token are still there.
pub fn decoder() -> decode.Decoder(Interaction)
pub fn defer(
api: api.Api,
interaction: Interaction,
) -> Result(Nil, api.CallFailure)
Show “thinking…” and buy fifteen minutes. Callback type 5. Send within
three seconds, then finish with edit_response. The reply is public: the
eventual edit cannot make it ephemeral, so pick defer_ephemeral now if
only the invoker should see it.
pub fn defer_call(interaction: Interaction) -> rest.Call(Nil)
The Call for [defer], for building the request without sending it.
pub fn defer_ephemeral(
api: api.Api,
interaction: Interaction,
) -> Result(Nil, api.CallFailure)
defer with the reply visible only to the invoker. Fixed at defer time:
the eventual edit_response cannot change it back to public.
pub fn defer_ephemeral_call(
interaction: Interaction,
) -> rest.Call(Nil)
The Call for [defer_ephemeral], for building the request without sending
it.
pub fn delete_followup(
api: api.Api,
responder: Responder,
message: id.Id(id.Message),
) -> Result(Nil, api.CallFailure)
DELETE /webhooks/{application.id}/{token}/messages/{message.id}.
pub fn delete_followup_call(
responder: Responder,
message: id.Id(id.Message),
) -> rest.Call(Nil)
The Call for [delete_followup], for building the request without sending
it.
pub fn delete_original_response(
api: api.Api,
responder: Responder,
) -> Result(Nil, api.CallFailure)
DELETE /webhooks/{application.id}/{token}/messages/@original, which
works on an ephemeral response as well.
pub fn delete_original_response_call(
responder: Responder,
) -> rest.Call(Nil)
The Call for [delete_original_response], for building the request
without sending it.
pub fn edit_followup(
api: api.Api,
responder: Responder,
message: id.Id(id.Message),
body: body.Body,
) -> Result(message.Message, api.CallFailure)
PATCH /webhooks/{application.id}/{token}/messages/{message.id}.
pub fn edit_followup_call(
responder: Responder,
message: id.Id(id.Message),
body: body.Body,
) -> rest.Call(message.Message)
The Call for [edit_followup], for building the request without sending
it.
pub fn edit_original_response(
api: api.Api,
responder: Responder,
body: body.Body,
) -> Result(message.Message, api.CallFailure)
PATCH /webhooks/{application.id}/{token}/messages/@original. Turns a
deferred response into a real one, and edits one already sent.
pub fn edit_original_response_call(
responder: Responder,
body: body.Body,
) -> rest.Call(message.Message)
The Call for [edit_original_response], for building the request without
sending it.
pub fn edit_response(
api: api.Api,
interaction: Interaction,
edit: message.Edit,
) -> Result(message.Message, api.CallFailure)
Turn a deferred response into a real one, or edit one already sent.
PATCH /webhooks/{application.id}/{token}/messages/@original.
pub fn edit_response_call(
interaction: Interaction,
edit: message.Edit,
) -> rest.Call(message.Message)
The Call for [edit_response], for building the request without sending
it.
pub fn empty_resolved() -> ResolvedData
pub fn ephemeral(
data: MessageCallbackData,
) -> MessageCallbackData
Only the invoking user sees it.
pub fn find_option(
options: List(InteractionOption),
name: String,
) -> option.Option(InteractionOption)
A named parameter of the command the user actually invoked. Descends
through subcommands first, so /config set key:red finds key from the
top-level options, the same depth focused_option reads at. A group or a
subcommand is not a parameter and is not found here: subcommand_path
returns those names.
pub fn float_option(
options: List(InteractionOption),
name: String,
) -> option.Option(Float)
pub fn focused_option(
options: List(InteractionOption),
) -> option.Option(InteractionOption)
The option being typed, during autocomplete. Descends into subcommands:
/config set key:<typing> is two levels down.
pub fn followup(
api: api.Api,
interaction: Interaction,
draft: message.Draft,
) -> Result(message.Message, api.CallFailure)
A second message on the same interaction, after respond or defer has
answered it. POST /webhooks/{application.id}/{token}?wait=true.
pub fn followup_call(
interaction: Interaction,
draft: message.Draft,
) -> rest.Call(message.Message)
The Call for [followup], for building the request without sending it.
pub fn from_draft(draft: message.Draft) -> MessageCallbackData
A Draft as callback data, so message.text and its setters build an
interaction reply as well as a channel post. sticker_ids, reference and
nonce are dropped: an interaction response is not a channel create, and
Discord takes none of them here.
pub fn get_followup(
api: api.Api,
responder: Responder,
message: id.Id(id.Message),
) -> Result(message.Message, api.CallFailure)
GET /webhooks/{application.id}/{token}/messages/{message.id}.
pub fn get_followup_call(
responder: Responder,
message: id.Id(id.Message),
) -> rest.Call(message.Message)
The Call for [get_followup], for building the request without sending it.
pub fn get_original_response(
api: api.Api,
responder: Responder,
) -> Result(message.Message, api.CallFailure)
GET /webhooks/{application.id}/{token}/messages/@original.
pub fn get_original_response_call(
responder: Responder,
) -> rest.Call(message.Message)
The Call for [get_original_response], for building the request without
sending it.
pub const initial_response_ms: Int
Discord’s deadline for the first response to an interaction.
pub fn int_option(
options: List(InteractionOption),
name: String,
) -> option.Option(Int)
pub fn interaction_guild_decoder() -> decode.Decoder(
InteractionGuild,
)
pub fn interaction_token(raw: String) -> InteractionToken
For a token that did not come through this decoder: an HTTP-interactions endpoint reading it out of its own request, or one kept across a restart.
pub fn interaction_type_decoder() -> decode.Decoder(
InteractionType,
)
pub fn interaction_type_from_int(
value: Int,
) -> option.Option(InteractionType)
pub fn interaction_type_to_int(value: InteractionType) -> Int
pub fn interaction_type_to_json(
value: InteractionType,
) -> json.Json
pub fn invoking_user(
interaction: Interaction,
) -> option.Option(user.User)
In a guild the user is at member.user, in a DM at user.
pub fn mentionable_option(
options: List(InteractionOption),
name: String,
resolved: ResolvedData,
) -> option.Option(Mentionable)
The one snowflake accessor that reads a MENTIONABLE, because the resolved
that says user or role is handed to it. Take it off the same CommandData
the options came from.
pub fn message_data() -> MessageCallbackData
pub fn message_data_to_json(
data: MessageCallbackData,
) -> json.Json
pub fn option_decoder() -> decode.Decoder(InteractionOption)
pub fn remaining_response_budget_ms(
interaction: Interaction,
now_ms now_ms: Int,
) -> Int
Milliseconds left for the first response, counted from the interaction’s snowflake and not from receipt. 0 once closed, and 0 for a non-snowflake.
pub fn resolved_channel_decoder() -> decode.Decoder(
ResolvedChannel,
)
pub fn resolved_decoder() -> decode.Decoder(ResolvedData)
pub fn respond(
api: api.Api,
interaction: Interaction,
draft: message.Draft,
) -> Result(Nil, api.CallFailure)
Reply with a message. Callback type 4. The first response owed within
three seconds; past that Discord drops the interaction and this call
answers 404. defer first if the reply takes longer to build.
pub fn respond_call(
interaction: Interaction,
draft: message.Draft,
) -> rest.Call(Nil)
The bare Call, for driving glyde/rest yourself.
pub fn responder(
interaction interaction: id.Id(id.Interaction),
application application: id.Id(id.Application),
token token: InteractionToken,
) -> Responder
The HTTP-interactions path, and a token kept somewhere across a restart.
Prefer responding_to where there is an Interaction to hand.
pub fn responding_to(interaction: Interaction) -> Responder
The gateway path. Everything comes off the one INTERACTION_CREATE, so the three cannot disagree.
pub fn response_body(response: InteractionResponse) -> body.Body
A ready-to-send body for the callback route, files already paired to their
attachments entries. callback calls this for you; an HTTP-interactions
bot writing straight to its own HTTP response uses it directly.
The callback nests its attachments array under data, so the document is
finished here rather than left open: a top-level array as well would name
the same parts twice, and the copy without the kept ones deletes them.
pub fn response_files(
response: InteractionResponse,
) -> List(attachment.File)
The files the multipart body has to carry, in files[n] order.
pub fn response_to_json(
response: InteractionResponse,
) -> json.Json
pub fn role_option(
options: List(InteractionOption),
name: String,
) -> option.Option(id.Id(id.Role))
MENTIONABLE is not accepted, for the reason user_option gives.
pub fn string_option(
options: List(InteractionOption),
name: String,
) -> option.Option(String)
pub fn subcommand_path(
options: List(InteractionOption),
) -> #(List(String), List(InteractionOption))
Flatten /group sub key:value to #(["group", "sub"], [the key option]).
pub fn target_message_id(
data: InteractionData,
) -> option.Option(id.Id(id.Message))
pub fn target_user_id(
data: InteractionData,
) -> option.Option(id.Id(id.User))
pub fn text(content: String) -> MessageCallbackData
pub fn update_data(
mentions: mentions.AllowedMentions,
) -> message.Edit
Same as message.new_edit: the mention policy is not optional.
pub fn update_data_to_json(data: message.Edit) -> json.Json
pub fn user_option(
options: List(InteractionOption),
name: String,
) -> option.Option(id.Id(id.User))
MENTIONABLE is not accepted here: only resolved says whether its id is a
user or a role, so reading one as a user is a coin flip. Read one with
mentionable_option, which takes the resolved that settles it.