All Projects → fjodor-rybakov → discord-nestjs

fjodor-rybakov / discord-nestjs

Licence: MIT license
👾 NestJS package for discord.js

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to discord-nestjs

nestjs-ratelimiter
Distributed consistent flexible NestJS rate limiter based on Redis
Stars: ✭ 49 (-71.68%)
Mutual labels:  nest, nestjs
typegraphql-nestjs
TypeGraphQL integration with NestJS
Stars: ✭ 117 (-32.37%)
Mutual labels:  nest, nestjs
twitch-project
A weekly stream in which I build a web application with Neo4j and Typescript
Stars: ✭ 78 (-54.91%)
Mutual labels:  nest, nestjs
Notadd
A microservice development architecture based on nest.js. —— 基于 Nest.js 的微服务开发架构。
Stars: ✭ 2,556 (+1377.46%)
Mutual labels:  nest, nestjs
ogma
A monorepo for the ogma logger and related packages
Stars: ✭ 201 (+16.18%)
Mutual labels:  nest, nestjs
Jwt
JWT utilities module based on the jsonwebtoken package 🔓
Stars: ✭ 232 (+34.1%)
Mutual labels:  nest, nestjs
nestjs-asyncapi
NestJS AsyncAPI module - generate the documentation of your event-based services using decorators
Stars: ✭ 88 (-49.13%)
Mutual labels:  nest, nestjs
Mongoose
Mongoose module for Nest framework (node.js) 🍸
Stars: ✭ 191 (+10.4%)
Mutual labels:  nest, nestjs
prime-nestjs
A production-ready NestJS boilerplate using Typescript, Postgres, TypeORM, and Docker.
Stars: ✭ 140 (-19.08%)
Mutual labels:  nest, nestjs
nestjs-telegraf
🤖 Powerful Nest module for easy and fast creation Telegram bots
Stars: ✭ 300 (+73.41%)
Mutual labels:  nest, nestjs
Nestjs Typegoose
Typegoose with NestJS
Stars: ✭ 215 (+24.28%)
Mutual labels:  nest, nestjs
nestjs-starter
🚀 Nest framework starter
Stars: ✭ 30 (-82.66%)
Mutual labels:  nest, nestjs
Stator
Stator, your go-to template for the perfect stack. 😍🙏
Stars: ✭ 217 (+25.43%)
Mutual labels:  nest, nestjs
MyAPI
A template to create awesome APIs easily ⚡️
Stars: ✭ 117 (-32.37%)
Mutual labels:  nest, nestjs
Passport
Passport module for Nest framework (node.js) 🔑
Stars: ✭ 211 (+21.97%)
Mutual labels:  nest, nestjs
nest-queue
Queue manager for NestJS Framework for Redis (via bull package)
Stars: ✭ 69 (-60.12%)
Mutual labels:  nest, nestjs
Crud
NestJs CRUD for RESTful APIs
Stars: ✭ 2,709 (+1465.9%)
Mutual labels:  nest, nestjs
Cool Admin Api
cool-admin-api 是基于egg.js、typeorm、jwt等封装的api开发脚手架、快速开发api接口
Stars: ✭ 188 (+8.67%)
Mutual labels:  nest, nestjs
nestjs-objection
Objection module for NestJS
Stars: ✭ 24 (-86.13%)
Mutual labels:  nest, nestjs
nestjs-session
Idiomatic Session Module for NestJS. Built on top of `express-session` 😎
Stars: ✭ 150 (-13.29%)
Mutual labels:  nest, nestjs

Nest Logo

A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.

Package License

👨🏻‍💻 Installation

$ npm install @discord-nestjs/core discord.js

Or via yarn

$ yarn add @discord-nestjs/core discord.js

🧾 Description

NestJS package for discord.js

This monorepo consists of several packages.

Answers on questions

How to migrate from v2 to v3

Click to expand

Modules

For ease of understanding, move your bot declarations to the root module(AppModule).

/* app.module.ts */

import { DiscordModule } from '@discord-nestjs/core';
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { GatewayIntentBits } from 'discord.js';

