Advanced Features
Disapp framework includes powerful advanced features that dramatically reduce boilerplate code and improve developer experience.
Smart Component Handling
Automatically manage button clicks and select menu interactions without manual collector setup.
With onClick Handlers
import { v2 } from "@disapp/core";
import { ButtonStyle } from "discord.js";
const message = v2()
.text("# Menu")
.buttons(
{
id: "button1",
label: "Option 1",
style: ButtonStyle.Primary,
onClick: async (i) => {
await i.reply("You clicked Option 1!");
},
},
{
id: "button2",
label: "Option 2",
style: ButtonStyle.Success,
onClick: async (i) => {
await i.reply("You clicked Option 2!");
},
},
)
.build();
await interaction.reply(message);
Select Menus with onChange
const message = v2()
.text("# Choose an option")
.select(
"my_select",
"Select something",
[
{ label: "Option A", value: "a" },
{ label: "Option B", value: "b" },
],
async (i) => {
const selected = i.values[0];
await i.reply(`You selected: ${selected}`);
},
)
.build();
Benefits
- 90% less code - No manual collector setup
- Memory safe - Auto cleanup after timeout
- Type safe - Full TypeScript support
- Centralized - All handlers in one place
Auto-Chunking
Automatically split long messages that exceed Discord's 2000 character limit.
const message = v2()
.enableAutoChunking({
maxLength: 2000,
preserveCodeBlocks: true,
})
.text(veryLongText)
.build();
Command Middleware
Add reusable logic to commands with middleware functions.
Built-in Middleware
import { Command, OnlyAdmin, Cooldown } from "@disapp/core";
export default class BanCommand extends Command {
constructor() {
super({
name: "ban",
description: "Ban a user",
data: new SlashCommandBuilder()
.setName("ban")
.setDescription("Ban a user"),
middlewares: [OnlyAdmin(), Cooldown(5000)],
execute: async () => {},
});
}
async execute(interaction: any) {
await interaction.reply("User banned!");
}
}
Available Middleware
| Middleware | Description | Usage |
|---|---|---|
OnlyAdmin() | Requires Administrator permission | middlewares: [OnlyAdmin()] |
RequirePermission(perm) | Requires specific permission | middlewares: [RequirePermission(PermissionFlagsBits.ManageMessages)] |
Cooldown(ms) | Adds cooldown per user | middlewares: [Cooldown(5000)] |
RateLimit(max, window) | Limits uses per time window | middlewares: [RateLimit(3, 60000)] |
RequireDatabase() | Requires database connection | middlewares: [RequireDatabase()] |
RequireGuild() | Requires command in server | middlewares: [RequireGuild()] |
RequireRole(roleId) | Requires specific role | middlewares: [RequireRole('123456789')] |
OwnerOnly(ownerId) | Only bot owner can use | middlewares: [OwnerOnly('123456789')] |
Custom Middleware
import { MiddlewareFunction } from "@disapp/core";
function RequireLevel(minLevel: number): MiddlewareFunction {
return async (ctx) => {
const userLevel = await getUserLevel(ctx.interaction.user.id);
if (userLevel < minLevel) {
await ctx.interaction.reply({
content: `❌ You need level ${minLevel} to use this command!`,
flags: 64,
});
return false;
}
return true;
};
}
export default class AdvancedCommand extends Command {
constructor() {
super({
name: "advanced",
description: "Advanced command",
data: new SlashCommandBuilder()
.setName("advanced")
.setDescription("Advanced command"),
middlewares: [RequireLevel(10)],
execute: async () => {},
});
}
}
Dynamic Configuration
Hot-reload bot configuration without restarting.
import { DynamicConfig } from "@disapp/core";
const config = DynamicConfig.getInstance("./config.json");
config.on("changed", (newConfig, oldConfig) => {
console.log("Config updated!", newConfig);
});
if (config.isMaintenanceMode()) {
await interaction.reply("🔧 Bot is in maintenance mode!");
return;
}
const color = config.get("color");
Internationalization (i18n)
Multi-language support with JSON-based translations.
import { I18nHelper } from "@disapp/core";
const lang = interaction.locale?.split("-")[0] || "en";
const message = I18nHelper.command("ping.response", lang, { latency: 50 });
await interaction.reply(message);
With Components V2
const lang = interaction.locale?.split("-")[0] || "en";
const t = (key: string, params?: Record<string, any>) =>
I18nHelper.command(key, lang, params);
const message = v2()
.text(t("menu.title"))
.buttons({
id: "confirm",
label: I18nHelper.button("confirm", lang),
onClick: async (i) => {
await i.reply(t("menu.confirmed"));
},
})
.build();
Complete Example
Combining all features:
import {
Command,
v2,
OnlyAdmin,
Cooldown,
DynamicConfig,
I18nHelper,
} from "@disapp/core";
import { SlashCommandBuilder, ButtonStyle } from "discord.js";
export default class AdvancedCommand extends Command {
constructor() {
super({
name: "advanced",
description: "Advanced command with all features",
data: new SlashCommandBuilder()
.setName("advanced")
.setDescription("Advanced command with all features"),
middlewares: [OnlyAdmin(), Cooldown(5000)],
execute: async () => {},
});
}
async execute(interaction: any) {
const config = DynamicConfig.getInstance();
const color = config.get("color") || 0x5865f2;
const lang = interaction.locale?.split("-")[0] || "en";
const message = v2()
.enableAutoChunking()
.accentColor(color)
.text(`# ${I18nHelper.t("advanced.title", lang)}`)
.separator()
.buttons(
{
id: "refresh",
label: I18nHelper.button("refresh", lang),
style: ButtonStyle.Primary,
emoji: "🔄",
onClick: async (i) => {
await i.update({
content: "Refreshed at " + new Date().toLocaleTimeString(),
});
},
},
{
id: "config",
label: I18nHelper.button("config", lang),
style: ButtonStyle.Secondary,
emoji: "⚙️",
onClick: async (i) => {
const cfg = config.getAll();
await i.reply({
content: `\`\`\`json\n${JSON.stringify(cfg, null, 2)}\n\`\`\``,
flags: 64,
});
},
},
)
.build();
await interaction.reply(message);
}
}
Performance
All features are optimized for performance:
- Smart Handlers: O(1) lookup, automatic cleanup
- Auto-Chunking: Lazy evaluation, minimal overhead
- Middleware: Short-circuit on failure, cached results
- Dynamic Config: File watching with debounce, event-driven
Best Practices
- Use middleware for common checks - Don't repeat yourself
- Enable auto-chunking for user-generated content - Prevent errors
- Use smart handlers for complex interactions - Cleaner code
- Watch config in production - Live updates without downtime