gaato/discord/app does not have a README file

CommandCheck

type CommandCheck = (CheckCtx) -> Bool raise HandlerError

A command guard. Returning false produces HandlerError::CheckFailed; expected denials can instead raise a more specific HandlerError.

ComponentWaiter

type ComponentWaiter = async (String, Int?) ->
ComponentCtx
?

Executor-provided lookup behind wait_for_component: resolves the next component interaction matching a custom id, with an optional timeout in milliseconds.

ErrorPolicy

type ErrorPolicy = async (FailureCtx, Error) -> Unit

Policy invoked for interaction, event, and service failures.

InteractionMiddleware

type InteractionMiddleware = async (InteractionCtx, async () -> Unit) -> Unit

Middleware around interaction dispatch: receives the read-only context and a next continuation. Call next() to continue the chain; skip it (typically after InteractionCtx::respond) to short-circuit the handler.

Spawner

type Spawner = async (async () -> Unit) -> Unit

Executor-provided function that runs a handler task concurrently on the surrounding async runtime.

AppConfigError

pub(all) suberror AppConfigError {
EmptyToken
DuplicateCommand(name~ : String)
DuplicateCommandPath(command~ : String, path~ : String)
NestedSubcommandGroup(command~ : String, path~ : String)
ChoicesWithAutocomplete(command~ : String, path~ : String)
RequiredOptionAfterOptional(command~ : String, path~ : String)
InvalidModalFieldCount(custom_id~ : String, count~ : Int)
DuplicateModalTextInput(custom_id~ : String, field~ : String)
InvalidCooldown(command~ : String, seconds~ : Int)
InvalidMaxInFlight(value~ : Int)
} derive(
Debug
)

Configuration errors detected before starting an application executor.

AppDispatchError

pub(all) suberror AppDispatchError {
Failure(command~ : String, phase~ : ResponsePhase, source~ : Error)
} derive(
Debug
)

A command dispatch failure with its response phase and original cause.

HandlerError

pub(all) suberror HandlerError {
UserMessage(message~ : String, ephemeral~ : Bool)
GuildOnly
DmOnly
CheckFailed
MissingPermission(
Permissions
)
OnCooldown(retry_after_ms~ : Int64)
InvalidArgument(String)
} derive(
Debug
)

Expected command failures that an error policy can present to the user.

Raise these from handlers, checks, or app middleware; the application's ErrorPolicy turns them into user-facing responses. A permission guard computed with @util.channel_permissions typically raises MissingPermission:

test "guard a handler with a permission requirement" {
fn require_send_messages(permissions : @model.Permissions) -> Unit raise {
let required = @model.Permissions::send_messages()
if !permissions.contains(required) {
raise @app.HandlerError::MissingPermission(required)
}
}

try require_send_messages(@model.Permissions::none()) catch {
@app.HandlerError::MissingPermission(_) => ()
other => raise other
} noraise {
_ => fail("expected MissingPermission")
}
}

ModalPrefillError

pub(all) suberror ModalPrefillError {
UnknownCustomId(custom_id~ : String)
NonTextInput(custom_id~ : String)
} derive(
Debug
)

Invalid per-show text-input prefill configuration.

App

pub struct App {
// private fields
}

Gateway-free application declarations shared by gateway and HTTP executors.

App::App

fn App::App(sync? : CommandSync, max_in_flight? : Int) -> App

Create an application core. sync picks the command-sync strategy applied by sync_commands (default: overwrite global commands); max_in_flight caps concurrently running interaction handlers.

App::attach

Wire every registered command, component, modal, and autocomplete route into framework and return the AppCtx shared by handlers. Called by the built-in executors (Bot, the HTTP endpoint); only custom executors need it directly.

App::autocomplete

fn App::autocomplete(self : App, name : String, handler : async (
AutocompleteCtx
) -> Unit) -> Unit

Register a raw autocomplete handler. A raw handler takes precedence over Arg-level suggest handlers registered for the same command name.

App::command

fn[A] App::command(self : App, command : Command[A]) -> Unit

Register a typed slash or context-menu command built with the command / user_command / message_command builders.

App::error_policy

fn App::error_policy(self : App, policy : async (FailureCtx, Error) -> Unit) -> Unit

