44[ Discord commands] ( https://discord.com/developers/docs/interactions/application-commands )
55that run on [ Cloudflare Workers] ( https://workers.cloudflare.com/ ) , using a
66React-inspired syntax. It focuses on providing a great local development
7- experience, powered by [ 🔥 Miniflare 2 ] ( https://v2. miniflare.dev/ ) .
7+ experience, powered by [ 🔥 Miniflare] ( https://miniflare.dev/ ) .
88
99<!-- prettier-ignore-start -->
1010``` tsx
@@ -15,7 +15,7 @@ function add(): CommandHandler {
1515 const a = useNumber (" a" , " 1st number" , { required: true });
1616 const b = useNumber (" b" , " 2nd number" , { required: true });
1717 return (interaction , env , ctx ) => (
18- <Message ephemeral >{ a } + { b } = { a + b } </Message >
18+ <Message ephemeral >{ a } + { b } = { a + b } </Message >
1919 );
2020};
2121
@@ -44,14 +44,15 @@ export default { fetch: handler };
4444
4545## Quick* ish* Start
4646
47- > ⚠️ To enable auto-deployments on reload, Slshx requires the
48- > [ ` --global-async-io ` Miniflare flag] ( https://v2.miniflare.dev/core/standards#global-functionality-limits )
49- > to be set.
50-
51471 . Clone the [ ` slshx-starter ` ] ( https://github.com/mrbbot/slshx-starter )
52- repository. This includes a [ Miniflare] ( https://v2. miniflare.dev/ ) and
48+ repository. This includes a [ Miniflare] ( https://miniflare.dev/ ) and
5349 [ ` esbuild ` ] ( https://esbuild.github.io/ ) setup that removes unneeded local
5450 development code when deploying to Workers.
51+
52+ > ⚠️ To enable auto-deployments on reload, Slshx requires the
53+ > [ ` --global-async-io ` Miniflare flag] ( https://miniflare.dev/core/standards#global-functionality-limits )
54+ > to be set. ` slshx-starter ` automatically enables this for you.
55+
55562 . Copy the ` env.example.jsonc ` file to ` env.jsonc ` . ⚠️ Do not commit this file.
56573 . Create a new application in the
5758 [ Discord Developer Portal] ( https://discord.com/developers/applications ) . Copy
@@ -220,7 +221,7 @@ Some types have additional optional fields that control acceptable values.
220221<!-- prettier-ignore-start -->
221222``` tsx
222223import { ChannelType } from " slshx" ;
223- import type { APIUser , APIInteractionDataResolvedChannel , APIRole } from " discord-api-types/v9" ;
224+ import type { APIUser , APIInteractionDataResolvedChannel , APIRole , APIAttachment } from " discord-api-types/v9" ;
224225
225226function cmd(): CommandHandler {
226227 useDescription (" Command demonstrating option types" );
@@ -256,6 +257,9 @@ function cmd(): CommandHandler {
256257 const n1 = useNumber (" name" , " Description" );
257258 // └ number | null
258259 const n2 = useNumber (" name" , " Description" , { min: 5 , max: 100 });
260+
261+ const a = useAttachment (" name" , " Description" );
262+ // └ APIAttachment | null
259263
260264 return () => {}; // ...
261265};
@@ -347,6 +351,11 @@ function cover(): CommandHandler<Env> {
347351}
348352```
349353
354+ > ⚠️ Discord does not include full user, channel, role, mentionable or
355+ > attachment objects in autocomplete interactions. If a user specifies a value
356+ > for one of these options, the hook will return a partial object of the form
357+ > ` { id: "..." } ` instead.
358+
350359### Subcommands
351360
352361Discord supports grouping chat commands into
@@ -1144,6 +1153,115 @@ function selects(): CommandHandler {
11441153
11451154![ Select Menu] ( ./.github/screenshots/select.png )
11461155
1156+ ## Using Modals
1157+
1158+ [ Modals] ( https://discord.com/developers/docs/interactions/receiving-and-responding#responding-to-an-interaction )
1159+ allow you to respond to commands or message component interactions with dialog
1160+ boxes containing text inputs. Instead of returning a ` <Message> ` , return a
1161+ ` <Modal> ` or a plain message object with the ` [$modal] ` property set to ` true ` .
1162+
1163+ To generate a custom modal ID including the required Slshx routing information,
1164+ call the ` useModal ` hook. This takes a callback function taking an
1165+ ` interaction ` , ` env ` , and ` ctx ` that will be called when the modal is submitted.
1166+
1167+ To add text inputs, call the ` useInput ` hook. This returns an ` [id, value] `
1168+ tuple containing a custom ID to identify the input and the submitted value. Note
1169+ that the ` value ` should only be used inside ` useModal ` callback functions.
1170+
1171+ <!-- prettier-ignore-start -->
1172+ ``` tsx
1173+ import { CommandHandler , useInput , useModal , createElement , Message , Modal , Input , $modal , ComponentType , TextInputStyle } from " slshx" ;
1174+
1175+ export function modals(): CommandHandler <Env > {
1176+ // ...
1177+ const [nameId, nameValue] = useInput ();
1178+ const [messageId, messageValue] = useInput ();
1179+ const modalId = useModal <Env >((interaction , env , ctx ) => {
1180+ // └ APIModalSubmitInteraction
1181+
1182+ // With JSX
1183+ return <Message >Hello { nameValue } ! { messageValue } </Message >;
1184+
1185+ // Without JSX
1186+ return { content: ` Hello ${nameValue }! ${messageValue } ` };
1187+ });
1188+
1189+ return () => {
1190+ // With JSX
1191+ return (
1192+ <Modal id = { modalId } title = " Send Message" >
1193+ <Input
1194+ id = { nameId } // Only `id` and `label` are required
1195+ label = " Name"
1196+ required
1197+ value = " Initial value"
1198+ minLength = { 1 }
1199+ />
1200+ <Input
1201+ id = { messageId }
1202+ label = " Message"
1203+ placeholder = " Something to send"
1204+ maxLength = { 1000 }
1205+ paragraph // Multiline input
1206+ />
1207+ </Modal >
1208+ );
1209+
1210+ // Without JSX
1211+ return {
1212+ [$modal ]: true ,
1213+ custom_id: modalId ,
1214+ title: " Send Message" ,
1215+ components: [
1216+ {
1217+ type: ComponentType .ACTION_ROW ,
1218+ components: [
1219+ {
1220+ type: ComponentType .TEXT_INPUT ,
1221+ style: TextInputStyle .SHORT ,
1222+ custom_id: nameId ,
1223+ label: " Name" ,
1224+ required: true ,
1225+ value: " Initial value" ,
1226+ min_length: 1 ,
1227+ },
1228+ ],
1229+ },
1230+ {
1231+ type: ComponentType .ACTION_ROW ,
1232+ components: [
1233+ {
1234+ type: ComponentType .TEXT_INPUT ,
1235+ style: TextInputStyle .PARAGRAPH ,
1236+ custom_id: messageId ,
1237+ label: " Message" ,
1238+ placeholder: " Something to send" ,
1239+ required: false , // Inputs are required by default
1240+ max_length: 1000 ,
1241+ },
1242+ ],
1243+ },
1244+ ],
1245+ };
1246+ };
1247+ }
1248+ ```
1249+ <!-- prettier-ignore-end -->
1250+
1251+ ![ Modal] ( ./.github/screenshots/modal.png )
1252+
1253+ ![ Modal Submission] ( ./.github/screenshots/modal-submit.png )
1254+
1255+ ## Errors
1256+
1257+ During development, if a command, message component, or modal submission handler
1258+ throws an error, Slshx will respond with the message and stack trace. In
1259+ production, the interaction will fail.
1260+
1261+ ![ Development Error] ( ./.github/screenshots/error-development.png )
1262+
1263+ ![ Production Error] ( ./.github/screenshots/error-production.png )
1264+
11471265## Deploying Commands Globally
11481266
11491267Once you're happy with your commands, you can deploy them globally, making them
@@ -1273,9 +1391,11 @@ If an API does not have Slshx bindings, you can use the
12731391 ` URLSearchParams ` (sent as ` application/x-www-form-urlencoded ` ), or an
12741392 arbitrary JSON-serializable object (sent as ` application/json ` ). If ` body ` is
12751393 falsy, it's omitted.
1276- - ` auth ` can be an object of the form ` { bearer: string } ` (what ` getBearerAuth `
1277- returns) to use ` Bearer ` token authentication, or
1278- ` { username: string; password: string } ` to use HTTP ` Basic ` authentication
1394+ - ` auth ` can be an object of the form:
1395+ - ` { bearer: string } ` (what ` getBearerAuth ` returns) to use ` Bearer ` token
1396+ authentication
1397+ - ` { username: string; password: string } ` to use HTTP ` Basic ` authentication
1398+ - ` { bot: string } ` to use ` Bot ` token authentication
12791399
12801400This function is generic in ` Body ` and ` Result ` . You can find types for these in
12811401the ` discord-api-types ` package. See [ ` src/api/ ` ] ( ./src/api ) for examples of
0 commit comments