Thư viện hỗ trợ xây dựng Discord Bot với cấu trúc lệnh mạnh mẽ, typed an toàn và dễ mở rộng.
Tối ưu cho cả message command và slash command.
CommandBuilder, SlashCommandBuilder rõ ràng, dễ quản lýuser, guild, globalroleWeights giảm thời gian cooldowndiscord.jscategorynpm install blackcat.js-discord
hoặc
yarn add blackcat.js-discord
discord_bot
├─ commands/
│ ├─ general/
│ ├─ admin/
│ └─ moderation/
├─ slashCommands
│ ├─ general/
│ ├─ admin/
│ └─ moderation/
├─ events/
│ ├─ Client/
│ └─ Guild/
└─ index.ts
import { Client, CommandManager, EventManager, SlashCommandManager } from "blackcat.js-discord";
import { GatewayIntentBits, Partials } from "discord.js";
const config = {
botToken: "Bot token",
};
const client = new Client({
discordClientOptions: {
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMembers],
partials: [Partials.Channel, Partials.Message, Partials.Reaction, Partials.User],
allowedMentions: {
parse: ["users", "roles"],
repliedUser: false
},
},
config: config,
eventManager: new EventManager({
directory: "./events",
scopes: ["client", "Guild"], // hoặc tên folder event bất kì.
onLoad: (event) => {
console.log(`${event.file} - ok`);
},
onError: (event) => {
console.error(`${event.file}:`, event.error);
}
}),
commandManager: new CommandManager({
directory: "./commands",
prefix: "!",
onLoad: (command) => {
console.log(`commands: ${command.commandName} - ok`);
},
onError: (command) => {
console.error(`${command.file}:`, command.error);
}
}),
slashCommandManager: new SlashCommandManager({
directory: "./slashCommands",
guildID: "guild id", // có thể bỏ qua để áp dụng cho tất cả các guild mà bot tham gia.
reset: {
guild: true // reset lại command
},
onLoad: (command) => {
console.log(`slashCommands: ${command.commandName} - ok`);
},
onError: (command) => {
console.error(`${command.file}:`, command.error);
}
})
});
client.start();
import { EventBuilder } from "blackcat.js-discord";
const exampleEvent = new EventBuilder({
eventName: "event name",
once: false,
execute: async (client, ...) => {
// logic code
}
});
export default exampleEvent;
import { CommandBuilder } from "blackcat.js-discord";
const exampleCommand = new CommandBuilder({
commandName: "string",
description: "string",
aliases: ["string"],
category: "string",
usage: "string",
cooldown: {
duration: 5,
scope: ["user"], // "user" | "guild" | "global"
roleWeights: {
"id role": 0.5, // giảm 50%
},
message: (ms, ctx, commandName) => `này <@${ctx.userId}> vui lòng chờ ${ms} giây trước khi sử dụng lại lệnh ${commandName}.`
},
userPermission: {
permission: ["SendMessages"],
message: (ctx) => ({ content: `Bạn không đủ quyền để sử dụng lệnh ${ctx.commandName}` }),
},
execute: async (client, message, args) => {
// logic code.
}
});
export default exampleCommand;
import { CommandBuilder } from "blackcat.js-discord";
const exampleCommand = new SlashCommandBuilder({
commandName: "string",
description: "string",
cooldown: {
duration: 5,
scope: ["user"], // "user" | "guild" | "global"
roleWeights: {
"id role": 0.5, // giảm 50%
},
message: (ms, ctx, commandName) => `này <@${ctx.userId}> vui lòng chờ ${ms} giây trước khi sử dụng lại lệnh ${commandName}.`
},
userPermission: {
permission: ["SendMessages"],
message: (ctx) => ({ content: `Bạn không đủ quyền để sử dụng lệnh ${ctx.commandName}` }),
},
options: (o) => ({
string: o.string({ description: "string description", required: true | false }), // // integer, number, boolean, user, member, role, channel, mentionable, attachment
}),
execute: (client, interaction, options) => {
const string = options.string; // integer, number, boolean, user, member, role, channel, mentionable, attachment,
// logic code
}
});
export default exampleCommand;
// sub commands
const exampleCommand = new SlashCommandBuilder({
commandName: "admin",
description: "Admin commands",
cooldown: {
duration: 5,
scope: "user"
},
userPermission: {
permission: ["SendMessages"],
},
/* SUB COMMAND TRỰC TIẾP */
subcommands: {
reload: new SlashSubCommandBuilder({
description: "Reload bot",
options: (o) => ({
channel: o.channel({
description: "test",
channelTypes: ["GuildText"],
required: false
})
})
}),
},
/* EXECUTE */
execute: async (client, interaction, options) => {
// sub commands
if (options.payload?.type === "sub") {
if (options.payload.sub === "reload") {
const channel = options.payload.options.channel;
console.log(channel);
}
}
},
})
// groups
import { SlashCommandBuilder, SlashSubCommandGroupBuilder, SlashSubCommandBuilder } from "blackcat.js-ddiscord";
const exampleCommand = new SlashCommandBuilder({
commandName: "admin",
description: "Admin commands",
cooldown: {
duration: 5,
scope: "user"
},
userPermission: {
permission: ["SendMessages"],
},
/* GROUP */
groups: {
user: new SlashSubCommandGroupBuilder({
description: "User management",
subcommands: {
ban: new SlashSubCommandBuilder({
description: "Ban user",
options: (o) => ({
user: o.user({
description: "Target user",
required: true,
}),
reason: o.string({
description: "Reason",
required: true,
}),
}),
}),
kick: new SlashSubCommandBuilder({
description: "Kick user",
options: (o) => ({
user: o.user({
description: "Target user",
required: false,
}),
userid: o.number({
description: "user id",
required: false
}),
}),
}),
},
}),
},
/* EXECUTE */
execute: async (client, interaction, options) => {
// group commands
if (options.payload?.type === "group") {
// sub commands
if (options.payload.group === "user" && options.payload.sub === "ban") {
console.log(options.payload.options.user);
console.log(options.payload.options.reason);
}
if (options.payload.group === "user" && options.payload.sub === "kick") {
console.log(options.payload.options.user);
console.log(options.payload.options.userid);
}
}
},
})
// sub và groups
const exampleCommand = new SlashCommandBuilder({
commandName: "admin",
description: "Admin commands",
cooldown: {
duration: 5,
scope: "user"
},
userPermission: {
permission: ["SendMessages"],
},
/* SUB COMMAND TRỰC TIẾP */
subcommands: {
reload: new SlashSubCommandBuilder({
description: "Reload bot",
options: (o) => ({
channel: o.channel({
description: "test",
channelTypes: ["GuildText"],
required: false
})
})
}),
},
/* GROUP */
groups: {
user: new SlashSubCommandGroupBuilder({
description: "User management",
subcommands: {
ban: new SlashSubCommandBuilder({
description: "Ban user",
options: (o) => ({
user: o.user({
description: "Target user",
required: true,
}),
reason: o.string({
description: "Reason",
required: true,
}),
}),
}),
kick: new SlashSubCommandBuilder({
description: "Kick user",
options: (o) => ({
user: o.user({
description: "Target user",
required: false,
}),
userid: o.number({
description: "user id",
required: false
}),
}),
}),
},
}),
},
/* EXECUTE */
execute: async (client, interaction, options) => {
// sub commands
if (options.payload?.type === "sub") {
if (options.payload.sub === "reload") {
const channel = options.payload.options.channel;
console.log(channel);
}
}
// group commands
if (options.payload?.type === "group") {
// sub commands
if (options.payload.group === "user" && options.payload.sub === "ban") {
console.log(options.payload.options.user);
console.log(options.payload.options.reason);
}
if (options.payload.group === "user" && options.payload.sub === "kick") {
console.log(options.payload.options.user);
console.log(options.payload.options.userid);
}
}
// slash commands
// logic code
},
});
// hoặc
import { SlashCommandBuilder, SlashSubCommandBuilder, SlashSubCommandGroupBuilder } from "blackcat.js-discord";
const exampleCommand = new SlashCommandBuilder()
.setName("example")
.setDescription("example description")
.setCooldown({
duration: 5,
scope: "user"
})
.setUserPermissions({ permission: ["SendMessages"] })
.setGroups({
user: new SlashSubCommandGroupBuilder({
description: "User management",
subcommands: {
ban: new SlashSubCommandBuilder({ .... }),
kick: new SlashSubCommandBuilder({ ... }),
},
}),
})
.setSubcommands({
reload: new SlashSubCommandBuilder({ ... }),
})
.setExecute(async (client, interaction, options) => {
// sub commands
if (options.payload?.type === "sub") {
if (options.payload.sub === "reload") {
const channel = options.payload.options.channel;
console.log(channel);
}
}
// group commands
if (options.payload?.type === "group") {
// sub commands
if (options.payload.group === "user" && options.payload.sub === "ban") {
console.log(options.payload.options.user);
console.log(options.payload.options.reason);
}
if (options.payload.group === "user" && options.payload.sub === "kick") {
console.log(options.payload.options.user);
console.log(options.payload.options.userid);
}
}
// slash commands
// logic code
});
export default exampleCommand;
MIT License