Replace the error policy invoked when a handler raises. The default policy maps HandlerError variants to ephemeral user-facing messages and warns about everything else.

App::middleware

fn App::middleware(self : App, middleware : async (InteractionCtx, async () -> Unit) -> Unit) -> Unit

Install middleware around every command, component, and modal handler (not autocomplete). First installed is outermost. Runs inside the error policy: raising HandlerError behaves exactly like a failing check.

App::on_component

fn App::on_component(self : App, prefix~ : String, handler : ComponentHandler) -> Unit

Route component interactions whose custom id starts with prefix to handler. Longer prefixes win when several match.

App::on_modal

fn[A] App::on_modal(self : App, modal : Modal[A], handler : ModalSubmitHandler[A]) -> Unit

Route submissions of the typed modal to handler; field values are decoded through the modal's ModalFields before the handler runs.

App::on_modal_raw

fn App::on_modal_raw(self : App, prefix~ : String, handler : async (
ModalCtx
) -> Unit) -> Unit

Register a fully raw modal route without a typed modal definition.

App::on_warn

fn App::on_warn(self : App, hook : (String) -> Unit) -> Unit

Replace the warning hook used for non-fatal diagnostics (default: println).

App::register

fn App::register(self : App, command : RegisteredCommand) -> Unit

Register a type-erased command. App::command is the typed entry point; use this when composing pre-erased commands, e.g. from a plugin.

App::report_failure

async fn App::report_failure(self : App, origin : FailureOrigin, error : Error) -> Unit

Run the error policy for a failure raised outside interaction dispatch. Executors use this for event and service handlers; the policy context has no response target in that case.

App::serve

Build a gateway-free dispatcher.

When client is omitted, the endpoint owns a client created from token and closes it when group finishes. When application_id is omitted, this method always resolves it through GET /applications/@me, including when sync is false. Supplying both values avoids startup HTTP requests when synchronization is disabled.

If sync is true, command synchronization follows the app's CommandSync setting; CommandSync::Disabled still performs no synchronization.

App::spawner

fn App::spawner(self : App, group :
TaskGroup
[Unit]) -> (async (async () -> Unit) -> Unit)

Create a bounded task spawner for an executor-owned task group.

App::sync_commands

Push the declared command set to Discord following the CommandSync strategy chosen at construction: global, one or more guilds, or disabled.

App::validate

fn App::validate(self : App) -> Unit raise AppConfigError

Check declarations for configuration errors: invalid command trees and cooldowns, invalid modal field counts, and duplicate modal text-input ids. Executors call this at startup; call it directly in a test to fail fast.

App::warn

fn App::warn(self : App, message : String) -> Unit

Emit a message through the app's warning hook.

AppCtx

pub struct AppCtx {
// private fields
}

Transport-neutral services available to interaction handlers.

Executors construct these values; the public API exposes read-only accessors.

AppCtx::application_id

The application id learned during startup.

AppCtx::application_ref

The current application bound to its Discord REST client.

AppCtx::http

The Discord REST client used by this application.

AppCtx::latency_ms

fn AppCtx::latency_ms(self : AppCtx) -> Int64?

The latest gateway heartbeat round-trip time in milliseconds. For a multi-shard bot, this is the arithmetic mean of shards that have measured latency. HTTP interaction executors and gateway connections awaiting their first heartbeat acknowledgement return None; use GatewayCtx::latency_ms() when the exact value for one shard is required.

CheckCtx

pub struct CheckCtx {
// private fields
}

Read-only context passed to command checks before argument decoding and handler execution.

CheckCtx::guild_id

The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

CheckCtx::guild_scope

The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

CheckCtx::interaction

The full interaction payload.

CheckCtx::scope

Guild or DM invocation scope, carrying the invoking member or user.

CheckCtx::user

The invoking user.

Command

pub struct Command[A] {
// private fields
}

An application-command definition with a context-aware decoder.

Command::check

fn[A] Command::check(self : Command[A], check : (CheckCtx) -> Bool raise HandlerError) -> Command[A]

Add a pre-execution check. Checks run in registration order before argument decoding. Returning false is equivalent to HandlerError::CheckFailed.

Command::cooldown

