base-app-for-discordjs v0.10.9
Skeleton - A Lightweight Extension For discord.js 14
(This README and project is WIP, anything can happen if you decide to try it...)
This projects is a made using discord.js. It includes a couple of handy features
Features
- Easier command creation.
- Automatic command deployment - all command are sent to the Discord API.
- Interaction handling
- Write custom command types, interaction handlers, and
.job.ts
files, to extend functionality.
Set up
- Install with
npm i base-app-for-discordjs
- Install all dependencies
- Run a file with the following code:
// Create the object
const skeleton = new Skeleton();
// Set what will be passed to commands when executed
skeleton.setContext({});
// Manually add a command, instead of writing it in a .job.ts file
// Be sure to add them before before you call skeleton.run
skeleton.addUserCommand(
new UserCommand<{}>({
name: "testcommand",
description: "I added this manually",
},
async (interaction, context) => {
interaction.reply("hej")
}
),
);
// This loads all command files and deploys them
skeleton.run({
appId: config["APP_ID"],
client: client,
token: config["APP_TOKEN"],
guildId: config["DEV_GUILD_ID"], // Optional, if youre using a dev guild.
});
Command files
Command files are file which ends in .job.ts
and define one command. All of the commands are imported and deployed when you run skeleton.run()
Here is an example command file:
export default new SlashCommand<{}>(
{
name: "foo",
description: "bar",
options: [
{
name: "foo",
description: "bar",
type: ApplicationCommandOptionType.String,
},
],
},
async (interaction, app) => {
interaction.reply("Hi.");
},
);
If youre using typescript the parameters are typed.
Read more here on what data to pass: https://discord.com/developers/docs/interactions/application-commands & https://old.discordjs.dev/#/docs/discord.js/14.11.0/class/ApplicationCommand
Subcommand with subcommand groups example
export default new SubCommand<{}>(
{
master: "mastercommand",
group: "group",
name: "foo",
description: "bar",
options: [
{
name: "user",
description: "useroption",
type: ApplicationCommandOptionType.User,
},
],
},
async (interaction, app) => {
interaction.reply("Hi.");
},
);
export default new MasterCommand<{}>({
name: "mastercommand",
description: "A master command",
options: [
{
description: "A group",
name: "group",
type: ApplicationCommandOptionType.SubcommandGroup,
},
],
});
Types of commands
There are 4 types of commands of which all are deployed automatically:
SlashCommand
SubCommand
UserCommand
MessageCommand
Interaction handling
You can write custom interaction handlers. For example, maybe we would want to handle all the interactions with a certain custom id. Here is how you would do it:
export default class CustomIdInteractionHandler<T> extends InteractionHandler<CustomIdInteraction, T> {
customIds = [..., "foo", ...]
// This is run before check() and execute() to make sure it is the correct type on interaction
typeGuard = (interaction: BaseInteraction): interaction is CustomIdInteraction => isCustomInteraction(interaction)
// If this return true, then the execute() method will run.
check = (interaction: CustomIdInteraction) => {
return this.customIds.find(cid => cid === interaction.customId)
}
execute = async (interaction: CustomIdInteraction, context: T) => {
let customId = interaction.customId;
// Do something depending on the custom id
}
}
Then call skeleton.registerInteractionHandler()
before you call skeleton.run()
skeleton.registerInteractionHandler(new CustomIdInteractionHandler<{}>)
Custom commands
You can extend the functionality and add more type of commands.
CustomIdCommand
export class CustomIdCommand<T> {
customId: string;
execute
constructor(customId: string, execute: (i: CustomIdInteraction, context: T) => any) {
this.customId = customId;
this.execute = execute
}
}
new CustomIdCommand<{}>(
"test",
async (interaction, app) => {
if (interaction.isRepliable())
interaction.reply("Button with custom id 'test' was clicked!")
}
);
You could then add this in the CustomIdInteractionHandler
class and run it when and interaction with the custom id "test" comes.
Writing your custom commands in .job.ts
file
You can then extend so that your new commands can be written in .job.ts
files.
First make your command class extend the Job
class and use the @JobRegistry.JobClass
decorator. Then, create a class which implements the RegistrationHandler
interface.
@JobRegistry.JobClass
export class CustomIdCommand<T> extends Job<T> {
customId: string;
constructor(customId: string, execute: (i: CustomIdInteraction, context: T) => any) {
super(execute);
this.customId = customId;
}
}
new CustomIdCommand<{}>(
"test",
async (interaction, app) => {
if (interaction.isRepliable())
interaction.reply("Button with custom id 'test' was clicked!")
}
);
export class CustomIdCommandJobHandler<T> implements RegistrationHandler<CustomIdCommand<T>> {
jobType = CustomIdCommand;
constructor() {}
onRegister = (job: CustomIdCommand<T>) => {
// Do something with the command, such as passing it to the an InteractionHandler
}
}
Then call skeleton.onRegister()
before you call skeleton.run()
skeleton.onRegister(new CustomIdCommandJobHandler<{}>)
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago