- Full ESM
- TypeScript & JavaScript support
- Written in TypeScript
- Completely Modular and Extendable
- Command Handler, Arguments, Preconditions and Listeners Store
- Powered by @sapphire/framework preconditions and arguments system
With RevoltX you have at your disposal the creation of highly typed, secure and easy to make bots with a wide variety of tools and utilities available.
Now you can continue installing the necessary packages.
npm i @kaname-png/revoltx revolt.js
Or
yarn add @kaname-png/revoltx revolt.js
This is how the client is created and the bot is started.
// client.js
import { Client } from '@kaname-png/revoltx';
import { join } from 'path';
import { fileURLToPath } from 'url';
const start = () => {
const client = new Client({ prefix: '!' });
await client.login('<BOT_TOKEN>');
};
void start();
Now you can start bot as follows:
node --experimental-specifier-resolution=node client.js
To set the path to the commands, listeners, etc. you need to indicate the path to your "main.js" file (the file which starts your bot) in the "main" property of your package.json
file.
Remember that the name of your main file
(main.js)
is up to you.
For JavaScript it should be for example:
{
"name": "my-awesome-bot",
"version": "1.0.0",
"main": "src/main.js"
}
For TypeScript it should be for example:
{
"name": "my-awesome-bot",
"version": "1.0.0",
"main": "dist/main.js"
}
Once the client is created and instantiated, it is time to configure where all your commands, listeners, arguments, etc. are located.
import { Client } from '@kaname-png/revoltx';
import { join } from 'path';
import { fileURLToPath } from 'url';
const start = () => {
const client = new Client({ prefix: '!' });
await client.login('<BOT_TOKEN>');
};
Our project should have a folder structure like this.
ββββcommands
β ββββhelp.js
ββββmain.js
Basic structure of a basic command.
Commands are actions that users can request to the bot by means of a prefix and command name, e.g.: n!help
.
// commands/help.ts
import { Command, CommandOptions, PieceContext } from '@kaname-png/revoltx';
import type { Message } from 'revolt.js';
export class HelpCommand extends Command {
// If you need to add extra options to the command, you can do it in the constructor, it is not required if you don't need to add options.
constructor(context: PieceContext, options: CommandOptions) {
super(context, {
...options,
alias: ['helpme']
/* optional commands options */
});
}
public async run(message: Message) {
return message.reply('@kaname-png/revoltx');
}
}
Basic structure of a basic listener.
The listeners have the function of listening to events that the client emits by default, but you can assign the emitter you need and listen to the events of that emitter.
// listener/message.ts
import { Listener, ListenerOptions ClientEvents, PieceContext } from '@kaname-png/revoltx';
import type { Message } from 'revolt.js';
export class MessageListener extends Listener {
// You can set the event name you need.
constructor(context: PieceContext, options: ListenerOptions) {
super(context, {
...options,
event: ClientEvents.MessageCreate
/* optional listeners options */
});
}
public async run(message: Message) {
return message.reply('@kaname-png/revoltx');
}
}
Basic structure of a basic argument. Arguments are parameters that the bot receives from the message sent by the user. This argument system allows to use arguments dynamically as needed, and not only by configuring the command options.
// arguments/serverOwner.ts
import { Argument, ArgumentOptions ArgumentResult, PieceContext } from '../lib/structures/argument';
import type { ArgumentContext } from '../utils/interfaces/argument';
// <boolean> is for TypeScript users only.
export class ServerOwnerArgument extends Argument<boolean> {
// Asign name of argument
public constructor(context: PieceContext, options: ArgumentOptions) {
super(context, {
...options,
name: 'ServerOwner'
/* optional arguments options */
});
}
public run(parameter: string, context: ArgumentContext): ArgumentResult<boolean> {
const resolved = message.member?.server?.owner === parameter;
if (!resolved) return this.ok(true);
return this.error({
parameter,
identifier: resolved.error,
message: 'The argument did not resolve to server owner.',
context
});
}
}
// For TypeScript users only.
declare module '@kaname-png/revoltx' {
interface ArgType {
// The type returned by the this.ok() method;
ServerOwner: boolean;
}
}
// Command Usage
// User Input: n!server @kaname-png
import { Args, Command } from '@kaname-png/revoltx';
import type { Message } from 'revolt.js';
export class ServerCommand extends Command {
public run(message: Message, args: Args) {
const owner = await args.pick('ServerOwner');
return message.channel?.sendMessage(owner ? 'You are server owner.' : 'You are not the owner of the server.');
}
}
Basic structure of a basic precondition.
// preconditions/nsfw.ts
import type { PieceContext, Precondition, PreconditionOptions, PreconditionResult, Identifiers } from '@kaname-png/revoltx';
import type { Message } from 'revolt.js';
export class NSFWPrecondition extends Precondition {
public constructor(context: PieceContext, options: PreconditionOptions) {
super(context, {
...options,
name: 'NSFW'
/* optional preconditions options */
});
}
public run(message: Message): PreconditionResult {
return message.channel?.nsfw === true
? this.ok()
: this.error({ identifier: Identifiers.PreconditionsNsfw, message: 'You cannot run this command outside NSFW channels.' });
}
}
// For TypeScript users only.
declare module '@kaname-png/revoltx' {
interface Preconditions {
// Name of precondition
NSFW: never;
}
}
- More examples in the comments of the corresponding classes.
- The examples shown are written in TypeScript, but you can replicate them in JavaScript by simply removing the variable types.
This also applies to arguments, listeners, preconditions, etc.
TypeScript code
// commands/help.ts
import { Command, CommandOptions, PieceContext } from '@kaname-png/revoltx';
import type { Message } from 'revolt.js';
export class HelpCommand extends Command {
// If you need to add extra options to the command, you can do it in the constructor, it is not required if you don't need to add options.
constructor(context: PieceContext, options: CommandOptions) {
super(context, {
...options
/* optional commands options */
});
}
public run(message: Message) {
return message.reply('@kaname-png/revoltx');
}
}
JavaScript code
// commands/help.js
import { Command } from '@kaname-png/revoltx';
export class HelpCommand extends Command {
// If you need to add extra options to the command, you can do it in the constructor, it is not required if you don't need to add options.
constructor(context, options) {
super(context, {
...options
/* optional commands options */
});
}
run(message) {
return message.reply('@kaname-png/revoltx');
}
}
Thanks goes to these wonderful people (emoji key):
Kaname π π» π π€ π§ π π |
This project follows the all-contributors specification. Contributions of any kind welcome!