fn[A] Command::cooldown(self : Command[A], seconds~ : Int, bucket? : CooldownBucket) -> Command[A]

Apply a fixed-window cooldown to this command. The window starts when all checks pass, before argument decoding and handler execution.

Command::erase

fn[A] Command::erase(self : Command[A]) -> RegisteredCommand

Erase the decoded argument type while retaining registration and dispatch.

Command::spec

The command registration specification.

CommandReply

pub(all) enum CommandReply {
Message(InitialResponse)
ShowModal(ModalHandle)
}

An initial response returned by an immediate command handler.

CommandReply::message

Construct an immediate message reply.

CommandSync

Where application commands are synchronized after the first READY.

ComponentDeferredCtx

pub struct ComponentDeferredCtx {
// private fields
}

Component context available after a deferred callback.

ComponentDeferredCtx::app

The app-level services: the REST client and application id.

ComponentDeferredCtx::custom_id

fn ComponentDeferredCtx::custom_id(self : ComponentDeferredCtx) -> String

The full custom id of the component that fired.

ComponentDeferredCtx::edit_original

Edit the original response after deferring. For DeferredUpdate handlers this edits the component's host message.

ComponentDeferredCtx::followup

Send a followup message after the initial deferred response.

ComponentDeferredCtx::guild_id

The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

ComponentDeferredCtx::guild_scope

The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

ComponentDeferredCtx::interaction

The full interaction payload.

ComponentDeferredCtx::message

The message hosting the component.

ComponentDeferredCtx::raw

Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

ComponentDeferredCtx::scope

Guild or DM invocation scope, carrying the invoking member or user.

ComponentDeferredCtx::selected_channels

Resolved partial channel objects for a channel select.

ComponentDeferredCtx::selected_roles

Resolved role objects for a role or mentionable select.

ComponentDeferredCtx::selected_users

Resolved user objects for a user or mentionable select.

ComponentDeferredCtx::suffix

fn ComponentDeferredCtx::suffix(self : ComponentDeferredCtx) -> String

The custom id with this route's registered prefix stripped (the full id when it does not start with the prefix).

ComponentDeferredCtx::user

The invoking user.

ComponentDeferredCtx::values

fn ComponentDeferredCtx::values(self : ComponentDeferredCtx) -> Array[String]

The raw string values selected in a select menu (empty for buttons).

ComponentDeferredCtx::wait_for_component

async fn ComponentDeferredCtx::wait_for_component(self : ComponentDeferredCtx, custom_id~ : String, timeout_ms? : Int) ->
ComponentCtx
?

Wait for the next component interaction with an exact custom id. Returns None on timeout, or immediately when running without a gateway connection.

ComponentHandler

pub(all) enum ComponentHandler {
Immediate(async (ComponentImmediateCtx) -> ComponentReply)
DeferredUpdate(async (ComponentDeferredCtx) -> Unit)
DeferredMessage(ephemeral~ : Bool, async (ComponentDeferredCtx) -> Unit)
Raw(async (
ComponentCtx
) -> Unit)
}

Execution strategy for a component route.

ComponentImmediateCtx

pub struct ComponentImmediateCtx {
// private fields
}

Read-only component context for handlers returning their initial callback.

ComponentImmediateCtx::app

The app-level services: the REST client and application id.

ComponentImmediateCtx::custom_id

fn ComponentImmediateCtx::custom_id(self : ComponentImmediateCtx) -> String

The full custom id of the component that fired.

ComponentImmediateCtx::guild_id

The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

ComponentImmediateCtx::guild_scope

The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

ComponentImmediateCtx::interaction

The full interaction payload.

ComponentImmediateCtx::message

The message hosting the component.

ComponentImmediateCtx::raw

Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

ComponentImmediateCtx::scope

Guild or DM invocation scope, carrying the invoking member or user.

ComponentImmediateCtx::selected_channels

Resolved partial channel objects for a channel select.

ComponentImmediateCtx::selected_roles

Resolved role objects for a role or mentionable select.

ComponentImmediateCtx::selected_users

Resolved user objects for a user or mentionable select.

ComponentImmediateCtx::suffix

fn ComponentImmediateCtx::suffix(self : ComponentImmediateCtx) -> String

The custom id with this route's registered prefix stripped (the full id when it does not start with the prefix).

