A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.
NestJS package for discord.js
$ npm install discord-nestjs discord.js
OR
$ yarn add discord-nestjs discord.js
You can use forRoot
or forRootAsync
to configure your module
token
* - your discord bot token seecommandPrefix
* - global prefix for command eventsallowGuilds
- list of Guild IDs that the bot is allowed to work withdenyGuilds
- list of Guild IDs that the bot is not allowed to work withallowChannels
- linking commands to a channel (can also be set through a decorator)commandName
* - command namechannels
* - channel ID list
webhook
- connecting with webhookwebhookId
* - webhook idwebhookToken
* - webhook token
- you can also set all options as for the client from the "discord.js" library
/*bot.module.ts*/
@Module({
imports: [
DiscordModule.forRoot({
token: 'Njg2MzI2OTMwNTg4NTY1NTQx.XmVlww.EF_bMXRvYgMUCQhg_jYnieoBW-k',
commandPrefix: '!',
allowGuilds: ['745366351929016363'],
denyGuilds: ['520622812742811698'],
allowChannels: [
{
commandName: 'some',
channels: ['745366352386326572'],
},
],
webhook: {
webhookId: 'your_webhook_id',
webhookToken: 'your_webhook_token',
},
// and other discord options
}),
],
providers: [BotGateway],
})
export class BotModule {}
Or async
/*bot.module.ts*/
@Module({
imports: [
DiscordModule.forRootAsync({
useFactory: () => ({
token: 'Njg2MzI2OTMwNTg4NTY1NTQx.XmVlww.EF_bMXRvYgMUCQhg_jYnieoBW-k',
commandPrefix: '!',
allowGuilds: ['745366351929016363'],
denyGuilds: ['520622812742811698'],
allowChannels: [
{
commandName: 'some',
channels: ['745366352386326572'],
},
],
webhook: {
webhookId: 'your_webhook_id',
webhookToken: 'your_webhook_token',
},
// and other discord options
}),
}),
],
providers: [BotGateway],
})
export class BotModule {}
Create your class (e.g. BotGateway
), mark it with @Injectable()
or @Controller()
/*bot.gateway.ts*/
import { Injectable, Logger } from '@nestjs/common';
import { On, DiscordClient } from 'discord-nestjs';
@Injectable()
export class BotGateway {
private readonly logger = new Logger(BotGateway.name);
constructor(private readonly discordClient: DiscordClient) {}
@On({ event: 'ready' })
onReady(): void {
this.logger.log(`Logged in as ${this.discordClient.user.tag}!`);
this.discordClient.getWebhookClient().send('hello bot is up!');
}
}
You can get discord client via @Client()
decorator instead constructor property
/*bot.gateway.ts*/
import { Injectable, Logger } from '@nestjs/common';
import { On, DiscordClient } from 'discord-nestjs';
@Injectable()
export class BotGateway {
private readonly logger = new Logger(BotGateway.name);
@Client()
discordClient: DiscordClient;
@On({ event: 'ready' })
onReady(): void {
this.logger.log(`Logged in as ${this.discordClient.user.tag}!`);
}
}
Use the @Command
decorator to handle incoming commands to the bot
name
* - command nameprefix
- override global prefixisRemoveCommandName
- remove command name from messageisRemovePrefix
- remove prefix name from messageisIgnoreBotMessage
- ignore incoming messages from botsallowChannels
- list of channel identifiers on which this command will workisRemoveMessage
- remove message from channel after receive
/*bot.gateway.ts*/
@Injectable()
export class BotGateway {
@OnCommand({ name: 'start' })
async onCommand(message: Message): Promise<void> {
await message.reply(`Execute command: ${message.content}`);
}
}
Handle discord events see
event
* - name of the event to listen to
/*bot.gateway.ts*/
@Injectable()
export class BotGateway {
@On({ event: 'message' })
async onMessage(message: Message): Promise<void> {
if (!message.author.bot) {
await message.reply("I'm watching you");
}
}
}
Handle discord events (only once) see
event
* - name of the event to listen to
/*bot.gateway.ts*/
@Injectable()
export class BotGateway {
@Once({ event: 'message' })
async onceMessage(message: Message): Promise<void> {
if (!message.author.bot) {
await message.reply("I'm watching you");
}
}
}
By default, the library sets the handler arguments on its own,
but you can manage the arguments yourself using the @Content()
and @Context()
decorators
- Content - message content (allow only for on message event)
- Context - default args
/*bot.gateway.ts*/
import { Content, Context, OnCommand } from 'discord-nestjs';
@Injectable()
export class BotGateway {
private readonly logger = new Logger(BotGateway.name);
@OnCommand({ name: 'start' })
async onCommand(@Content() content: string, @Context() context: any[]): Promise<void> {
await context[0].reply(`Execute command: ${content}`, `Args: ${context}`);
}
}
Set value by argument number
/*some.dto.ts*/
import { ArgNum } from 'discord-nestjs';
export class SomeDto {
@ArgNum(0)
name: string;
}
/*bot.gateway.ts*/
import { Content, Context, OnCommand } from 'discord-nestjs';
@Injectable()
export class BotGateway {
@OnCommand({ name: 'start' })
async onCommand(@Content() content: SomeDto, @Context() context: any[]): Promise<void> {
await context[0].reply(`Hello ${content.name}`);
}
}
!start Alice
To guard incoming messages you can use @UseGuards()
decorator
You need to implement DiscordGuard
interface
/*bot.guard.ts*/
import { DiscordGuard } from 'discord-nestjs';
import { ClientEvents, Message } from 'discord.js';
export class BotGuard implements DiscordGuard {
async canActive(
event: keyof ClientEvents,
context: Message,
): Promise<boolean> {
if (context.author.id === '766863033789563648') {
return true;
} else {
const embed = new MessageEmbed().setColor().setTitle('Ups! Not allowed!');
await context.reply(embed);
return false;
}
}
}
/*bot.gateway.ts*/
import { On, UseGuards, OnCommand } from 'discord-nestjs';
import { Message } from 'discord.js';
@Injectable()
export class BotGateway {
@UseGuards(BotGuard)
@OnCommand({ name: 'hide' })
async guardCommand(message: Message): Promise<void> {
// to do something
}
}
For handling intermediate requests you can use @Middleware
decorator
allowEvents
- handled eventsdenyEvents
- skipped events
You need to implement DiscordMiddleware
interface
/*bot.middleware.ts*/
@Middleware()
export class BotMiddleware implements DiscordMiddleware {
private readonly logger = new Logger(BotMiddleware.name);
use(
event: keyof ClientEvents,
context: ClientEvents[keyof ClientEvents],
): void {
if (event === 'message') {
this.logger.log('On message event triggered');
}
}
}
Don't forget to add to providers
@Module({
providers: [BotMiddleware],
})
export class BotModule {}
To intercept incoming messages for some function you can use @UsePipes()
decorator
@Content()
and @Context()
decorators
You need to implement DiscordPipesTransform
interface
/*bot.pipe.ts*/
import { DiscordPipeTransform } from 'discord-nestjs';
import { ClientEvents } from 'discord.js';
export class BotPipe implements DiscordPipeTransform {
transform(event: keyof ClientEvents, context: any): any {
return 'Some custom value';
}
}
/*bot.gateway.ts*/
import { On, UsePipes } from 'discord-nestjs';
@Injectable()
export class BotGateway {
@UsePipes(BotPipe)
@On({ event: 'message' })
async onSomeEvent(context: string): Promise<void> {
// to do something
}
}
Any questions or suggestions? Discord Федок#3051