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
- 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']
}]
// 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']
}]
// 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}!`);
}
}
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');
}
}
}
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
}
}
To intercept incoming messages you can use @UseInterceptors()
decorator
You need to implement DiscordInterceptor
interface
/*bot.interceptor.ts*/
import { DiscordInterceptor } from 'discord-nestjs';
import { ClientEvents } from 'discord.js';
export class BotInterceptor implements DiscordInterceptor {
intercept(event: keyof ClientEvents, context: any): any {
return 'Some custom value';
}
}
/*bot.gateway.ts*/
import { On, UseInterceptors } from 'discord-nestjs';
@Injectable()
export class BotGateway {
@UseInterceptors(BotInterceptor)
@On({event: 'message'})
async onSomeEvent(context: string): 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 {
}
Any questions or suggestions? Discord Федок#3051