Sign in

    gaato/discord/framework does not have a README file

    InteractionContextError

    pub(all) suberror InteractionContextError {
    MissingInvoker
    MissingGuildMemberUser
    MissingGuildId
    MissingComponentMessage
    } derive(
    Debug
    )

    A malformed interaction that cannot satisfy the guarantees exposed by a typed handler context.

    ResponseGateError

    pub(all) suberror ResponseGateError {
    AlreadyResponded
    Expired
    InvalidCallback(kind~ :
    InteractionType
    , typ~ :
    InteractionResponseType
    )
    } derive(
    Debug
    )

    An error raised when an interaction callback cannot be accepted.

    AutocompleteCtx

    Context handed to an autocomplete handler.

    AutocompleteCtx::remaining_ms

    fn AutocompleteCtx::remaining_ms(self : AutocompleteCtx) -> Int?

    Milliseconds left before the autocomplete response window closes, or None when the executor set no deadline.

    AutocompleteCtx::suggest

    Send autocomplete suggestions. Choices beyond the first 25 are truncated.

    AutocompleteCtx::token_remaining_ms

    fn AutocompleteCtx::token_remaining_ms(self : AutocompleteCtx) -> Int

    Milliseconds left before this interaction's token expires (15 minutes after the executor received it). Followups and edits fail after that.

    CapturedResponse

    A callback plus any multipart files captured by an in-memory gate.

    CommandCtx

    Context handed to a slash / context-menu command handler.

    CommandCtx::defer_response

    async fn CommandCtx::defer_response(self : CommandCtx, ephemeral? : Bool) -> Unit

    Acknowledge now and reply later via edit_response / followup.

    CommandCtx::delete_followup

    Delete a followup message for this command interaction.

    CommandCtx::delete_response

    async fn CommandCtx::delete_response(self : CommandCtx) -> Unit

    Delete the original response to this command interaction.

    CommandCtx::edit_followup

    Edit a followup message for this command interaction.

    CommandCtx::edit_response

    Edit the original response to this command interaction. poll may only be added while editing a deferred response.

    CommandCtx::followup

    Send a followup message for this command interaction.

    CommandCtx::get_followup

    Fetch a followup message for this command interaction.

    CommandCtx::guild_scope

    fn CommandCtx::guild_scope(self : CommandCtx) -> GuildInvocation?

    The validated guild invocation, or None when invoked in a DM.

    CommandCtx::model

    Decode the submitted options into a typed CommandModel.

    CommandCtx::original_response

    async fn CommandCtx::original_response(self : CommandCtx) ->
    Message

    Fetch the original response to this command interaction.

    CommandCtx::remaining_ms

    fn CommandCtx::remaining_ms(self : CommandCtx) -> Int?

    Milliseconds left before the initial-response window closes, or None when the executor set no deadline.

    CommandCtx::reply

    Send a message through whichever path the response state allows: the initial response while pending, an edit of a still-loading deferred placeholder, or a followup after any other callback. ephemeral cannot change an existing message, so an edited placeholder keeps the visibility chosen when deferring. Raises ResponseGateError::Expired once the callback window has closed unused. Concurrent replies to one interaction run one at a time, so only the first replaces the placeholder.

    CommandCtx::respond

    Send the initial "channel message with source" response.

    CommandCtx::response_state

    fn CommandCtx::response_state(self : CommandCtx) -> ResponseState

    The current state of this interaction's initial callback.

    CommandCtx::scope

    Whether the command was invoked in a guild or a DM.

    CommandCtx::show_modal

    async fn CommandCtx::show_modal(self : CommandCtx, custom_id~ : String, title~ : String, components~ : Array[
    Component
    ]) -> Unit

    Display a modal as the initial command response.

    CommandCtx::target_message

    The resolved target of a MESSAGE context-menu command, or None when this is not a message command or its target is unavailable.

    CommandCtx::target_user

    fn CommandCtx::target_user(self : CommandCtx) -> TargetUser?

    The resolved target of a USER context-menu command, or None when this is not a user command or its target is unavailable.

    CommandCtx::token_remaining_ms

    fn CommandCtx::token_remaining_ms(self : CommandCtx) -> Int

    Milliseconds left before this interaction's token expires (15 minutes after the executor received it). Followups and edits fail after that.

    CommandCtx::user

    The invoking user.

    CommandSyncPlan

    pub struct CommandSyncPlan {
    application_id :
    Id
    [
    ApplicationMarker
    ]
    report : ScopeSyncReport
    // private fields
    }

    One scope's planned synchronization: the changes report lists and the bulk overwrite that makes them. Nothing is sent until apply. Apply soon after planning: the overwrite replaces whatever the scope holds by then, including commands registered after the plan was made.

    CommandSyncPlan::apply

    Send the planned bulk overwrite, if the plan has changes, and return its report. Failures propagate without returning a successful report.

    ComponentCtx

    Context handed to a message-component (button / select) handler.

    ComponentCtx::defer_response

    async fn ComponentCtx::defer_response(self : ComponentCtx, ephemeral? : Bool) -> Unit

    Acknowledge now and send a message later through webhook methods.

    ComponentCtx::defer_update

    async fn ComponentCtx::defer_update(self : ComponentCtx) -> Unit

    Acknowledge without any visible change (edit later if needed).

    ComponentCtx::delete_followup

    Delete a followup message for this component interaction.

    ComponentCtx::delete_response

    async fn ComponentCtx::delete_response(self : ComponentCtx) -> Unit

    Delete the original response to this component interaction.

    ComponentCtx::edit_followup

    Edit a followup message for this component interaction.

    ComponentCtx::edit_response

    Edit the original response to this component interaction. poll may only be added while editing a deferred response.

    ComponentCtx::followup

    Send a followup message for this component interaction.

    ComponentCtx::get_followup

    Fetch a followup message for this component interaction.

    ComponentCtx::guild_scope

    fn ComponentCtx::guild_scope(self : ComponentCtx) -> GuildInvocation?

    The validated guild invocation, or None when invoked in a DM.

    ComponentCtx::message

    The message to which the component was attached.

    ComponentCtx::original_response

    async fn ComponentCtx::original_response(self : ComponentCtx) ->
    Message

    Fetch the original response to this component interaction.

    ComponentCtx::remaining_ms

    fn ComponentCtx::remaining_ms(self : ComponentCtx) -> Int?

    Milliseconds left before the initial-response window closes, or None when the executor set no deadline.

    ComponentCtx::reply

    Send a message through whichever path the response state allows: the initial response while pending, an edit of a still-loading deferred placeholder, or a followup after any other callback. ephemeral cannot change an existing message, so an edited placeholder keeps the visibility chosen when deferring. Raises ResponseGateError::Expired once the callback window has closed unused. Concurrent replies to one interaction run one at a time, so only the first replaces the placeholder.

    ComponentCtx::respond

    Send a new "channel message with source" response.

    ComponentCtx::response_state

    fn ComponentCtx::response_state(self : ComponentCtx) -> ResponseState

    The current state of this interaction's initial callback.

    ComponentCtx::scope

    Whether the component was invoked in a guild or a DM.

    ComponentCtx::show_modal

    async fn ComponentCtx::show_modal(self : ComponentCtx, custom_id~ : String, title~ : String, components~ : Array[
    Component
    ]) -> Unit

    Display a modal as the initial component response.

    ComponentCtx::token_remaining_ms

    fn ComponentCtx::token_remaining_ms(self : ComponentCtx) -> Int

    Milliseconds left before this interaction's token expires (15 minutes after the executor received it). Followups and edits fail after that.

    ComponentCtx::update_message

    Edit the message the component is attached to.

    ComponentCtx::user

    The invoking user.

    DeliveryFailure

    pub(all) enum DeliveryFailure {
    Rejected
    Unsent
    Expired
    Uncertain
    } derive(Eq,
    Debug
    )

    How a failed callback delivery left the interaction's callback window.

    Framework

    pub struct Framework {
    // private fields
    }

    Routes incoming interactions to declared command / component / modal handlers, and can register the declared commands with Discord.

    Registration methods return self for chaining. Feed every InteractionCreate gateway event to process.

    Framework::Framework

    Create an empty interaction router bound to a REST client and application id. Most bots configure routes through @app.App and let an executor call App::attach instead of registering here directly. clock times callback deadlines, token lifetimes, and component waits.

    Framework::autocomplete

    fn Framework::autocomplete(self : Framework, command_name : String, handler : async (AutocompleteCtx) -> Unit) -> Framework

    Register an autocomplete handler for a command name.

    Framework::clock

    The clock this router times interactions with, for executors that wait alongside it.

    Framework::command

    fn Framework::command(self : Framework, spec :
    CommandSpec
    , handler : async (CommandCtx) -> Unit) -> Framework

    Register a command: spec describes it to Discord, handler runs when it is invoked. Routing is by command type and top-level command name; subcommand routing happens inside the handler via ctx.options.path().

    Framework::command_specs

    fn Framework::command_specs(self : Framework) -> Json

    The registration payload for every declared command, as sent to the bulk-overwrite endpoints.

    Framework::component

    fn Framework::component(self : Framework, prefix : String, handler : async (ComponentCtx) -> Unit) -> Framework

    Register a component handler for custom ids starting with prefix. Longer prefixes win; equally long prefixes retain registration order. Exact-id waiters take precedence over all registered handlers. Empty and duplicate routes are accepted here; validation is App's job.

    Framework::component_id

    fn Framework::component_id(self : Framework, id : String, handler : async (ComponentCtx) -> Unit) -> Framework

    Register a component handler matching id or id followed by : and state. Ranked by the length of id + ":"; ties retain registration order. Exact-id waiters take precedence. Empty, duplicate, and malformed ids are accepted here; validation is App's job.

    Framework::modal

    fn Framework::modal(self : Framework, prefix : String, handler : async (ModalCtx) -> Unit) -> Framework

    Register a modal-submit handler for custom ids starting with prefix. Longer prefixes win; equally long prefixes retain registration order. Empty and duplicate routes are accepted here; validation is App's job.

    Framework::modal_id

    fn Framework::modal_id(self : Framework, id : String, handler : async (ModalCtx) -> Unit) -> Framework

    Register a modal handler matching id or id followed by : and state. Ranked by the length of id + ":"; ties retain registration order. Empty, duplicate, and malformed ids are accepted here; validation is App's job.

    Framework::on_error

    fn Framework::on_error(self : Framework, hook : async (String, Error) -> Unit) -> Framework

    Install an error hook. When set, handler errors are passed to it (with a kind:name label) instead of propagating out of process.

    Framework::plan_global

    async fn Framework::plan_global(self : Framework, unowned? : UnownedCommands) -> CommandSyncPlan

    Plan the global scope's synchronization without changing it.

    Framework::plan_guild

    Plan one guild's synchronization without changing it.

    Framework::process

    async fn Framework::process(self : Framework, interaction :
    Interaction
    , deadline_ms? : Int) -> Bool

    Route one interaction. Returns true when a handler (or waiter) consumed it, false when nothing matched. Handler errors propagate unless an on_error hook is installed. The initial-response deadline is measured from this call, so call it as soon as the interaction arrives.

    Framework::process_with

    async fn Framework::process_with(self : Framework, interaction :
    Interaction
    , gate~ : ResponseGate) -> Bool

    Route one interaction through a caller-provided initial-response gate.

    Framework::sync_global

    async fn Framework::sync_global(self : Framework, unowned? : UnownedCommands) -> ScopeSyncReport

    Synchronize global commands, preserving entry points and reporting changes.

    Framework::sync_guild

    Synchronize one guild's commands and report changes.

    Framework::wait_for_component

    async fn Framework::wait_for_component(self : Framework, custom_id~ : String, user? :
    Id
    [
    UserMarker
    ], timeout_ms? : Int) -> ComponentCtx?

    Wait for the next component interaction whose custom id matches exactly and whose invoking user matches user, when provided. Returns None on timeout. Waiters win over registered component handlers, which makes multi-step flows (confirm buttons, pagination) straightforward inside one handler.

    GuildInvocation

    Proof that an interaction was invoked in a guild: the guild id and the invoking member, both validated when the context was built.

    GuildInvocation::user

    The user who invoked this interaction.

    InvocationScope

    pub(all) enum InvocationScope {
    Guild(GuildInvocation)
    Dm(
    User
    )
    } derive(
    Debug
    )

    The context in which an interaction was invoked.

    ModalCtx

    Context handed to a modal-submit handler.

    ModalCtx::defer_response

    async fn ModalCtx::defer_response(self : ModalCtx, ephemeral? : Bool) -> Unit

    Acknowledge now and reply later via a followup.

    ModalCtx::defer_update

    async fn ModalCtx::defer_update(self : ModalCtx) -> Unit

    Acknowledge without changing the message whose component opened this modal (edit it later with edit_response). A modal opened by a command has no such message, so this raises ResponseGateError::InvalidCallback.

    ModalCtx::delete_followup

    async fn ModalCtx::delete_followup(self : ModalCtx, message_id :
    Id
    [
    MessageMarker
    ]) -> Unit

    Delete a followup message for this modal interaction.

    ModalCtx::delete_response

    async fn ModalCtx::delete_response(self : ModalCtx) -> Unit

    Delete the original response to this modal interaction.

    ModalCtx::edit_followup

    Edit a followup message for this modal interaction.

    ModalCtx::edit_response

    Edit the original response to this modal interaction. poll may only be added while editing a deferred response.

    ModalCtx::followup

    Send a followup message for this modal interaction.

    ModalCtx::get_followup

    Fetch a followup message for this modal interaction.

    ModalCtx::guild_scope

    fn ModalCtx::guild_scope(self : ModalCtx) -> GuildInvocation?

    The validated guild invocation, or None when invoked in a DM.

    ModalCtx::origin

    fn ModalCtx::origin(self : ModalCtx) -> ModalOrigin

    Whether the modal was opened from a component or from a command.

    ModalCtx::original_response

    async fn ModalCtx::original_response(self : ModalCtx) ->
    Message

    Fetch the original response to this modal interaction.

    ModalCtx::remaining_ms

    fn ModalCtx::remaining_ms(self : ModalCtx) -> Int?

    Milliseconds left before the initial-response window closes, or None when the executor set no deadline.

    ModalCtx::reply

    Send a message through whichever path the response state allows: the initial response while pending, an edit of a still-loading deferred placeholder, or a followup after any other callback. ephemeral cannot change an existing message, so an edited placeholder keeps the visibility chosen when deferring. Raises ResponseGateError::Expired once the callback window has closed unused. Concurrent replies to one interaction run one at a time, so only the first replaces the placeholder.

    ModalCtx::respond

    Send a "channel message with source" response to the modal.

    ModalCtx::response_state

    fn ModalCtx::response_state(self : ModalCtx) -> ResponseState

    The current state of this interaction's initial callback.

    ModalCtx::scope

    fn ModalCtx::scope(self : ModalCtx) -> InvocationScope

    Whether the modal was submitted in a guild or a DM.

    ModalCtx::text_value

    fn ModalCtx::text_value(self : ModalCtx, custom_id : String) -> String?

    The submitted value of the text input with the given custom id.

    ModalCtx::token_remaining_ms

    fn ModalCtx::token_remaining_ms(self : ModalCtx) -> Int

    Milliseconds left before this interaction's token expires (15 minutes after the executor received it). Followups and edits fail after that.

    ModalCtx::update_message

    Edit the message whose component opened this modal. A modal opened by a command has no such message, so this raises ResponseGateError::InvalidCallback without sending anything.

    ModalCtx::user

    The invoking user.

    ModalOrigin

    pub(all) enum ModalOrigin {
    FromComponent(
    Message
    )
    FromCommand
    } derive(
    Debug
    )

    The interaction that opened a submitted modal.

    ResponseCapture

    pub struct ResponseCapture {
    // private fields
    }

    The receiving side of a capture gate.

    ResponseCapture::get

    Wait for and remove the captured callback.

    ResponseCapture::try_get

    fn ResponseCapture::try_get(self : ResponseCapture) -> CapturedResponse? raise

    Remove the captured callback without waiting, if one is available.

    ResponseGate

    pub struct ResponseGate {
    // private fields
    }

    A single-use interaction callback gate.

    ResponseGate::ResponseGate

    Construct a gate around an injected callback sink.

    classify decides how a failed delivery leaves the callback window; it defaults to Uncertain. Cancellation is always Uncertain, regardless of the classifier. With deadline_ms, the window closes that many milliseconds after construction: a later send expires the gate instead of contacting Discord. clock times the deadline and the token lifetime.

    ResponseGate::capture

    Construct an in-memory gate and a receiver for the first callback value. The deadline is measured from this call.

    ResponseGate::close_placeholder

    fn ResponseGate::close_placeholder(self : ResponseGate) -> Unit

    Record that the original response no longer shows the deferred placeholder. Response helpers call this after editing or deleting the original response, or after sending a followup.

    ResponseGate::expire

    fn ResponseGate::expire(self : ResponseGate) -> Unit

    Close an unused callback window. Other states remain unchanged.

    test "expire an unused callback window" {
    let gate = @framework.ResponseGate(ApplicationCommand, (_, _) => ())
    assert_eq(gate.state(), Pending)
    gate.expire()
    assert_eq(gate.state(), Expired)
    assert_false(gate.is_pending())
    }

    ResponseGate::is_pending

    fn ResponseGate::is_pending(self : ResponseGate) -> Bool

    Whether the initial callback can still be sent.

    ResponseGate::placeholder_open

    fn ResponseGate::placeholder_open(self : ResponseGate) -> Bool

    Whether a deferred message's loading placeholder is still showing: the callback was DeferredChannelMessageWithSource and the original response has not been edited, deleted, or answered with a followup since.

    ResponseGate::remaining_ms

    fn ResponseGate::remaining_ms(self : ResponseGate) -> Int?

    Milliseconds left before the callback window closes, clamped at zero, or None when this gate has no deadline.

    ResponseGate::rest

    Construct a gate that delivers its callback through Discord's REST API. The deadline is measured from this call, so construct the gate as soon as the interaction arrives.

    ResponseGate::send

    Validate and deliver the one allowed initial interaction callback. A call made while another callback is being delivered waits for that delivery to settle, then observes its outcome.

    ResponseGate::state

    The current state of this interaction's initial callback. A pending callback whose deadline has passed reads as Expired.

    ResponseGate::token_remaining_ms

    fn ResponseGate::token_remaining_ms(self : ResponseGate) -> Int

    Milliseconds left before the interaction token expires, counted from this gate's construction (when the executor received the interaction). Zero once it has expired.

    ResponseState

    What has happened to an interaction's single initial callback.

    ScopeSyncReport

    pub(all) struct ScopeSyncReport {
    guild_id :
    Id
    [
    GuildMarker
    ]?
    created : Array[String]
    updated : Array[String]
    deleted : Array[String]
    unchanged : Array[String]
    preserved : Array[String]
    overwritten : Bool
    } derive(
    Debug
    )

    Changes in one scope. Slash commands use plain names; other commands use <type int>:<name>. None identifies the global scope.

    TargetUser

    pub(all) struct TargetUser {
    user :
    User

    member :
    GuildMember
    ?
    }

    The resolved target of a USER context-menu command.

    UnownedCommands

    pub(all) enum UnownedCommands {
    Delete
    Keep
    } derive(Eq,
    Debug
    )

    What to do with undeclared remote commands. Entry points are always kept.

    DEFAULT_INTERACTION_DEADLINE_MS

    let DEFAULT_INTERACTION_DEADLINE_MS : Int

    The default initial-response budget in milliseconds, measured from the moment an executor receives an interaction. Discord invalidates the interaction token three seconds after sending it; the remaining 500 ms absorb delivery latency.

    INTERACTION_TOKEN_LIFETIME_MS

    let INTERACTION_TOKEN_LIFETIME_MS : Int

    How long an interaction token stays valid after Discord sends the interaction: every followup, original-response edit, and deletion must happen within it.

    classify_rest_callback_failure

    fn classify_rest_callback_failure(error : Error) -> DeliveryFailure

    Classify a failed POST /interactions/{id}/{token}/callback.

    Unknown Interaction (10062) closes the window. A transport failure or timeout that proves nothing was sent (DiscordHttpError::is_unsent) is Unsent; the client has already resent it as often as max_retries allows. Already Acknowledged (40060), rate limits, server errors, and other transport failures and timeouts are uncertain. Other client errors are definitive refusals of that payload.

    plan_command_scope

    Fetch raw commands with localizations and plan the changes, without modifying anything. Inspect report (for example deleted) before calling apply.

    plan_command_sync

    Plan a bulk overwrite from raw list-endpoint objects without mutating them. Entry points and, under Keep, other undeclared commands retain their ids and unknown fields. A matching catalog needs no PUT; duplicate remote keys force one. The payload follows declaration order, then preserved remote order.

    test {
    let (payload, report) = @framework.plan_command_sync([], [], unowned=Keep)
    assert_true(payload is None)
    assert_false(report.overwritten)
    }

    sync_command_scope

    Plan one scope and apply the plan: fetch raw commands with localizations, and overwrite only when something changed. Failures propagate without returning a successful report.