gaato/discord/app does not have a README file
type Spawner = async (async () -> Unit) -> Unitpub(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)pub(all) suberror AppDispatchError {
Failure(command~ : String, phase~ : ResponsePhase, source~ : Error)
} derive(Debug)pub(all) suberror HandlerError {
UserMessage(message~ : String, ephemeral~ : Bool)
GuildOnly
DmOnly
CheckFailed
MissingPermission(Permissions)
OnCooldown(retry_after_ms~ : Int64)
InvalidArgument(String)
} derive(Debug)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")
}
}pub(all) suberror ModalPrefillError {
UnknownCustomId(custom_id~ : String)
NonTextInput(custom_id~ : String)
} derive(Debug)pub struct App {
// private fields
}fn App::attach(self : App, framework : Framework, client~ : Client, application_id~ : Id[ApplicationMarker], waiter? : async (String, Int?) -> ComponentCtx?, latency_ms? : () -> Int64?) -> AppCtxfn App::middleware(self : App, middleware : async (InteractionCtx, async () -> Unit) -> Unit) -> Unitasync fn App::serve(self : App, group : TaskGroup[Unit], client? : Client, token? : String, application_id? : Id[ApplicationMarker], sync? : Bool) -> InteractionEndpointasync fn App::sync_commands(self : App, client : Client, application_id : Id[ApplicationMarker]) -> Unitpub struct AppCtx {
// private fields
}pub struct CheckCtx {
// private fields
}pub struct Command[A] {
// private fields
}fn[A] Command::check(self : Command[A], check : (CheckCtx) -> Bool raise HandlerError) -> Command[A]fn CommandReply::message(content? : String, embeds? : Array[Embed], components? : Array[Component], files? : Array[FileUpload], allowed_mentions? : AllowedMentions, ephemeral? : Bool) -> CommandReplypub(all) enum CommandSync {
Global
Guild(Id[GuildMarker])
Guilds(Array[Id[GuildMarker]])
Disabled
} derive(Debug)pub struct ComponentDeferredCtx {
// private fields
}async fn ComponentDeferredCtx::edit_original(self : ComponentDeferredCtx, content? : String, clear_content? : Bool, embeds? : Array[Embed], components? : Array[Component], allowed_mentions? : AllowedMentions, files? : Array[FileUpload]) -> Messageasync fn ComponentDeferredCtx::followup(self : ComponentDeferredCtx, content? : String, embeds? : Array[Embed], components? : Array[Component], files? : Array[FileUpload], allowed_mentions? : AllowedMentions, ephemeral? : Bool) -> Messagefn ComponentDeferredCtx::guild_scope(self : ComponentDeferredCtx) -> GuildInvocation raise HandlerErrorasync fn ComponentDeferredCtx::wait_for_component(self : ComponentDeferredCtx, custom_id~ : String, timeout_ms? : Int) -> ComponentCtx?pub(all) enum ComponentHandler {
Immediate(async (ComponentImmediateCtx) -> ComponentReply)
DeferredUpdate(async (ComponentDeferredCtx) -> Unit)
DeferredMessage(ephemeral~ : Bool, async (ComponentDeferredCtx) -> Unit)
Raw(async (ComponentCtx) -> Unit)
}pub struct ComponentImmediateCtx {
// private fields
}fn ComponentImmediateCtx::guild_scope(self : ComponentImmediateCtx) -> GuildInvocation raise HandlerErrorpub(all) enum ComponentReply {
UpdateMessage(content~ : String?, embeds~ : Array[Embed]?, components~ : Array[Component]?, allowed_mentions~ : AllowedMentions?)
Message(InitialResponse)
ShowModal(ModalHandle)
}fn ComponentReply::message(content? : String, embeds? : Array[Embed], components? : Array[Component], files? : Array[FileUpload], allowed_mentions? : AllowedMentions, ephemeral? : Bool) -> ComponentReplyfn ComponentReply::update_message(content? : String, embeds? : Array[Embed], components? : Array[Component], allowed_mentions? : AllowedMentions) -> ComponentReplypub struct DeferredCtx {
// private fields
}async fn DeferredCtx::edit_original(self : DeferredCtx, content? : String, clear_content? : Bool, embeds? : Array[Embed], components? : Array[Component], allowed_mentions? : AllowedMentions, files? : Array[FileUpload]) -> Messageasync fn DeferredCtx::followup(self : DeferredCtx, content? : String, embeds? : Array[Embed], components? : Array[Component], files? : Array[FileUpload], allowed_mentions? : AllowedMentions, ephemeral? : Bool) -> Messageasync fn DeferredCtx::wait_for_component(self : DeferredCtx, custom_id~ : String, timeout_ms? : Int) -> ComponentCtx?pub struct FailureCtx {
// private fields
}async fn FailureCtx::respond_error(self : FailureCtx, content? : String, embeds? : Array[Embed], components? : Array[Component], files? : Array[FileUpload], allowed_mentions? : AllowedMentions, ephemeral? : Bool) -> Unitpub struct ImmediateCtx {
// private fields
}pub struct InitialResponse {
// private fields
}fn InitialResponse::message(content? : String, embeds? : Array[Embed], components? : Array[Component], files? : Array[FileUpload], allowed_mentions? : AllowedMentions, ephemeral? : Bool) -> InitialResponsepub struct InteractionCtx {
// private fields
}async fn InteractionCtx::respond(self : InteractionCtx, message : String, ephemeral? : Bool) -> Unitpub struct InteractionEndpoint {
// private fields
}async fn InteractionEndpoint::handle(self : InteractionEndpoint, body : Json, deadline_ms? : Int) -> Json?async fn InteractionEndpoint::handle_interaction(self : InteractionEndpoint, interaction : Interaction, deadline_ms? : Int) -> InteractionOutcomepub(all) enum InteractionHandler[A] {
Immediate(async (ImmediateCtx, A) -> CommandReply)
Deferred(ephemeral~ : Bool, async (DeferredCtx, A) -> Unit)
Raw(async (CommandCtx) -> Unit)
}pub(all) enum InteractionOutcome {
Reply(response~ : InteractionResponse, files~ : Array[FileUpload]?)
NoRoute
NoResponse
TimedOut
} derive(Debug)pub(all) enum InteractionTarget {
Command(name~ : String)
Component(custom_id~ : String)
Modal(custom_id~ : String)
} derive(Debug)pub struct Modal[A] {
// private fields
}fn[A] Modal::show(self : Modal[A], state? : String, values? : Map[String, String]) -> ModalHandle raise ModalPrefillErrorpub struct ModalDeferredCtx {
// private fields
}async fn ModalDeferredCtx::edit_original(self : ModalDeferredCtx, content? : String, clear_content? : Bool, embeds? : Array[Embed], components? : Array[Component], allowed_mentions? : AllowedMentions, files? : Array[FileUpload]) -> Messageasync fn ModalDeferredCtx::followup(self : ModalDeferredCtx, content? : String, embeds? : Array[Embed], components? : Array[Component], files? : Array[FileUpload], allowed_mentions? : AllowedMentions, ephemeral? : Bool) -> Messagepub struct ModalField[A] {
// private fields
}pub struct ModalFields[A] {
// private fields
}fn[A, B, Z] ModalFields::map2(a : ModalField[A], b : ModalField[B], f : (A, B) -> Z) -> ModalFields[Z]fn[A, B, C, Z] ModalFields::map3(a : ModalField[A], b : ModalField[B], c : ModalField[C], f : (A, B, C) -> Z) -> ModalFields[Z]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]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]pub struct ModalHandle {
// private fields
}pub struct ModalImmediateCtx {
// private fields
}pub(all) enum ModalSubmitHandler[A] {
Immediate(async (ModalImmediateCtx, A) -> InitialResponse)
Deferred(ephemeral~ : Bool, async (ModalDeferredCtx, A) -> Unit)
Raw(async (ModalCtx) -> Unit)
}pub struct RegisteredCommand {
// private fields
}pub struct SlashChild {
// private fields
}fn message_command(name~ : String, handler~ : InteractionHandler[Message], default_member_permissions? : Permissions, nsfw? : Bool, integration_types? : Array[ApplicationIntegrationType], contexts? : Array[InteractionContextType], name_localizations? : Map[String, String]) -> Command[Message]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")
}fn select_field(custom_id~ : String, label~ : String, options~ : Array[SelectOption], description? : String, placeholder? : String, min_values? : Int, max_values? : Int) -> ModalField[Array[String]]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]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,
},
],
})
}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]fn[A] subcommand(name~ : String, description~ : String, args~ : Args[A], handler~ : InteractionHandler[A], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> SlashChildfn subcommand_group(name~ : String, description~ : String, children~ : Array[SlashChild], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> SlashChildfn text_field(custom_id~ : String, label~ : String, style? : TextInputStyle, description? : String, placeholder? : String, min_length? : Int, max_length? : Int, value? : String) -> ModalField[String]fn user_command(name~ : String, handler~ : InteractionHandler[TargetUser], default_member_permissions? : Permissions, nsfw? : Bool, integration_types? : Array[ApplicationIntegrationType], contexts? : Array[InteractionContextType], name_localizations? : Map[String, String]) -> Command[TargetUser]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,
})
}Install
Download zipAn experimental Discord library for MoonBit: typed APIs, a native gateway with voice (DAVE E2EE), and JS/serverless HTTP interactions.
Dependencies