ComponentImmediateCtx::user

The invoking user.

ComponentImmediateCtx::values

fn ComponentImmediateCtx::values(self : ComponentImmediateCtx) -> Array[String]

The raw string values selected in a select menu (empty for buttons).

ComponentReply

pub(all) enum ComponentReply {
UpdateMessage(content~ : String?, embeds~ : Array[
Embed
]?, components~ : Array[
Component
]?, allowed_mentions~ :
AllowedMentions
?)
Message(InitialResponse)
ShowModal(ModalHandle)
}

Initial response returned by an immediate component handler.

ComponentReply::message

Reply with a new message; set ephemeral=true to show it only to the invoking user.

ComponentReply::update_message

Reply by editing the message that hosts the component.

CooldownBucket

pub(all) enum CooldownBucket {
User
Guild
Global
} derive(Eq,
Debug
)

Identity used to share a fixed-window command cooldown.

DeferredCtx

pub struct DeferredCtx {
// private fields
}

Command context made available after the initial deferred response.

DeferredCtx::app

fn DeferredCtx::app(self : DeferredCtx) -> AppCtx

The app-level services: the REST client and application id.

DeferredCtx::edit_original

Edit the original response after deferring.

DeferredCtx::followup

Send a followup message after the initial deferred response.

DeferredCtx::guild_id

The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

DeferredCtx::guild_scope

The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

DeferredCtx::interaction

The full interaction payload.

DeferredCtx::raw

Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

DeferredCtx::scope

Guild or DM invocation scope, carrying the invoking member or user.

DeferredCtx::user

The invoking user.

DeferredCtx::wait_for_component

async fn DeferredCtx::wait_for_component(self : DeferredCtx, custom_id~ : String, timeout_ms? : Int) ->
ComponentCtx
?

Wait for the next component interaction with an exact custom id.

FailureCtx

pub struct FailureCtx {
// private fields
}

Context handed to the error policy when a handler fails.

FailureCtx::interaction

The interaction payload associated with this failure. Event and service failures return None.

FailureCtx::origin

fn FailureCtx::origin(self : FailureCtx) -> FailureOrigin

What opened the modal: a component (with its host message) or a command.

FailureCtx::phase

fn FailureCtx::phase(self : FailureCtx) -> ResponsePhase?

How far the response lifecycle progressed before the failure, when an interaction was involved.

FailureCtx::raw

fn FailureCtx::raw(self : FailureCtx) -> FailureRaw?

Access the underlying interaction context. Event and service failures return None. Direct responses through this escape hatch may fail unless the response phase is checked first; normally use respond_error().

FailureCtx::respond_error

async fn FailureCtx::respond_error(self : FailureCtx, content? : String, embeds? : Array[
Embed
], components? : Array[
Component
], files? : Array[
FileUpload
], allowed_mentions? :
AllowedMentions
, ephemeral? : Bool) -> Unit

Send an error without violating Discord's one-initial-response rule. Event and service failures have no response target; those calls are sent to the warning hook instead of guessing a channel.

FailureCtx::user

The user who invoked the failed interaction. Event and service failures return None.

FailureOrigin

pub(all) enum FailureOrigin {
Command(name~ : String)
Autocomplete(name~ : String)
Component(custom_id~ : String)
Modal(custom_id~ : String)
Event(kind~ :
EventKind
)
Service(name~ : String)
} derive(
Debug
)

The operation whose handler failed.

FailureRaw

The underlying interaction context for a failure.

Event and service failures have no raw context. Responding through one of these contexts without first checking the response phase may fail; prefer FailureCtx::respond_error() for ordinary error responses.

ImmediateCtx

pub struct ImmediateCtx {
// private fields
}

Read-only command context for handlers that return their initial response.

ImmediateCtx::app

fn ImmediateCtx::app(self : ImmediateCtx) -> AppCtx

The app-level services: the REST client and application id.

ImmediateCtx::guild_id

The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

ImmediateCtx::guild_scope

The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

ImmediateCtx::interaction

The full interaction payload.

ImmediateCtx::raw

Escape hatch for advanced read-only inspection. Calling response methods on this raw value opts out of the immediate-handler response discipline.

ImmediateCtx::scope

