### Install Project Dependencies Source: https://github.com/luisfun/discord-hono-docs/blob/main/README.md Run this command in your project's root directory to install all the necessary packages listed in your `package.json` file. This is typically the first step after cloning a project or creating a new one. ```bash npm install ``` -------------------------------- ### Start Local Development Server Source: https://github.com/luisfun/discord-hono-docs/blob/main/README.md This command starts a local development server, usually at `localhost:4321`. It enables hot-reloading, allowing you to see changes in your documentation site as you make them. ```bash npm run dev ``` -------------------------------- ### Create New Project and Install Dependencies Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/guides/start.mdx Initialize a new Cloudflare project, navigate into it, and install discord-hono and related development dependencies. Use discord-api-types for TypeScript projects. ```sh npm create cloudflare@latest cd YOUR_PROJECT npm i discord-hono npm i -D discord-api-types # When using TypeScript # npm i -D @types/node # As needed ``` -------------------------------- ### Discord Bot Components Response Example Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Illustrates the visual output of the chained .row() example, showing the buttons arranged in action rows. ```bash [1][22] [333][4444] ``` -------------------------------- ### Basic Command Creation Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/command.md Demonstrates the basic instantiation of the Command class with a name and description. This is the starting point for defining any application command. ```typescript import { Command } from 'discord-hono' const commands = [ new Command('name', 'description'), new Command('ping', 'response pong'), ] ``` -------------------------------- ### Components V2 Example with Layouts and Content Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Demonstrates the usage of Components V2, including nested layouts, content blocks, and integrating with other components like buttons. ```typescript export const command_components_v2 = factory.command( new Command('components_v2', 'response components_v2'), async c => { const image = await fetch('https://luis.fun/images/hono.webp') const blob = new Blob([await image.arrayBuffer()]) return c.flags('EPHEMERAL', 'IS_COMPONENTS_V2').res( { components: [ new Content('text top'), new Layout('Container').components( new Layout('Action Row').components(component_delete.component), new Layout('Separator'), new Content('container - text'), new Layout('Section') .components( new Content('container - section - text'), new Content('container - section - text2'), ) .accessory(new Content('image.webp', 'Thumbnail')), new Content('container - text2'), ), ], }, { blob, name: 'image.webp' }, ) }, ) export const component_delete = factory.component( new Button('delete', ['🗑️', 'Delete'], 'Secondary'), c => c.update().resDefer(c => c.followup()), ) ``` -------------------------------- ### Wrangler.toml Configuration for Cron Jobs Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Example configuration in wrangler.toml to enable cron triggers for the application. ```toml //wrangler.toml name = "example" main = "src/index.ts" compatibility_date = "2024-02-08" [triggers] crons = [ "0 * * * *", "0 0 * * *" ] ``` -------------------------------- ### Simple Emoji Setup for Buttons Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Shows a concise way to add an emoji to a button using an array containing the emoji and label. ```typescript import { Components, Button } from 'discord-hono' const components = new Components().row(new Button('button', ['✅', 'button'])) ``` -------------------------------- ### Create a Basic Modal with TextInput Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/modal.md Demonstrates the basic structure for creating a modal with a single text input field. Ensure 'discord-hono' is installed. ```typescript import { Modal, TextInput } from 'discord-hono' const modal = new Modal('unique-id', 'Title').row( new TextInput('custom_id', 'Label'), ) ``` -------------------------------- ### Load Handlers with Factory Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/create-factory.md Use the initialized factory to load command and event handlers. This example demonstrates loading handlers from a separate module. ```typescript // src/index.ts import * as handlers from './handlers' import { factory } from './init' export default factory.discord().loader(Object.values(handlers)) ``` -------------------------------- ### Basic DiscordHono App on Deno Deploy Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/guides/tips.mdx A minimal example of a Discord bot using DiscordHono on Deno Deploy. This registers a 'ping' command that responds with 'Pong!!'. ```typescript import { DiscordHono } from 'npm:discord-hono' const app = new DiscordHono() app.command('ping', c => c.res('Pong!!')) Deno.serve(app.fetch) ``` -------------------------------- ### Discord.js Command Builder with DiscordHono Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/migration-guides/discordjs.mdx Example of using Discord.js SlashCommandBuilder with DiscordHono's register function. Ensure you have the necessary imports. ```typescript import { SlashCommandBuilder } from '@discordjs/builders' import { register } from 'discord-hono' const commands = [ new SlashCommandBuilder() .setName('ping') .setDescription('Check if this interaction is responsive') ] register(commands, ...) ``` -------------------------------- ### Register Commands with Factory Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/create-factory.md Register your application commands using the factory. This involves getting the commands from your handlers and passing them to the `register` function along with your bot's credentials. ```typescript // src/register.ts import { register } from 'discord-hono' import * as handlers from './handlers/index.js' import { factory } from './init.js' register( factory.getCommands(Object.values(handlers)), process.env.DISCORD_APPLICATION_ID, process.env.DISCORD_TOKEN, //process.env.DISCORD_TEST_GUILD_ID, ) ``` -------------------------------- ### Command Registration for Pagination Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/examples/pagination.md This TypeScript code defines the command registration for the pagination example. It specifies the command name, description, and required options. ```typescript // register.ts const commands = [ new Command('page', 'pagination').options( new Option('content', 'page content').required(), ), ] ``` -------------------------------- ### Create Discord Message using c.rest (Docs Path) Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/rest.mdx Example of creating a Discord message using `c.rest` with the explicit path string. This method requires correctly identifying and providing path variables. ```typescript await c.rest('POST', '/channels/{channel.id}/messages', [channel_id], { content: 'this is rest', }) ``` -------------------------------- ### Create Discord Message using c.rest (Variables) Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/rest.mdx Example of creating a Discord message using `c.rest` by referencing predefined path variables. Ensure the `channel_id` is correctly set. ```typescript import { $channels$_$messages } from 'discord-hono' await c.rest('POST', $channels$_$messages, [channel_id], { content: 'this is rest', }) ``` -------------------------------- ### Accessing Message Content via `c.ref.target_id` Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Provides an example of how to retrieve the content of a trigger message using `c.ref.messages` and `c.ref.target_id`. ```typescript c.ref.messages?.[c.ref.target_id]?.content // Get the content of the trigger message ``` -------------------------------- ### Discord.js Embed Builder with DiscordHono Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/migration-guides/discordjs.mdx Example of using Discord.js EmbedBuilder within a DiscordHono command to send an embed. The EmbedBuilder is supported by default. ```typescript import { EmbedBuilder } from '@discordjs/builders' import { DiscordHono } from 'discord-hono' const app = new DiscordHono().command('embed', c => c.res({ embeds: [ new EmbedBuilder().setTitle('Title').setDescription('Description'), ], }), ) ``` -------------------------------- ### DiscordHono App on Fastly Compute Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/guides/tips.mdx An example of a Discord bot using DiscordHono deployed on Fastly Compute. It configures Discord environment variables from Fastly's environment and registers a 'ping' command. ```typescript import { env } from 'fastly:env' import { DiscordHono } from 'discord-hono' const app = new DiscordHono({ discordEnv: () => ({ APPLICATION_ID: env('DISCORD_APPLICATION_ID'), PUBLIC_KEY: env('DISCORD_PUBLIC_KEY'), TOKEN: env('DISCORD_TOKEN'), }), }).command('ping', c => c.res('Pong!!')) addEventListener('fetch', event => event.respondWith(app.fetch(event.request, undefined, event)), ) ``` -------------------------------- ### Mount DiscordHono with Basic Handlers Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/examples/mount-on-hono.mdx Mount the DiscordHono instance to a specific route in your Hono app. This setup is useful for handling Discord interactions alongside other HTTP endpoints. ```typescript // index.ts import { DiscordHono } from 'discord-hono'; // Create the DiscordHono instance and add interaction handlers const discordApp = new DiscordHono(); discordApp.command('ping', c => c.res("Pong!")); const app = new Hono<{ Bindings: Env }>(); app.get("/", (c) => c.text("I like apples")); // Mount it app.mount("/interactions", discordApp.fetch); export default app; ``` -------------------------------- ### Type DiscordHono Interactions with Context Types Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/typescript.md Utilize specific context types for different Discord interactions (commands, components, modals, autocomplete, cron jobs) to ensure type safety. This example demonstrates how to correctly type handlers for each interaction type. ```typescript import type { CommandContext, ComponentContext, AutocompleteContext, ModalContext, CronContext, } from 'discord-hono' import { DiscordHono, Components, Button, Modal, TextInput, Autocomplete, } from 'discord-hono' type Env = { Bindings: { DB: D1Database } } const commandHandler = async (c: CommandContext) => { const db = c.env.DB /* Perform some operation */ return c.res({ components: new Components().row(new Button('button', 'Yo!!')), }) } const componentHandler = async (c: ComponentContext) => { const db = c.env.DB /* Perform some operation */ return c.resModal( new Modal('modal', 'This is Modal').row( new TextInput('id', 'Type something'), ), ) } const modalHandler = async (c: ModalContext) => { const db = c.env.DB /* Perform some operation */ return c.res('Modal Submit') } const autocompleteHandler = async (c: AutocompleteContext) => { const db = c.env.DB /* Perform some operation */ return c.resAutocomplete(new Autocomplete().choices()) } const autocompleteCommandHandler = async (c: CommandContext) => { const db = c.env.DB /* Perform some operation */ return c.res('Autocomplete Command') } const cronHandler = async (c: CronContext) => { const db = c.env.DB /* Perform some operation */ } const app = new DiscordHono() .command('hey', commandHandler) .component('button', componentHandler) .modal('modal', modalHandler) .autocomplete('autocomplete', autocompleteHandler, autocompleteCommandHandler) .cron('', cronHandler) export default app ``` -------------------------------- ### Retrieving Target ID for Message/User Commands Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Shows how to access `c.ref.target_id` for message or user-triggered commands to get the ID of the target message or user. ```typescript // `c.ref.target_id` = `c.interaction.data.target_id` ``` -------------------------------- ### Using `c.ref.key` for Handler Trigger Identification Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Illustrates how `c.ref.key` provides a unified way to get the trigger identifier across different interaction types (command, component, modal, cron). ```typescript // `c.ref.key` = `c.interaction.data.name` (command, autocomplete) // `c.ref.key` = `c.interaction.data.custom_id` (component, modal) // `c.ref.key` = `c.interaction.cron` (cron) ``` -------------------------------- ### Custom Map for Regex Routing Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/examples/regex-routing.mdx This snippet defines a custom Map class that extends the default Map behavior to support regular expressions as keys. It overrides the `get` method to test incoming string keys against RegExp keys before falling back to string keys or a default handler. ```typescript // index.ts import type { ComponentHandler, ModalHandler } from 'discord-hono' import { DiscordHono } from 'discord-hono' class CustomMap< E extends Env, H extends ComponentHandler | ModalHandler, > extends Map { override get = (key: string) => { if (super.has(key)) return super.get(key)! ///// your custom logic ///// for (const [k, v] of this) if (k instanceof RegExp && k.test(key)) return v! ///// your custom logic ///// if (super.has('')) return super.get('')! throw new Error('Handler is missing') } } const app = new DiscordHono() app.component('', c => { const map = new CustomMap>() map.set('string', c => c.res('string')) map.set(/regex/, c => c.res('regex')) map.set('', c => c.res('error')) return map.get(c.ref.key)(c) }) export default app ``` -------------------------------- ### Preview Production Build Source: https://github.com/luisfun/discord-hono-docs/blob/main/README.md Use this command to preview your production build locally before deploying. It serves the contents of the `./dist/` directory, giving you a final check of how your site will appear online. ```bash npm run preview ``` -------------------------------- ### Build Production Site Source: https://github.com/luisfun/discord-hono-docs/blob/main/README.md This command compiles your Starlight site into a production-ready format, outputting the static files to the `./dist/` directory. This is the step before deploying your site. ```bash npm run build ``` -------------------------------- ### Create a Basic Embed Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/embed.md Demonstrates how to create a simple embed with a title and description using DiscordHono. ```typescript import { DiscordHono, Embed } from 'discord-hono' const app = new DiscordHono().command('embed', c => c.res({ embeds: [new Embed().title('Title').description('description')], }), ) ``` -------------------------------- ### Basic DiscordHono App with Command Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Initializes a DiscordHono app and registers a simple 'ping' command. ```typescript import { DiscordHono } from 'discord-hono' const app = new DiscordHono() app.command('ping', c => c.res('Pong!!')) export default app ``` -------------------------------- ### Defining Command Options Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/command.md Demonstrates how to add options to commands, including specifying the option type and providing basic descriptions. This allows users to pass arguments to your commands. ```typescript type OptionType = | 'String' | 'Integer' | 'Number' | 'Boolean' | 'User' | 'Channel' | 'Role' | 'Mentionable' | 'Attachment' const optionType: OptionType = 'Channel' // default: 'String' const commands = [ new Command('hello', 'response world').options( new Option('text', 'text input'), // String option new Option('channel', 'channel select', optionType), // Channel option ), ] ``` -------------------------------- ### Create Starlight Project Source: https://github.com/luisfun/discord-hono-docs/blob/main/README.md Use this command to create a new Astro project with the Starlight template. This sets up the basic structure for your documentation site. ```bash npm create astro@latest -- --template starlight ``` -------------------------------- ### Command Method Configuration Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/command.md Illustrates the extensive configuration options available for a Command instance, including type, localizations, permissions, and more. Use this to customize command behavior and appearance. ```typescript const commands = [ new Command('name', 'description') .id() .type(2) // 1,2,3 default 1 --- 1: CHAT_INPUT, 2: USER, 3: MESSAGE .application_id() .guild_id() .name_localizations() .description_localizations() .options( new Option('text', 'first text'), new Option('second', 'second text'), ) .default_member_permissions() .dm_permission() .default_permission() .nsfw() .integration_types() .contexts() .version() .handler(), ] ``` -------------------------------- ### Basic Command Handling with Context Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Demonstrates how to access the context object `c` within command handlers to send simple string responses. ```typescript import { DiscordHono } from 'discord-hono' const app = new DiscordHono() .command('ping', c => c.res('Pong!!')) .command('hello', c => c.res('world!!')) ``` -------------------------------- ### Initialize createFactory Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/create-factory.md Initialize the `createFactory` with environment bindings. This is typically done once in your main initialization file. ```typescript // src/init.ts import { createFactory } from 'discord-hono' export type Env = { Bindings: { DB: any } } export const factory = createFactory() ``` -------------------------------- ### Initializing DiscordHono with discord-verify Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Initializes DiscordHono using discord-verify for signature verification, specifying crypto and algorithm. ```typescript import { verify, PlatformAlgorithm } from 'discord-verify' const app = new DiscordHono({ verify: (...args) => verify(...args, crypto.webcrypto.subtle, PlatformAlgorithm.OldNode), }) ``` -------------------------------- ### Configure package.json for Development Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/guides/start.mdx Add 'type': 'module' to enable ES module syntax and define scripts for registering commands and deploying your bot. Ensure Node.js can load environment variables. ```json // package.json "type": "module", "scripts": { "register": "tsc && node --env-file=.env dist/register.js", } ``` -------------------------------- ### Register Commands and Deploy Bot Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/guides/start.mdx Execute the npm scripts to register your bot's commands with Discord and deploy your bot application. This step makes your bot functional and accessible. ```sh npm run register npm run deploy ``` -------------------------------- ### Configure DiscordHono with Init Options Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/typescript.md Initialize DiscordHono with custom options, including environment bindings. This allows for centralized configuration of your application's behavior and dependencies. ```typescript import type { InitOptions } from 'discord-hono' import { DiscordHono } from 'discord-hono' type Env = { Bindings: { DB: D1Database } } const options: InitOptions = { /***/ } const app = new DiscordHono(options) ``` -------------------------------- ### Initializing DiscordHono with discord-interactions verifyKey Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Initializes DiscordHono with the verifyKey function from the discord-interactions library for signature verification. ```typescript import { verifyKey } from 'discord-interactions' const app = new DiscordHono({ verify: verifyKey }) ``` -------------------------------- ### Project Structure Overview Source: https://github.com/luisfun/discord-hono-docs/blob/main/README.md This is a visual representation of the typical file and folder structure for an Astro + Starlight project. It highlights key directories like `public/`, `src/content/docs/`, and configuration files. ```bash . ├── public/ ├── src/ │ ├── assets/ │ ├── content/ │ │ ├── docs/ │ │ └── config.ts │ └── env.d.ts ├── astro.config.mjs ├── package.json └── tsconfig.json ``` -------------------------------- ### Create Select Menu Components Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Illustrates how to create a basic select menu component, specifying its unique ID and type (e.g., String, User, Role, Channel). ```typescript import { Components, Select } from 'discord-hono' type Type = 'String' | 'User' | 'Role' | 'Mentionable' | 'Channel' const selectType: Type = 'Channel' // defaul: 'String' const components = new Components().row(new Select('unique-id', selectType)) ``` -------------------------------- ### Create Button Components Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Demonstrates how to create and add basic buttons to a message response using the Components and Button classes. ```typescript import { DiscordHono, Components, Button } from 'discord-hono' const app = new DiscordHono().command('component', c => c.res({ content: 'components', components: new Components().row( new Button('button-1', 'button'), new Button('button-2', 'second'), ), }), ) ``` -------------------------------- ### Initializing DiscordHono with Custom Discord Environment Variables Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Initializes DiscordHono with a custom function to map environment variables for Discord API credentials. ```typescript const app = new DiscordHono({ discordEnv: env => ({ APPLICATION_ID: env.DISCORD_APPLICATION_ID, PUBLIC_KEY: env.DISCORD_PUBLIC_KEY, TOKEN: env.DISCORD_TOKEN, }), }) ``` -------------------------------- ### Configure Button Styles and Types Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Explains how to set the style for buttons (Primary, Secondary, Success, Danger, Link) and create link buttons. ```typescript import { Components, Button } from 'discord-hono' type Style = 'Primary' | 'Secondary' | 'Success' | 'Danger' | 'Link' | 'SKU' const style: Style = 'Secondary' // defaul: 'Primary' const components = new Components().row( new Button('unique-id', 'label'), new Button('button', 'button', style), new Button('https://example.com', 'Link button', 'Link'), ) ``` -------------------------------- ### Structuring Subcommands and Subgroups Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/command.md Shows how to organize commands using subcommands and subcommand groups for more complex interactions. This helps in creating hierarchical command structures. ```typescript import { Command, SubGroup, SubCommand } from 'discord-hono' const commands = [ new Command('slash', 'slash description').options( new SubCommand('sub1', 'Subcommand 1'), new SubGroup('group', 'group description').options( new SubCommand('sub2', 'Subcommand 2'), new SubCommand('sub3', 'Subcommand 3'), ), ), ] ``` -------------------------------- ### Handling Button Interactions Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Sets up a command that displays buttons and defines handlers for each button click. The first argument of Button() must match the first argument of .component(). ```typescript const app = new DiscordHono() .command('components', c => c.res({ content: 'No button clicked yet', components: new Components().row( new Button('button-1', 'Button'), new Button('button-2', 'Second'), ), }), ) .component('button-1', c => c.update().res('Button clicked')) .component('button-2', c => c.update().res('Second clicked')) ``` -------------------------------- ### .resActivity() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Launches the Activity. This method is only available for apps with Activities enabled. ```APIDOC ## .resActivity() ### Description Launches the Activity. This method is only available for apps with Activities enabled. ### Method Not applicable (SDK method) ### Endpoint Not applicable (SDK method) ### Parameters None ### Request Example ```ts const app = new DiscordHono().command('activity', c => c.resActivity()) ``` ### Response None (SDK method) ``` -------------------------------- ### Run Astro CLI Commands Source: https://github.com/luisfun/discord-hono-docs/blob/main/README.md This command allows you to execute various Astro CLI commands, such as `astro add` for integrating new tools or `astro check` for verifying your project's integrity. Use `-- --help` to see all available commands. ```bash npm run astro ... ``` ```bash npm run astro -- --help ``` -------------------------------- ### Respond to Activity Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Use .resActivity() to launch an Activity for your Discord app. This is only available for apps with Activities enabled. ```typescript const app = new DiscordHono().command('activity', c => c.resActivity()) ``` -------------------------------- ### Define Command with Options and Components Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/create-factory.md Define a command that accepts options and includes interactive components like buttons. The factory's `command` and `component` methods are used here. ```typescript // src/handlers/help.ts import { Command, Option, Components, Button } from 'discord-hono' import { factory } from '../init.js' type Var = { text?: string } export const command_help = factory.command( new Command('help', 'response help').options(new Option('text', 'with text')), c => c.res({ content: `text: ${c.var.text}`, components: new Components().row( new Button('https://discord-hono.luis.fun', ['📑', 'Docs'], 'Link'), component_delete.component, ), }), ) export const component_delete = factory.component( new Button('delete', ['🗑️', 'Delete'], 'Secondary'), c => c.update().resDefer(c => c.followup()), ) ``` -------------------------------- ### Basic Autocomplete Implementation Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/autocomplete.md Initializes an Autocomplete component with a search term and a predefined list of choices. The component will filter these choices based on the user's input. ```typescript return c.resAutocomplete( new Autocomplete(c.focused?.value).choices( { name: 'world', value: 'world!!!' }, { name: 'hi', value: 'hi!' }, ), ) ``` -------------------------------- ### Mount DiscordHono with Handlers Loaded Automatically Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/examples/mount-on-hono.mdx Mount a DiscordHono instance where handlers are loaded automatically using a factory. This approach simplifies managing a larger number of interaction handlers. ```typescript // index.ts import * as handlers from './handlers'; import { factory } from './init'; // Load all your handlers automatically const discordApp = factory.discord().loader(Object.values(handlers)); const app = new Hono<{ Bindings: Env }>(); app.get("/", (c) => c.text("I like apples")); app.mount("/interactions", discordApp.fetch); export default app; ``` -------------------------------- ### Define a Command with Factory Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/create-factory.md Define a simple command using the factory. The factory provides a `command` method that takes a `Command` object and a handler function. ```typescript // src/handlers/hello-world.ts import { Command } from 'discord-hono' import { factory } from '../init.js' export const command_hello = factory.command( new Command('hello', 'response world'), c => c.res('world'), ) ``` -------------------------------- ### Configure TextInput Properties Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/modal.md Demonstrates advanced configuration for a text input field, including minimum/maximum length, required status, default value, and placeholder text. Refer to Discord API documentation for detailed options. ```typescript const modal = new Modal('unique-id', 'Modal Title').row( new TextInput('custom_id', 'Label') .min_length() .max_length() .required() .value() .placeholder(), ) ``` -------------------------------- ### Handling Autocomplete for a Slash Command Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Sets up an autocomplete handler for a specific slash command. This is used to provide suggestions to users as they type command options. ```typescript const app = new DiscordHono().autocomplete('hello', c => { console.log(c.focused?.name) // option name console.log(c.focused?.value) // option value return c.resAutocomplete(...) }) ``` -------------------------------- ### .resAutocomplete() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Provides autocomplete suggestions for Discord commands. Accepts an Autocomplete instance or APICommandAutocompleteInteractionResponseCallbackData. ```APIDOC ## .resAutocomplete() ### Description Provides autocomplete suggestions for Discord commands. The argument can be an Autocomplete instance or APICommandAutocompleteInteractionResponseCallbackData. ### Parameters #### Arguments - `autocompleteData` (Autocomplete | APICommandAutocompleteInteractionResponseCallbackData) - The data for autocomplete suggestions. ``` -------------------------------- ### Registering Multiple Commands Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Defines and registers multiple commands ('ping', 'image') for the Discord bot. The first argument of Command() must match the first argument of .command(). ```typescript const commands = [ new Command('ping', 'response Pong'), new Command('image', 'response Image'), ] const app = new DiscordHono() .command('ping', c => c.res('Pong!!')) .command('image', c => c.res('Image!!')) ``` -------------------------------- ### Handling Modal Submissions Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Defines a command that opens a modal and a handler for when the modal is submitted. The first argument of Modal() must match the first argument of .modal(). ```typescript const app = new DiscordHono() .command('modal', c => c.resModal( new Modal('modal-1', 'Modal Title') .row(new TextInput('text-1', 'Text')) .row(new TextInput('text-2', 'Second')), ), ) .modal('modal-1', c => c.res('Modal submitted')) ``` -------------------------------- ### Chaining .row() for Multiple Action Rows Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Shows how to chain multiple .row() calls to create several action rows, each containing different buttons. ```typescript const components = new Components() .row(new Button('button-1', '1'), new Button('button-2', '22')) .row(new Button('button-3', '333'), new Button('button-4', '4444')) ``` -------------------------------- ### Advanced Button Customization Methods Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Demonstrates advanced customization options for buttons, including setting custom values, emojis, and disabling them. ```typescript // prettier-ignore const components = new Components().row( new Button('custom_id or URL or sku_id', 'label', 'Primary') .custom_value() // library-specific custom value .emoji() .disabled(), ) ``` -------------------------------- ### Export Handlers Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/create-factory.md Organize your command and event handlers into separate files and export them from an index file. This allows for easy importing and loading. ```typescript // src/handlers/index.ts export * from './hello-world.js' export * from './help.js' ``` -------------------------------- ### Advanced Select Menu Customization Methods Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/components.md Details advanced configuration options for select menus, including custom values, options, placeholders, and value ranges. ```typescript const components = new Components().row( new Select('custom_id') .custom_value() // library-specific custom value .options() // required: String .channel_types() // Channel .placeholder() .default_values() // User, Role, Mentionable, Channel .min_values() .max_values() .disabled(), ) ``` -------------------------------- ### Implementing Autocomplete for Commands Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Adds autocomplete functionality to a command option, providing suggestions as the user types. The first argument of Command() must match the first argument of .autocomplete(). ```typescript const commands = [ new Command('hello', 'command').options( new Option('option', 'selector').autocomplete().required(), ), ] const app = new DiscordHono().autocomplete( 'hello', c => c.resAutocomplete( new Autocomplete(c.focused?.value).choices( { name: 'world', value: 'world!!!' }, { name: 'hi', value: 'hi!' }, ), ), c => c.res(c.var.option), ) ``` -------------------------------- ### Responding to Commands with .res() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Use .res() to send an immediate response to a command. The response can be a simple string or a more complex object conforming to APIInteractionResponseCallbackData. Files can also be attached. ```typescript const app = new DiscordHono() .command('ping', c => c.res('Pong!!')) .command('hello', c => c.res({ content: 'World!!' })) ``` -------------------------------- ### .resModal() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Presents a modal dialog to the user for input. Accepts a Modal instance or APIModalInteractionResponseCallbackData. ```APIDOC ## .resModal() ### Description Presents a modal dialog to the user for input. This can be used for commands and components. The argument can be a Modal instance or APIModalInteractionResponseCallbackData. ### Parameters #### Arguments - `modalData` (Modal | APIModalInteractionResponseCallbackData) - The modal instance or data for the modal. ``` -------------------------------- ### .res() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Responds to a Discord interaction with text, data, or files. The first argument can be a string or APIInteractionResponseCallbackData, and the second can be FileData or an array of FileData. ```APIDOC ## .res() ### Description Responds to a Discord interaction. This can be used for commands, components, and modals. ### Parameters #### Arguments - `content` (string | APIInteractionResponseCallbackData) - The response content or data. - `file` (FileData | FileData[]) - Optional. File(s) to send with the response. FileData is an object with `blob` and `name` properties. ``` -------------------------------- ### c.rest Method Signature Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/rest.mdx Illustrates the general format for making REST API calls using `c.rest`. This includes the HTTP method, path, path variables, and data objects. ```typescript await c.rest('METHOD', 'PATH', ['PATH_VAR', QUERY_OBJ], DATA_OBJ, FILE_OBJ) ``` -------------------------------- ### Advanced Option Configuration Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/command.md Details advanced configurations for command options, such as localizations, required status, choices, type constraints, length limits, and autocomplete. Use these to refine user input and command behavior. ```typescript const commands = [ new Command('ping', 'response pong').options( new Option('name', 'description') .name_localizations() .description_localizations() .required() // .required(true) = .required() .choices( { name: 'choice 1', value: 'string 1' }, { name: 'choice 2', value: 'string 2' }, ) // STRING, INTEGER, NUMBER .channel_types() // CHANNEL .min_value() // INTEGER, NUMBER .max_value() // INTEGER, NUMBER .min_length() // STRING .max_length() // STRING .autocomplete(), // STRING, INTEGER, NUMBER ), ] ``` -------------------------------- ### Defining and Handling Slash Commands with Subcommands and Subgroups Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Defines a slash command with nested subcommands and subgroups, demonstrating how to access their names and values within the handler. Use this for complex command structures. ```typescript const commands = [ new Command('slash', 'slash description').options( new SubCommand('sub1', 'Subcommand 1'), new SubGroup('group', 'group description').options( new SubCommand('sub2', 'Subcommand 2').options( new Option('text', 'text'), ), new SubCommand('sub3', 'Subcommand 3'), ), ), ] const app = new DiscordHono().command('slash', c => { switch (c.sub.string) { case 'sub1': return c.res('sub1') case 'group sub2': return c.res('g-sub2: ' + c.var.text) default: return c.res(c.sub.group + '-' + c.sub.command) } }) ``` -------------------------------- ### Accessing Resolved Data with `c.ref` Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Demonstrates accessing resolved data, such as attachments, using properties like `c.ref.attachments`. ```typescript // `c.ref.attachments` = `c.interaction.data.resolved.attachments` // `c.ref.xxx` = `c.interaction.data.resolved.xxx` ``` -------------------------------- ### Create a Basic Poll Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/poll.md Use the Poll builder to create a simple poll with a question and multiple answer options. This snippet demonstrates the basic instantiation and configuration of a poll within a Discord Hono command. ```typescript import { DiscordHono, Poll } from 'discord-hono' const app = new DiscordHono().command('poll', c => c.res({ poll: new Poll() .question('What is your favorite color?') .answers(['🔴', 'Red'], ['🟢', 'Green'], 'Blue', 'Yellow'), }), ) ``` -------------------------------- ### .followup() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Sends a followup message after deferring the interaction. Can also be used to delete the original message. ```APIDOC ## .followup() ### Description Sends a followup message after deferring the interaction. Can also be used to delete the original message. ### Method Not applicable (SDK method) ### Endpoint Not applicable (SDK method) ### Parameters - **message** (string | RESTPatchAPIInteractionOriginalResponseJSONBody) - The content of the followup message or data. - **files** (FileData | FileData[]) - Optional. Files to attach to the followup message. FileData = { blob: Blob, name: 'file.name' }. ### Request Example ```ts "followup" const app = new DiscordHono().command('ping', c => c.resDefer( async c => await c.followup('Followup Text or Data', { blob: Blob, name: 'image-blob.png', }), ), ) ``` ### Response None (SDK method) ``` -------------------------------- ### Add Multiple Text Inputs using .row() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/modal.md Shows how to add multiple text input fields to a modal by chaining the `.row()` method. Each `.row()` call adds a new action row with a text input. ```typescript const modal = new Modal('unique-id', 'Modal Title') .row(new TextInput('text-1', 'Label')) .row(new TextInput('text-2', 'MultiInput', 'Multi')) ``` -------------------------------- ### Handling Autocomplete with .resAutocomplete() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Use .resAutocomplete() to provide suggestions for autocomplete interactions. It takes an Autocomplete instance or a response data object. ```typescript const app = new DiscordHono().autocomplete( 'hello', c => c.resAutocomplete( new Autocomplete(c.focused?.value).choices( { name: 'world', value: 'world!!!' }, { name: 'hi', value: 'hi!' }, ), ), c => c.res(c.var.option), ) ``` -------------------------------- ### Presenting Modals with .resModal() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Use .resModal() to present a modal form to the user. The argument is a Modal instance or a response data object. ```typescript const app = new DiscordHono().command('ping', c => c.resModal( new Modal('unique-id', 'Modal Title').row( new TextInput('text-id', 'Label'), ), ), ) ``` -------------------------------- ### Accessing Select Component Values Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Shows how to retrieve the selected values from a select component using `c.ref.values`. ```typescript // `c.ref.values` = `c.interaction.data.values` ``` -------------------------------- ### Configure TextInput Style Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/modal.md Illustrates how to specify the style of a text input field ('Single' or 'Multi') as the third argument to the TextInput constructor. The default style is 'Single'. ```typescript import { Modal, TextInput } from 'discord-hono' type Style = 'Single' | 'Multi' const modal = new Modal('unique-id', 'Modal Title') .row(new TextInput('text-1', 'Label')) .row(new TextInput('custom_id', 'MultiInput', 'Multi' as Style)) ``` -------------------------------- ### Register Commands Globally or to a Guild Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/register.md Use this snippet to register commands. Specify the DISCORD_TEST_GUILD_ID to register to a specific guild, or omit it to register globally. Ensure DISCORD_APPLICATION_ID and DISCORD_TOKEN environment variables are set. ```typescript import { Command, Option, register } from 'discord-hono' const commands = [ new Command('ping', 'response pong'), new Command('image', 'response image file').options( new Option('text', 'with text').required(), ), ] register( commands, process.env.DISCORD_APPLICATION_ID, process.env.DISCORD_TOKEN, //process.env.DISCORD_TEST_GUILD_ID, ) ``` -------------------------------- ### Send Follow-up Message with Files Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Use .followup() after .resDefer() to send a follow-up message, which can include text or data with files. Files are specified as an array of objects with 'blob' and 'name'. ```typescript const app = new DiscordHono().command('ping', c => c.resDefer( async c => await c.followup('Followup Text or Data', { blob: Blob, name: 'image-blob.png', }), ), ) ``` -------------------------------- ### Poll Builder Methods Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/poll.md This snippet outlines the available methods for configuring a Poll object, including setting the question, answers, duration, multi-select options, and layout type. These methods allow for detailed customization of the poll's behavior and appearance. ```typescript const poll = new Poll() .question() .tyanswerse() .duration() .allow_multiselect() .layout_type() ``` -------------------------------- ### Accessing Custom Variables in Context Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Shows how to use `c.var` to access custom variables passed to command and modal handlers. These variables can store specific data like option names or text input IDs. ```typescript const app = new DiscordHono() .command('ping', c => c.res(c.var.OPTION_NAME)) .modal('modal', c => c.res(c.var.TEXTINPUT_CUSTOM_ID)) ``` -------------------------------- ### Scheduling Cron Jobs Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/discord-hono.md Configures recurring tasks using cron syntax. The first argument of .cron() must match the crons defined in the wrangler.toml file. ```typescript const app = new DiscordHono() .cron('0 0 * * *', async c => { await c.rest('POST', $channels$_$messages, ['CHANNEL_ID'], { content: 'Daily Post', }) }) .cron('', async c => { await c.rest('POST', $channels$_$messages, ['CHANNEL_ID'], { content: 'Other Cron Triggers Post', }) }) ``` -------------------------------- ### Create Reusable Component Elements with .toJSON() Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/create-factory.md When reusing component elements, especially in dynamic scenarios like pagination, convert them to JSON using `.toJSON()` to avoid errors. This ensures each component instance is unique. ```typescript // src/handlers/pagination.ts import { Button, Command, type CommandContext, type ComponentContext, Components, Embed, Option, } from 'discord-hono' import { type Env, factory } from '../init.js' type Var = { content: string } const pageContent = ( c: CommandContext | ComponentContext, page: number, content: string, ) => { ///// const db = c.env.DB ///// const maxPage = 3 const embed = new Embed() .title('Title') .description(`${content}\nPage: ${page}`) const components = new Components().row( component_page.component .emoji('⬅️') .label('Previous') .custom_id(JSON.stringify([page - 1, content])) .disabled(page <= 1) .toJSON(), component_page.component .emoji('➡️') .label('Next') .custom_id(JSON.stringify([page + 1, content])) .disabled(maxPage <= page) .toJSON(), ) return c.res({ embeds: [embed], components }) } export const command_page = factory.command( new Command('page', 'pagination').options( new Option('content', 'page content').required(), ), c => pageContent(c, 1, c.var.content), ) export const component_page = factory.component(new Button('page', ''), c => { const arr: [number, string] = JSON.parse(c.var.custom_id ?? '') return pageContent(c.update(), ...arr) }) ``` -------------------------------- ### Using `c.ref.custom_value` for Component Data Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/context.md Illustrates how to set and access a library-specific transferable variable using `custom_value` for components and modals. ```typescript // Component definition new Button('button', 'Button').custom_value('value-string') // Inside handler code console.log(c.ref.custom_value) // value-string ``` -------------------------------- ### Retry POST Requests with retry429 Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/helpers/retry429.md Use `retry429` to automatically retry a POST request to create a message in a Discord channel up to 3 times with a 5-second delay between retries if a 429 rate limit error occurs. Ensure `token`, `channel_id`, and the `discord-hono` library are properly set up. ```typescript import { retry429, createRest, $channels$_$messages } from 'discord-hono' const manyPosts = async () => { const rest = createRest(token) for (let i = 0; i < 1000; i++) { await retry429( () => rest.post($channels$_$messages, [channel_id], { content: 'this is rest', }), 3, 5000, ) } } ``` -------------------------------- ### Embed Properties Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/builders/embed.md Lists all available properties for customizing an embed object. Refer to Discord API documentation for details on each property. ```typescript const embed = new Embed() .title() .type() .description() .url() .timestamp() .color() .footer() .image() .thumbnail() .video() .provider() .author() .fields() ``` -------------------------------- ### Define Custom Environment Types Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/interactions/typescript.md Define a custom environment type that includes bindings like a D1 database. This allows for type-safe access to environment variables within your application. ```typescript import { DiscordHono } from 'discord-hono' type Env = { Bindings: { DB: D1Database } } const app = new DiscordHono() app.command('hello', async c => { const db = c.env.DB /* Perform some operation */ return c.res('world!!') }) export default app ``` -------------------------------- ### Message Triggered Command Source: https://github.com/luisfun/discord-hono-docs/blob/main/src/content/docs/examples/command-type-message.md Defines a command named 'repost' that is triggered by messages. It retrieves and returns the content of a target message. ```typescript // handlers/repost.ts import { Command } from 'discord-hono' import { factory } from '../init.js' export const command_repost = factory.command( // .type(3) specifies a message trigger new Command('repost').type(3), c => { return c.res( c.ref.messages?.[c.ref.target_id!]?.content || 'Error: not found', ) }, ) ```