gaato/discord/app does not have a README file

    CommandCheck

    type CommandCheck = async (CheckCtx) -> Bool

    A command guard. Returning false produces HandlerError::CheckFailed; raise a more specific HandlerError for an expected denial. Any other error reaches the error policy unchanged.

    ComponentWaiter

    Executor-provided lookup behind wait_for_component: resolves the next component interaction matching a custom id and optional user filter, 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)
    DuplicateComponentRoute(custom_id~ : String)
    DuplicateModalRoute(custom_id~ : String)
    EmptyComponentRoute
    EmptyModalRoute
    InvalidRouteId(custom_id~ : String, reason~ : String)
    InvalidModalFieldCount(custom_id~ : String, count~ : Int)
    DuplicateModalTextInput(custom_id~ : String, field~ : String)
    ModalOutsideLimits(custom_id~ : String, violation~ :
    LimitViolation
    )
    InvalidFileTypes(owner~ : String, reason~ : String)
    InvalidCooldown(command~ : String, seconds~ : Int)
    InvalidMaxInFlight(value~ : Int)
    } derive(
    Debug
    )

    Configuration errors detected before starting an application executor.

    CustomIdError

    pub(all) suberror CustomIdError {
    TooLong(custom_id~ : String, length~ : Int)
    SeparatorInSegment(segment~ : String)
    } derive(
    Debug
    )

    A custom id that exceeds Discord's limit or cannot round-trip its segments.

    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)
    ValueTooLong(custom_id~ : String, length~ : Int)
    } 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(max_in_flight? : Int, cooldown_store? : &
    CooldownStore
    ) -> App

    Create an application core. max_in_flight caps concurrently running interaction handlers. Cooldowns use a fresh in-memory store unless a shared cooldown_store is supplied.

    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[A] App::on_component(self : App, route : ComponentRoute[A], handler : ComponentHandler[A]) -> Unit

    Route a component's exact id or id:state, decoding state before the handler. Use the same route's custom_id when building buttons and selects.

    App::on_component_raw

    fn App::on_component_raw(self : App, prefix~ : String, handler : async (
    ComponentCtx
    ) -> Unit) -> Unit

    Register a fully raw literal-prefix component route. Longer prefixes win. App::validate rejects empty or duplicate effective prefixes.

    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. Matches the exact modal id or that id followed by : and state.

    App::on_modal_raw

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

    Register a fully raw literal-prefix modal route. Longer prefixes win. App::validate rejects empty or duplicate effective prefixes.

    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 resolves it through GET /applications/@me. Supplying both values avoids startup HTTP requests.

    Command registration is a deploy-time step. Call app.sync_commands(...) from a one-shot program (see src/examples/workers_echo/register), never per request.

    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

    Synchronize the declared commands and report each scope's changes. Entry points are always preserved; Keep also preserves other owners.

    App::validate

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

    Check declarations for configuration errors: invalid command trees and cooldowns, invalid modal field counts, duplicate modal text-input ids, modal titles and fields outside Discord's documented limits, malformed file_types upload filters, empty or duplicate component/modal effective prefixes, and invalid typed route 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::app

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

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

    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 : async (CheckCtx) -> Bool) -> Command[A]

    Add a pre-execution check. Checks run in registration order after middleware and before cooldown, argument decoding, and handler dispatch. Checks share Discord's three-second initial-response budget, so keep them fast or cache their results. 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.

    CommandScope

    Which command scope a synchronization targets.

    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. Failure handling still follows the gate's real response state.

    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::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, from? : WaitFrom, timeout_ms? : Int) ->
    ComponentCtx
    ?

    Wait for the next component interaction with an exact custom id. By default, only the user who invoked this component may satisfy the wait. Returns None on timeout, or immediately when running without a gateway connection.

    ComponentHandler

    pub(all) enum ComponentHandler[A] {
    Immediate(async (ComponentImmediateCtx, A) -> ComponentReply)
    DeferredUpdate(async (ComponentDeferredCtx, A) -> Unit)
    DeferredMessage(ephemeral~ : Bool, async (ComponentDeferredCtx, A) -> 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. Failure handling still follows the gate's real response state.

    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::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.

    ComponentRoute

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

    A component's route identity and the codec shared by producer and handler.

    ComponentRoute::custom_id

    fn[A] ComponentRoute::custom_id(self : ComponentRoute[A], state : A) -> String raise CustomIdError

    Build the id or id:state, enforcing Discord's 100 UTF-16-unit limit. An empty encoded state produces the bare id.

    ComponentRoute::decode

    fn[A] ComponentRoute::decode(self : ComponentRoute[A], custom_id : String) -> A raise HandlerError

    Decode the state from a custom id this route produced — the inverse of custom_id. Typed handlers receive the state already decoded; use this for ids that reach you undecoded, such as the ComponentCtx returned by wait_for_component, and in tests. An id that belongs to another route, or whose state does not decode, raises HandlerError::InvalidArgument. The decoded state is untrusted input.

    test {
    let route = @app.component_route(
    id="ticket-close",
    state=@app.CustomIdCodec::int(),
    )
    assert_eq(route.decode(route.custom_id(42)), 42)
    }

    CooldownBucket

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

    Identity used to share a fixed-window command cooldown.

    CustomIdCodec

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

    A reversible text encoding for the state carried in a custom id. Custom encode/decode functions and imap mappings must preserve round trips.

    CustomIdCodec::custom

    fn[A] CustomIdCodec::custom(encode~ : (A) -> String, decode~ : (String) -> A raise HandlerError) -> CustomIdCodec[A]

    Define a reversible encoding. Decode failures should raise InvalidArgument.

    CustomIdCodec::decode

    fn[A] CustomIdCodec::decode(self : CustomIdCodec[A], text : String) -> A raise HandlerError

    Decode untrusted state. The handler must still authorize the invoking user.

    CustomIdCodec::encode

    fn[A] CustomIdCodec::encode(self : CustomIdCodec[A], value : A) -> String raise CustomIdError

    Encode state, rejecting ambiguous zip segments and text over 100 UTF-16 units. The complete route id is checked separately by ComponentRoute::custom_id.

    CustomIdCodec::id

    Encode and decode a snowflake without losing its phantom resource type.

    CustomIdCodec::imap

    fn[A, B] CustomIdCodec::imap(self : CustomIdCodec[A], to~ : (A) -> B raise HandlerError, from~ : (B) -> A) -> CustomIdCodec[B]

    Map a codec to another type using a fallible decode and a reverse mapping.

    CustomIdCodec::int

    fn CustomIdCodec::int() -> CustomIdCodec[Int]

    Encode and decode a decimal integer.

    CustomIdCodec::string

    fn CustomIdCodec::string() -> CustomIdCodec[String]

    Preserve the state string, including separators in a final zip segment.

    CustomIdCodec::unit

    fn CustomIdCodec::unit() -> CustomIdCodec[Unit]

    Encode unit as no state at all, producing only the route id.

    CustomIdCodec::zip

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

    Join two encodings with : and split at the first : on decode. Encoding rejects a separator in the non-final segment. Nest additional segments on the right, e.g. a.zip(b.zip(c)).

    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. Failure handling still follows the gate's real response state.

    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, from? : WaitFrom, timeout_ms? : Int) ->
    ComponentCtx
    ?

    Wait for the next component interaction with an exact custom id. By default, only the invoking user may satisfy the wait.

    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

    The operation whose handler failed.

    FailureCtx::raw

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

    Access the underlying interaction context. Event, service, and autocomplete failures return None. Direct responses through this escape hatch may fail unless the response state 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. Pending callbacks use an initial response; sent or unconfirmed callbacks use a best-effort followup. Expired callbacks and failures without a raw context send a payload summary to the warning hook.

    FailureCtx::response_state

    Read the gate's current state. Event, service, and autocomplete failures have no raw context and return None.

    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, service, and autocomplete failures have no raw context. Responding through these contexts without checking the response state 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. Failure handling still follows the gate's real response state.

    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.

    InteractionEndpoint::handle_signed_http

    Verify the raw HTTP body, decode one interaction, and dispatch it.

    The caller owns the task group supplied to App::serve. Keep that group alive after this method returns so deferred handlers can finish.

    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.

    InteractionHttpBody

    pub(all) enum InteractionHttpBody {
    Empty
    Bytes(Bytes)
    Chunks(Array[
    MultipartChunk
    ])
    }

    A callback body. Multipart chunks retain file bytes without a second copy.

    InteractionHttpRequest

    pub(all) struct InteractionHttpRequest {
    http_method : String
    signature : String?
    timestamp : String?
    body : Bytes
    }

    The exact bytes received from an HTTP host. Never parse or reserialize body before verifying the Discord signature.

    InteractionHttpResponse

    pub(all) struct InteractionHttpResponse {
    status : Int
    content_type : String?
    body : InteractionHttpBody
    }

    A host-independent HTTP response for a Discord interaction.

    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

    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, does not name a text input, or carries a value over 4000 UTF-16 units. Raises CustomIdError::TooLong when the complete id exceeds 100 UTF-16 units.

    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. Failure handling still follows the gate's real response state.

    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. Failure handling still follows the gate's real response state.

    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.

    SlashChild

    pub struct SlashChild {
    // private fields
    }

    A type-erased slash subcommand or subcommand group.

    SyncReport

    Reports for each synchronized scope, in the requested order.

    WaitFrom

    Who may satisfy a component wait.

    component_route

    fn[A] component_route(id~ : String, state~ : CustomIdCodec[A]) -> ComponentRoute[A]

    Define a component route matching id or id:state. The id may itself contain :, so ids that are already in use elsewhere (bot:rolemenu) keep working. App::validate rejects empty ids, ids over 100 units, and an id that extends another typed route's id at a : (ticket beside ticket:close), because the shorter route's state could then produce a custom id the longer route receives.

    test "build a component from its route" {
    let route = @app.component_route(id="page", state=@app.CustomIdCodec::int())
    let app = @app.App()
    app.on_component(
    route,
    Immediate((_, page) => @app.ComponentReply::message(content="Page \{page}")),
    )
    let _ = @interaction.button(custom_id=route.custom_id(2), label="Next")
    assert_eq(route.custom_id(2), "page:2")
    app.validate()
    }

    dm_only

    fn dm_only() -> (async (CheckCtx) -> Bool)

    Require a direct-message invocation.

    file_field

    fn file_field(custom_id~ : String, label~ : String, description? : String, min_values? : Int, max_values? : Int, file_types? : Array[
    FileTypeFilter
    ]) -> ModalField[Array[
    Attachment
    ]]

    Define a modern label-wrapped file upload. Decodes to the uploaded files' attachment objects (resolved by Discord alongside the submission). file_types filters selectable files by extension only — validate the contents yourself. min_values/max_values bound the file count.

    guild_only

    fn guild_only() -> (async (CheckCtx) -> Bool)

    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()
    app.on_modal(feedback, Raw(_ => ()))
    app.validate()
    let _ : @app.ModalHandle = feedback.show(state="draft")
    }

    required_permissions

    fn required_permissions(required :
    Permissions
    ) -> (async (CheckCtx) -> Bool)

    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,
    })
    }