Guild or DM invocation scope, carrying the invoking member or user.

ImmediateCtx::user

The invoking user.

InitialResponse

pub struct InitialResponse {
// private fields
}

A declarative initial message response returned by an immediate handler.

InitialResponse::message

Construct an initial channel-message response.

InteractionCtx

pub struct InteractionCtx {
// private fields
}

Read-only context handed to interaction middleware, before any initial response has been sent.

InteractionCtx::guild_id

The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

InteractionCtx::guild_scope

The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

InteractionCtx::interaction

The full interaction payload.

InteractionCtx::respond

async fn InteractionCtx::respond(self : InteractionCtx, message : String, ephemeral? : Bool) -> Unit

Send the initial response from middleware, short-circuiting the handler.

InteractionCtx::scope

Guild or DM invocation scope, carrying the invoking member or user.

InteractionCtx::target

The routed command, component, or modal being invoked.

InteractionCtx::user

The invoking user.

InteractionEndpoint

pub struct InteractionEndpoint {
// private fields
}

A gateway-free interaction dispatcher backed by a caller-owned task group.

InteractionEndpoint::handle

async fn InteractionEndpoint::handle(self : InteractionEndpoint, body : Json, deadline_ms? : Int) -> Json?

Decode and dispatch an interaction JSON body.

Returns callback JSON only for Reply. Multipart files cannot be expressed by this thin JSON API; callers that accept uploads should use handle_interaction and inspect InteractionOutcome::Reply.files.

InteractionEndpoint::handle_interaction

async fn InteractionEndpoint::handle_interaction(self : InteractionEndpoint, interaction :
Interaction
, deadline_ms? : Int) -> InteractionOutcome

Dispatch one interaction and wait only for its initial response deadline. A timed-out handler remains attached to the app's task group and continues in the background.

InteractionHandler

pub(all) enum InteractionHandler[A] {
Immediate(async (ImmediateCtx, A) -> CommandReply)
Deferred(ephemeral~ : Bool, async (DeferredCtx, A) -> Unit)
Raw(async (
CommandCtx
) -> Unit)
}

Execution strategy for a typed application command.

InteractionOutcome

pub(all) enum InteractionOutcome {
Reply(response~ :
InteractionResponse
, files~ : Array[
FileUpload
]?)
NoRoute
NoResponse
TimedOut
} derive(
Debug
)

The result of dispatching one HTTP-delivered interaction.

InteractionTarget

pub(all) enum InteractionTarget {
Command(name~ : String)
Component(custom_id~ : String)
Modal(custom_id~ : String)
} derive(
Debug
)

The routed target of an interaction entering the middleware chain. Autocomplete, gateway events, and services never pass through it.
pub struct Modal[A] {
// private fields
}

A typed modal definition. The field decoder is retained for the matching on_modal registration while show erases it into a ModalHandle.

Modal::show

fn[A] Modal::show(self : Modal[A], state? : String, values? : Map[String, String]) -> ModalHandle raise ModalPrefillError

Prepare a modal response, optionally appending opaque state after : and overriding text-input defaults by custom_id for this response only. Raises ModalPrefillError when an override key is unknown or does not name a text input.

ModalDeferredCtx

pub struct ModalDeferredCtx {
// private fields
}

Modal-submit context available after a deferred response.

ModalDeferredCtx::app

The app-level services: the REST client and application id.

ModalDeferredCtx::edit_original

Edit the original response after deferring.

ModalDeferredCtx::followup

Send a followup message after the initial deferred response.

ModalDeferredCtx::guild_id

The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

ModalDeferredCtx::guild_scope

The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

ModalDeferredCtx::interaction

The full interaction payload.

ModalDeferredCtx::origin

What opened the modal: a component (with its host message) or a command.

ModalDeferredCtx::raw

Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

ModalDeferredCtx::scope

Guild or DM invocation scope, carrying the invoking member or user.

ModalDeferredCtx::state

fn ModalDeferredCtx::state(self : ModalDeferredCtx) -> String?

The opaque state string passed to Modal::show, if any.

ModalDeferredCtx::user

The invoking user.

ModalField

pub struct ModalField[A] {
// private fields
}

One typed input in a modal form.

ModalField::map

