honocord 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -418
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,433 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
Welcome to the Honocord documentation! Honocord is a powerful, type-safe library for building Discord bots using interactions with the Hono web framework.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## What is Honocord?
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Honocord bridges Discord's Interaction API with Hono's lightweight web framework, allowing you to build fast, serverless Discord bots that run on edge platforms like Cloudflare Workers, or traditional Node.js environments.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Key Features
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- **🚀 Edge-First Design** - Optimized for Cloudflare Workers with async interaction handling
|
|
10
|
+
- **📘 Fully Type-Safe** - Built with TypeScript using `discord-api-types` for complete type safety (I hope at least)
|
|
11
|
+
- **🎯 Handler-Based Architecture** - Clean, modular system for commands, components, and modals
|
|
12
|
+
- **⚡ Hono Integration** - Leverages Hono's lightweight, fast routing capabilities
|
|
13
|
+
- **🔧 Flexible Deployment** - Works with Cloudflare Workers, Bun, Node.js, and more
|
|
14
|
+
- **🎨 Rich Builders** - Re-exports Discord.js builders for creating embeds, buttons, modals, and more
|
|
15
|
+
- **🤖 Autocomplete Support** - Built-in autocomplete helper for slash commands
|
|
16
|
+
- **🔐 Secure by Default** - Automatic signature verification for Discord interactions
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
_Disclaimer: Yes, AI helped me build this - the the focus on **helped**._
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
## Wiki
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
- **Autocomplete & IntelliSense** - IDE support for all methods and properties
|
|
17
|
-
- **Type Guards** - Runtime type checking with TypeScript inference
|
|
18
|
-
- **Custom Environment Types** - Extend with your own bindings and variables
|
|
22
|
+
Refer to the [Wiki](https://github.com/The-LukeZ/honocord/wiki) for detailed guides on getting started, building handlers, deployment, and more.
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
// TypeScript knows the exact type
|
|
22
|
-
const name = interaction.options.getString("name", true); // string
|
|
23
|
-
const count = interaction.options.getInteger("count"); // number | null
|
|
24
|
+
Also get familiar with [Discord.js](https://discord.js.org/docs/) and [Discord API Concepts](https://discord.com/developers/docs/intro).
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
const guildId = interaction.guildId; // TypeScript knows this exists
|
|
27
|
-
}
|
|
28
|
-
```
|
|
26
|
+
## Getting Help
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
If you encounter issues or have questions:
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
- Check the [Examples][examples] repo
|
|
31
|
+
- Review the documentation pages
|
|
32
|
+
- Open an issue on GitHub
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
## Examples
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
// Define handlers separately
|
|
38
|
-
const pingCommand = new SlashCommandHandler()
|
|
39
|
-
.setName("ping")
|
|
40
|
-
.setDescription("Pong!")
|
|
41
|
-
.addHandler(async (interaction) => {
|
|
42
|
-
await interaction.reply("🏓 Pong!");
|
|
43
|
-
});
|
|
36
|
+
Browse the [Examples][examples] repo for complete, working implementations:
|
|
44
37
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```
|
|
38
|
+
- **cloudflare-workers** - Basic bot on Cloudflare Workers
|
|
39
|
+
- **custom-hono-integration** - Integration with existing Hono apps (with Bun)
|
|
48
40
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- **Separation of Concerns** - Each handler is self-contained
|
|
52
|
-
- **Easy Testing** - Test handlers in isolation
|
|
53
|
-
- **Reusability** - Share handlers across projects
|
|
54
|
-
- **Hot Reloading** - Change handlers without restarting (in dev mode)
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## 💬 Interaction Support
|
|
59
|
-
|
|
60
|
-
### Slash Commands
|
|
61
|
-
|
|
62
|
-
Full-featured slash command support:
|
|
63
|
-
|
|
64
|
-
- **Options & Validation** - String, integer, boolean, user, role, channel, and more
|
|
65
|
-
- **Subcommands & Groups** - Organize complex command structures
|
|
66
|
-
- **Required & Optional** - Fine-grained control over user input
|
|
67
|
-
- **Autocomplete** - Real-time suggestions as users type
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
const searchCommand = new SlashCommandHandler()
|
|
71
|
-
.setName("search")
|
|
72
|
-
.setDescription("Search for items")
|
|
73
|
-
.addStringOption((option) =>
|
|
74
|
-
option.setName("query").setDescription("What to search for").setAutocomplete(true).setRequired(true)
|
|
75
|
-
)
|
|
76
|
-
.addHandler(handleSearch)
|
|
77
|
-
.addAutocompleteHandler(handleAutocomplete);
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
### Context Menus
|
|
83
|
-
|
|
84
|
-
Right-click context menu commands:
|
|
85
|
-
|
|
86
|
-
- **User Commands** - Actions on users (ban, view profile, etc.)
|
|
87
|
-
- **Message Commands** - Actions on messages (report, translate, etc.)
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
const reportUser = new ContextCommandHandler()
|
|
91
|
-
.setName("Report User")
|
|
92
|
-
.setType(ApplicationCommandType.User)
|
|
93
|
-
.addHandler(async (interaction) => {
|
|
94
|
-
const user = interaction.targetUser;
|
|
95
|
-
// Handle report...
|
|
96
|
-
});
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
### Message Components
|
|
102
|
-
|
|
103
|
-
Interactive buttons and select menus:
|
|
104
|
-
|
|
105
|
-
- **Buttons** - Primary, secondary, success, danger, link styles
|
|
106
|
-
- **Select Menus** - String, user, role, channel, mentionable options
|
|
107
|
-
- **Prefix Matching** - One handler for multiple related components
|
|
108
|
-
- **Parameter Passing** - Pass data through custom IDs
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
// Create a button
|
|
112
|
-
new ButtonBuilder().setCustomId("confirm/action?1234567890").setLabel("Confirm").setStyle(ButtonStyle.Success);
|
|
113
|
-
|
|
114
|
-
// Handle with prefix matching
|
|
115
|
-
const confirmHandler = new ComponentHandler("confirm").addHandler(async (interaction) => {
|
|
116
|
-
const { firstParam } = parseCustomId(interaction.custom_id);
|
|
117
|
-
// Use param...
|
|
118
|
-
});
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
### Modals (Forms)
|
|
124
|
-
|
|
125
|
-
Full modal/form support:
|
|
126
|
-
|
|
127
|
-
- **Text Inputs** - Short and paragraph styles
|
|
128
|
-
- **Validation** - Min/max length, required fields
|
|
129
|
-
- **Field Access** - Type-safe field resolution
|
|
130
|
-
- **Flexible Triggers** - Show from commands or components
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
await interaction.showModal(
|
|
134
|
-
new ModalBuilder({
|
|
135
|
-
custom_id: "feedback",
|
|
136
|
-
title: "Send Feedback",
|
|
137
|
-
}).addLabelComponents(
|
|
138
|
-
new LabelBuilder()
|
|
139
|
-
.setLabel("Your Feedback")
|
|
140
|
-
.setTextInputComponent((input) => input.setCustomId("message").setStyle(TextInputStyle.Paragraph).setRequired(true))
|
|
141
|
-
)
|
|
142
|
-
);
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
## 🔧 Developer Experience
|
|
148
|
-
|
|
149
|
-
### Minimal Boilerplate
|
|
150
|
-
|
|
151
|
-
_Well, I tried at least..._
|
|
152
|
-
|
|
153
|
-
Get started in seconds:
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
import { Honocord, SlashCommandHandler } from "honocord";
|
|
157
|
-
|
|
158
|
-
const bot = new Honocord();
|
|
159
|
-
|
|
160
|
-
bot.loadHandlers(
|
|
161
|
-
new SlashCommandHandler()
|
|
162
|
-
.setName("ping")
|
|
163
|
-
.setDescription("Pong!")
|
|
164
|
-
.addHandler(async (i) => await i.reply("Pong!"))
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
export default bot.getApp();
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
### Built-in Utilities
|
|
173
|
-
|
|
174
|
-
Helpful utilities included:
|
|
175
|
-
|
|
176
|
-
**Custom ID Parser:**
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
const { prefix, component, params } = parseCustomId("action/button?user123");
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**Autocomplete Helper:**
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
const autocompleteResponse = new AutocompleteHelper("query", interaction.user)
|
|
186
|
-
.addChoices({ name: "Option 1", value: "opt1" })
|
|
187
|
-
.response(); // Automatically filters
|
|
188
|
-
await interaction.respond(autocompleteResponse); // Sends filtered choices
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
**Color Constants:**
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
import { Colors } from "honocord";
|
|
195
|
-
|
|
196
|
-
const embed = new EmbedBuilder().setColor(Colors.Blue);
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
**Command Registration:**
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
await registerCommands(token, appId, ...handlers);
|
|
203
|
-
// You can also pass a single array
|
|
204
|
-
await registerCommands(token, appId, handlers);
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
### Flexible Integration
|
|
210
|
-
|
|
211
|
-
Use Honocord your way:
|
|
212
|
-
|
|
213
|
-
**Standalone App:**
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
const bot = new Honocord();
|
|
217
|
-
export default bot.getApp();
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
**Custom Hono Integration:**
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
const app = new Hono();
|
|
224
|
-
app.get("/", (c) => c.text("Hello"));
|
|
225
|
-
app.post("/interactions", bot.handle);
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**With Middleware:**
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
app.use("*", logger());
|
|
232
|
-
app.use("*", cors());
|
|
233
|
-
app.post("/interactions", bot.handle);
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
## 🔐 Security
|
|
239
|
-
|
|
240
|
-
### Automatic Signature Verification
|
|
241
|
-
|
|
242
|
-
Every request is automatically verified by the same logic [discord-interactions](https://github.com/discord/discord-interactions-js) has (without the extra dependency).
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
### Environment-Based Configuration
|
|
247
|
-
|
|
248
|
-
Keep secrets secure:
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
// Access through context
|
|
252
|
-
const token = interaction.context.env.DISCORD_TOKEN;
|
|
253
|
-
|
|
254
|
-
// Never hardcoded
|
|
255
|
-
const bot = new Honocord(); // Uses env vars automatically
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
## ⚡ Performance
|
|
261
|
-
|
|
262
|
-
### Efficient Routing
|
|
263
|
-
|
|
264
|
-
Optimized handler lookup:
|
|
265
|
-
|
|
266
|
-
- **Commands, Components and Modals**: O(1) hash map lookup by name/custom_id-prefix
|
|
267
|
-
- **Minimal Overhead**: Direct API access, no unnecessary layers (except the discordjs API wrapper and REST client)
|
|
268
|
-
|
|
269
|
-
---
|
|
270
|
-
|
|
271
|
-
### Deferred Responses
|
|
272
|
-
|
|
273
|
-
Handle long-running operations:
|
|
274
|
-
|
|
275
|
-
```typescript
|
|
276
|
-
await interaction.deferReply();
|
|
277
|
-
|
|
278
|
-
// Do expensive work
|
|
279
|
-
await processLargeDataset();
|
|
280
|
-
|
|
281
|
-
// Update when ready
|
|
282
|
-
await interaction.editReply("Complete!");
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
---
|
|
286
|
-
|
|
287
|
-
### Ephemeral Messages
|
|
288
|
-
|
|
289
|
-
Reduce server clutter:
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
// Only visible to user
|
|
293
|
-
await interaction.reply("Secret info", true);
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## 🎨 Rich Content
|
|
299
|
-
|
|
300
|
-
### Discord.js Builders
|
|
301
|
-
|
|
302
|
-
Re-exports most important builders like EmbedBuilder and Components V2 Builders.
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
import { EmbedBuilder, ActionRowBuilder, ButtonBuilder } from "honocord";
|
|
306
|
-
|
|
307
|
-
const embed = new EmbedBuilder().setTitle("Hello!").setColor(Colors.Blue).setDescription("Welcome to the server");
|
|
308
|
-
|
|
309
|
-
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
310
|
-
new ButtonBuilder().setCustomId("welcome").setLabel("Get Started").setStyle(1) // Primary Style
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
await interaction.reply({
|
|
314
|
-
embeds: [embed],
|
|
315
|
-
components: [row],
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
// Or with Components V2
|
|
319
|
-
import { ContainerBuilder, TextDisplayBuilder, Colors } from "honocord";
|
|
320
|
-
|
|
321
|
-
const container = new ContainerBuilder().setAccentColor(Colors.Green).addTextDisplayComponents(
|
|
322
|
-
new TextDisplayBuilder().setContent("# Hello, world!");
|
|
323
|
-
)
|
|
324
|
-
|
|
325
|
-
await interaction.reply({
|
|
326
|
-
components: [container],
|
|
327
|
-
});
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
You don't need to call `.toJSON()` manually - Honocord does it for you. Discord.js inspired.
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## 🌍 Deployment Options
|
|
335
|
-
|
|
336
|
-
### Cloudflare Workers
|
|
337
|
-
|
|
338
|
-
Deploy globally in seconds:
|
|
339
|
-
|
|
340
|
-
```bash
|
|
341
|
-
wrangler deploy
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
Cloudflare Workers has some unique configurations that Honocord needs to function. See the [Cloudflare Workers Deployment Guide](/wiki/Deployment-Guide#cloudflare-workers) for details.
|
|
345
|
-
|
|
346
|
-
---
|
|
347
|
-
|
|
348
|
-
### Traditional Servers
|
|
349
|
-
|
|
350
|
-
Works anywhere Node.js runs:
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
node index.js
|
|
354
|
-
# or
|
|
355
|
-
bun run index.ts
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
### Docker
|
|
361
|
-
|
|
362
|
-
Containerize your bot:
|
|
363
|
-
|
|
364
|
-
```dockerfile
|
|
365
|
-
FROM oven/bun:1
|
|
366
|
-
COPY . .
|
|
367
|
-
RUN bun install
|
|
368
|
-
CMD ["bun", "run", "index.ts"]
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
---
|
|
372
|
-
|
|
373
|
-
## 📦 Lightweight
|
|
374
|
-
|
|
375
|
-
### Minimal Dependencies
|
|
376
|
-
|
|
377
|
-
Honocord only requires:
|
|
378
|
-
|
|
379
|
-
- `hono` - Web framework
|
|
380
|
-
- `discord-api-types` - Type definitions
|
|
381
|
-
- `@discordjs/core` - API wrapper
|
|
382
|
-
- `@discordjs/rest` - HTTP REST client
|
|
383
|
-
- `@discordjs/builders` - Builders
|
|
384
|
-
|
|
385
|
-
---
|
|
386
|
-
|
|
387
|
-
### TypeScript First
|
|
388
|
-
|
|
389
|
-
Written in TypeScript, designed for TypeScript:
|
|
390
|
-
|
|
391
|
-
- Source maps included
|
|
392
|
-
- Full type inference
|
|
393
|
-
- JSDoc comments
|
|
394
|
-
- Declaration files
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
### Extensible
|
|
399
|
-
|
|
400
|
-
Extend with custom types:
|
|
401
|
-
|
|
402
|
-
```typescript
|
|
403
|
-
interface MyEnv {
|
|
404
|
-
DATABASE: D1Database;
|
|
405
|
-
CACHE: KVNamespace;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
type MyContext = BaseInteractionContext<MyEnv>;
|
|
409
|
-
|
|
410
|
-
// Now fully typed in handlers
|
|
411
|
-
new SlashCommandHandler<MyContext>().addHandler(async (interaction) => {
|
|
412
|
-
const db = interaction.context.env.DATABASE;
|
|
413
|
-
const cache = interaction.context.env.CACHE;
|
|
414
|
-
});
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
---
|
|
418
|
-
|
|
419
|
-
### Rate Limit Handling
|
|
420
|
-
|
|
421
|
-
Respects Discord rate limits automatically via `@discordjs/rest`.
|
|
422
|
-
|
|
423
|
-
---
|
|
424
|
-
|
|
425
|
-
### Monitoring
|
|
426
|
-
|
|
427
|
-
Built-in debug logging:
|
|
428
|
-
|
|
429
|
-
```typescript
|
|
430
|
-
const bot = new Honocord({
|
|
431
|
-
debugRest: true, // Log all REST requests
|
|
432
|
-
});
|
|
433
|
-
```
|
|
41
|
+
[examples]: https://github.com/The-LukeZ/honocord-examples
|