@Module({
  imports: [
    ConfigModule.forRoot(),
    DiscordModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        token: configService.get('TOKEN'),
        discordClientOptions: {
          intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
        },
        registerCommandOptions: [
          {
            forGuild: configService.get('GUILD_ID_WITH_COMMANDS'),
            removeCommandsBefore: true,
          },
        ],
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

Bot components(such as the slash command class or gateways) no longer related with DiscordModule. Absolutely all providers are searched globally through all modules. If you need to inject Discord client, you can only do this if you have exported providers from DiscordModule. The DiscordModule is not global, so a new forFeature function has been added.

/* bot.module.ts */

import { DiscordModule } from '@discord-nestjs/core';
import { Module } from '@nestjs/common';

import { BotGatewaty } from './bot.gateway';

@Module({
  imports: [DiscordModule.forFeature()],
  providers: [BotGatewaty],
})
export class BotModule {}
/* bot.gateway.ts */

import { InjectDiscordClient, Once } from '@discord-nestjs/core';
import { Injectable, Logger } from '@nestjs/common';
import { Client } from 'discord.js';

@Injectable()
export class BotGateway {
  private readonly logger = new Logger(BotGateway.name);

  constructor(
    @InjectDiscordClient()
    private readonly client: Client,
  ) {}

  @Once('ready')
  onReady() {
    this.logger.log(`Bot ${this.client.user.tag} was started!`);
  }
}

So the extraProviders option is no longer needed.

Guards, pipes and filters

The Request lifecycle has also been reworked. Now he repeats it like in NestJS.

  1. Incoming request
  2. Globally bound middleware
  3. Global guards
  4. Controller guards
  5. Route guards
  6. Global pipes
  7. Controller pipes
  8. Route pipes
  9. Method handler
  10. Exception filters (route, then controller, then global). Apply from end to beginning.
  11. Response

Removed options responsible for adding global guards, pipes and filters. Instead, add providers to the AppModule like so:

  • registerGuardGlobally() - use for register global guard
  • registerPipeGlobally() - use for register global pipe
  • registerFilterGlobally() - use for register global guard

The functions generate an always unique id, so each provider will be registered.

/* app.module.ts */

import { DiscordModule, registerGuardGlobally, registerFilterGlobally } from '@discord-nestjs/core';
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { GatewayIntentBits } from 'discord.js';

import { MyGlobalGuard } from './my-global-guard';
import { MySecondGlobalGuard } from './my-second-global-guard';
import { MyGlobalFilter } from './my-global-filter';

@Module({
  imports: [
    ConfigModule.forRoot(),
    DiscordModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        token: configService.get('TOKEN'),
        discordClientOptions: {
          intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
        },
        registerCommandOptions: [
          {
            forGuild: configService.get('GUILD_ID_WITH_COMMANDS'),
            removeCommandsBefore: true,
          },
        ],
      }),
      inject: [ConfigService],
    }),
  ],
  providers: [
    {
      provide: registerGuardGlobally(),
      useClass: MyGlobalGuard,
    },
    {
      provide: registerGuardGlobally(),
      useClass: MySecondGlobalGuard,
    },
    {
      provide: registerFilterGlobally(),
      useClass: MyGlobalFilter,
    },
  ],
})
export class AppModule {}

Collectors

If you are using InjectCollector decorator, add scope: Scope.REQUEST.

/* appreciated-reaction-collector.ts */

import {
  Filter,
  InjectCollector,
  On,
  Once,
  ReactionEventCollector,
} from '@discord-nestjs/core';
import { Injectable, Scope } from '@nestjs/common';
import { MessageReaction, ReactionCollector, User } from 'discord.js';

@Injectable({ scope: Scope.REQUEST }) // <--- here
@ReactionEventCollector({ time: 15000 })
export class AppreciatedReactionCollector {
  constructor(
    @InjectCollector()
    private readonly collector: ReactionCollector,
  ) {}

  @Filter()
  isLikeFromAuthor(reaction: MessageReaction, user: User): boolean {
    return (
      reaction.emoji.name === '👍' && user.id === reaction.message.author.id
    );
  }

  @On('collect')
  onCollect(): void {
    console.log('collect');
  }

  @Once('end')
  onEnd(): void {
    console.log('end');
  }
}

Providers by glob pattern

Previously, you could use the commands option, which allowed you to search files by glob pattern. All this functionality was moved to a separate library https://github.com/fjodor-rybakov/nestjs-dynamic-providers.

Mark the BotModule with the @InjectDynamicProviders decorator.

/* bot.module.ts */

import { DiscordModule } from '@discord-nestjs/core';
import { Module } from '@nestjs/common';
import { InjectDynamicProviders } from 'nestjs-dynamic-providers';

@InjectDynamicProviders('**/*.command.js')
@Module({
  imports: [DiscordModule.forFeature()],
})
export class BotModule {}

Also add the resolveDynamicProviders() function before creating the Nest application for add metadata for each module.

/* main.ts */

import { AppModule } from './app.module';
import { NestFactory } from '@nestjs/core';
import { resolveDynamicProviders } from 'nestjs-dynamic-providers';

async function bootstrap() {
  await resolveDynamicProviders();
  await NestFactory.createApplicationContext(AppModule);
}

bootstrap();

By default, classes are searched for that are marked with @Injectable() decorator. To override you need to pass filterPredicate as parameters to @InjectDynamicProviders().

Example with filter for `@Command` decorator only
/* bot.module.ts */

import { COMMAND_DECORATOR, DiscordModule } from '@discord-nestjs/core';
import { Module } from '@nestjs/common';
import { InjectDynamicProviders, IsObject } from 'nestjs-dynamic-providers';

@InjectDynamicProviders({
  pattern: '**/*.command.js',
  filterPredicate: (type) =>
    IsObject(type) && Reflect.hasMetadata(COMMAND_DECORATOR, type.prototype),
})
@Module({
  imports: [DiscordModule.forFeature()],
})
export class BotModule {}

The bot starts up, but the slash commands and events do not work

Click to expand

Check your intent is passed to the discordClientOptions of the module. More info

I created DTO and added TransformPipe, but when I receive response to the command, the DTO fields are missing

Click to expand

Set useDefineForClassFields to true in your tsconfig.json. Also check that the Palyoad and UsePipes decorators are imported from @discord-nestjs/core.

Any questions or suggestions? Join Discord https://discord.gg/kv89Q2dXSR

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].