fn[A, B] ModalField::map(self : ModalField[A], f : (A) -> B) -> ModalField[B]

Transform a decoded modal field without changing its emitted component.

ModalField::optional

fn[A] ModalField::optional(self : ModalField[A]) -> ModalField[A?]

Make a modal field optional. Missing and empty submissions decode to None.

ModalField::validate

fn[A] ModalField::validate(self : ModalField[A], check : (A) -> String?) -> ModalField[A]

Validate a decoded field. Returning a message rejects the submission.

ModalField::with_default

fn[A] ModalField::with_default(self : ModalField[A], value : A) -> ModalField[A]

Use a default when a modal field is missing or empty.

ModalFields

pub struct ModalFields[A] {
// private fields
}

A composable collection of typed modal inputs.

ModalFields::map

fn[A, B] ModalFields::map(self : ModalFields[A], f : (A) -> B) -> ModalFields[B]

Transform the decoded value without changing the emitted components.

ModalFields::map1

fn[A, Z] ModalFields::map1(a : ModalField[A], f : (A) -> Z) -> ModalFields[Z]

Build a modal's field set from one field, mapping its decoded value into the handler's argument type.

ModalFields::map2

fn[A, B, Z] ModalFields::map2(a : ModalField[A], b : ModalField[B], f : (A, B) -> Z) -> ModalFields[Z]

Build a modal's field set from two fields, combining their decoded values with the final function argument.

ModalFields::map3

fn[A, B, C, Z] ModalFields::map3(a : ModalField[A], b : ModalField[B], c : ModalField[C], f : (A, B, C) -> Z) -> ModalFields[Z]

Build a modal's field set from three fields, combining their decoded values with the final function argument.

ModalFields::map4

fn[A, B, C, D, Z] ModalFields::map4(a : ModalField[A], b : ModalField[B], c : ModalField[C], d : ModalField[D], f : (A, B, C, D) -> Z) -> ModalFields[Z]

Build a modal's field set from four fields, combining their decoded values with the final function argument.

ModalFields::map5

fn[A, B, C, D, E, Z] ModalFields::map5(a : ModalField[A], b : ModalField[B], c : ModalField[C], d : ModalField[D], e : ModalField[E], f : (A, B, C, D, E) -> Z) -> ModalFields[Z]

Build a modal's field set from five fields, combining their decoded values with the final function argument.

ModalFields::of

fn[A] ModalFields::of(field : ModalField[A]) -> ModalFields[A]

Lift a single field into a ModalFields; combine further with zip and map, or use the mapN helpers directly.

ModalFields::zip

fn[A, B] ModalFields::zip(self : ModalFields[A], other : ModalFields[B]) -> ModalFields[(A, B)]

Concatenate two field sets and pair their decoded values.

ModalHandle

pub struct ModalHandle {
// private fields
}

A type-erased modal response ready to be returned by a command or component handler.

ModalImmediateCtx

pub struct ModalImmediateCtx {
// private fields
}

Read-only modal-submit context for handlers returning an initial message.

ModalImmediateCtx::app

The app-level services: the REST client and application id.

ModalImmediateCtx::guild_id

The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

ModalImmediateCtx::guild_scope

The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

ModalImmediateCtx::interaction

The full interaction payload.

ModalImmediateCtx::origin

What opened the modal: a component (with its host message) or a command.

ModalImmediateCtx::raw

Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

ModalImmediateCtx::scope

Guild or DM invocation scope, carrying the invoking member or user.

ModalImmediateCtx::state

fn ModalImmediateCtx::state(self : ModalImmediateCtx) -> String?

The opaque state string passed to Modal::show, if any.

ModalImmediateCtx::user

The invoking user.

ModalSubmitHandler

pub(all) enum ModalSubmitHandler[A] {
Immediate(async (ModalImmediateCtx, A) -> InitialResponse)
Deferred(ephemeral~ : Bool, async (ModalDeferredCtx, A) -> Unit)
Raw(async (
ModalCtx
) -> Unit)
}

Execution strategy for a typed modal submission.

RegisteredCommand

pub struct RegisteredCommand {
// private fields
}

A type-erased command consumed by an App executor.

RegisteredCommand::name

fn RegisteredCommand::name(self : RegisteredCommand) -> String

The top-level command name used for routing.

ResponsePhase

pub(all) enum ResponsePhase {
BeforeInitial
AfterDeferred
AfterInitial
} derive(Eq,
Debug
)

The response state when an interaction handler failed.

SlashChild

pub struct SlashChild {
// private fields
}

A type-erased slash subcommand or subcommand group.

commands_in_sync

Whether Discord's registered commands already match the declarations.

Command (type, name) pairs must form the same set. For each command, comparison follows the declaration shape recursively, ignoring server-owned fields such as ids and versions while preserving option and choice order.

dm_only

fn dm_only() -> ((CheckCtx) -> Bool raise HandlerError)

Require a direct-message invocation.

guild_only

fn guild_only() -> ((CheckCtx) -> Bool raise HandlerError)

Require a guild invocation.

message_command

Define a MESSAGE context-menu command.
fn[A] modal(custom_id~ : String, title~ : String, fields~ : ModalFields[A]) -> Modal[A]

Define a typed modal.

test "construct and validate a typed modal" {
let feedback = @app.modal(
custom_id="feedback",
title="Feedback",
fields=@app.ModalFields::of(
@app.text_field(custom_id="details", label="Details").optional(),
),
)
let app = @app.App(sync=Disabled)
app.on_modal(feedback, Raw(_ => ()))
app.validate()
let _ : @app.ModalHandle = feedback.show(state="draft")
}

required_permissions

fn required_permissions(required :
Permissions
) -> ((CheckCtx) -> Bool raise HandlerError)

Require effective guild permissions supplied on the interaction member. Discord does not provide member permissions for DM invocations.

select_field

fn select_field(custom_id~ : String, label~ : String, options~ : Array[
SelectOption
], description? : String, placeholder? : String, min_values? : Int, max_values? : Int) -> ModalField[Array[String]]

Define a modern label-wrapped string select.

slash

fn[A] slash(name~ : String, description~ : String, args~ :
Args
[A], handler~ : InteractionHandler[A], default_member_permissions? :
Permissions
, nsfw? : Bool, integration_types? : Array[
ApplicationIntegrationType
], contexts? : Array[
InteractionContextType
], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> Command[A]

Define a typed slash command.

test "inspect a slash-command registration spec" {
let command = @app.slash(
name="echo",
description="Echo text",
args=@interaction.Args::of(
@interaction.arg_string(name="text", description="Text to echo"),
),
handler=Raw(_ => ()),
)
json_inspect(command.spec().to_json(), content={
"name": "echo",
"description": "Echo text",
"options": [
{
"type": 3,
"name": "text",
"description": "Text to echo",
"required": true,
},
],
})
}

slash_group

fn slash_group(name~ : String, description~ : String, children~ : Array[SlashChild], default_member_permissions? :
Permissions
, nsfw? : Bool, integration_types? : Array[
ApplicationIntegrationType
], contexts? : Array[
InteractionContextType
], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> Command[Unit]

Define a slash command whose children dispatch by submitted option path.

subcommand

fn[A] subcommand(name~ : String, description~ : String, args~ :
Args
[A], handler~ : InteractionHandler[A], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> SlashChild

Define a typed slash subcommand.

subcommand_group

fn subcommand_group(name~ : String, description~ : String, children~ : Array[SlashChild], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> SlashChild

Define a slash subcommand group. Nested groups are retained for validation and rejected by App::validate, never by panic or abort here.

text_field

fn text_field(custom_id~ : String, label~ : String, style? :
TextInputStyle
, description? : String, placeholder? : String, min_length? : Int, max_length? : Int, value? : String) -> ModalField[String]

Define a modern label-wrapped text input. value is its static prefill; Modal::show(values=...) can override it for one response.

user_command

Define a USER context-menu command.

test "inspect context-menu command kinds" {
let user = @app.user_command(name="Inspect user", handler=Raw(_ => ()))
let message = @app.message_command(
name="Inspect message",
handler=Raw(_ => ()),
)
json_inspect(user.spec().to_json(), content={
"name": "Inspect user",
"description": "",
"type": 2,
})
json_inspect(message.spec().to_json(), content={
"name": "Inspect message",
"description": "",
"type": 3,
})
}