necordjs / necord Goto Github PK
View Code? Open in Web Editor NEW๐ค A module for creating Discord bots using NestJS, based on Discord.js
Home Page: https://necord.org
License: MIT License
๐ค A module for creating Discord bots using NestJS, based on Discord.js
Home Page: https://necord.org
License: MIT License
When doing server management feature, such as changing the prefix or whitelisted channels, the command must be restricted to elevated users.
Instead of making a custom guard or decorator, I believe this would be a good feature to integrate within necord itself.
Currently, this must be done in a guard, and using a "manual" way to specify the required permissions.
Ex:
// command
@UseGuards(ServerAdminGuard)
// guard
interaction.memberPermissions.has(Permissions.FLAGS.MANAGE_GUILD)
It would be much cleaner to have this within its own @GuildPermission
decorator, or within arguments to the Command decorator.
@SlashCommand('name', 'desc', { defaultPermission: true, guildPermission: [Permissions.FLAGS.MANAGE_GUILD] } )
// or
@SlashCommand('name','desc')
@GuildPermissions(Permissions.FLAGS.MANAGE_GUILD)
No response
No response
`
@Injectable()
export class GeneralLogger implements LoggerService {
private readonly logger = new Logger(GeneralLogger.name);
public constructor(
private readonly client: Client,
private readonly configServer: ConfigService,
) {}
@once('ready')
public onReady(@context() [client]: ContextOf<'ready'>) {
this.logger.log(Bot logged in as ${client.user.username}
);
}
@on('warn')
public onWarn(@context() [message]: ContextOf<'warn'>) {
this.logger.warn(message);
}
log(message: string): void {
this.logger.log('info', message);
}
error(message: string): void {
this.logger.log('error', message);
}
warn(message: string): void {
this.logger.log('warn', message);
}
debug(message: string): void {
this.logger.log('debug', message);
}
verbose(message: string): void {
this.logger.log('debug', message);
}
sendToMessage(message: string) {
const channel = this.client.channels.cache.get('1131273538611982538') as any;
channel.send(message);
}
}
`
necord version 6.1
error 'TypeError: undefined is not an object (evaluating 'this.client.channels.cache.get("1131273538611982538").send')
at sendToMessage (/home/tuan-dd/repos/project_mentor/src/global/services/logger-general.service.ts:49:24)
at getHello (/home/tuan-dd/repos/project_mentor/src/app.service.ts:9:11)
at (/home/tuan-dd/repos/project_mentor/node_modules/@nestjs/core/router/router-execution-context.js:37:48)
at intercept (/home/tuan-dd/repos/project_mentor/node_modules/@nestjs/core/interceptors/interceptors-consumer.js:10:16)
at (/home/tuan-dd/repos/project_mentor/node_modules/@nestjs/core/router/router-execution-context.js:46:51)
at (/home/tuan-dd/repos/project_mentor/node_modules/@nestjs/core/router/router-execution-context.js:40:30)
at (/home/tuan-dd/repos/project_mentor/node_modules/@nestjs/core/router/router-proxy.js:10:12)
at (/home/tuan-dd/repos/project_mentor/node_modules/@nestjs/core/router/router-proxy.js:7:16)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/route.js:146:11)
at dispatch (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/route.js:115:21)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:283:43)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at (node:domain:34:22)
at runInContextMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/request-context/lib/index.js:136:28)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at urlencodedParser (/home/tuan-dd/repos/project_mentor/node_modules/body-parser/lib/types/urlencoded.js:91:6)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at jsonParser (/home/tuan-dd/repos/project_mentor/node_modules/body-parser/lib/types/json.js:113:6)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:518:6)
at xXssProtectionMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:294:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at xPoweredByMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:287:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at xPermittedCrossDomainPoliciesMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:280:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at xFrameOptionsMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:264:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at xDownloadOptionsMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:244:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at xDnsPrefetchControlMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:237:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at xContentTypeOptionsMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:229:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at strictTransportSecurityMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:222:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at referrerPolicyMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:190:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at originAgentClusterMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:165:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at crossOriginResourcePolicyMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:158:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at crossOriginOpenerPolicyMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:142:7)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at contentSecurityPolicyMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:107:8)
at internalNext (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:514:46)
at helmetMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/helmet/index.mjs:518:6)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at compression (/home/tuan-dd/repos/project_mentor/node_modules/compression/index.js:219:9)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at logger (/home/tuan-dd/repos/project_mentor/node_modules/morgan/index.js:143:9)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at cors (/home/tuan-dd/repos/project_mentor/node_modules/cors/lib/index.js:187:11)
at (/home/tuan-dd/repos/project_mentor/node_modules/cors/lib/index.js:225:13)
at originCallback (/home/tuan-dd/repos/project_mentor/node_modules/cors/lib/index.js:213:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/cors/lib/index.js:219:27)
at optionsCallback (/home/tuan-dd/repos/project_mentor/node_modules/cors/lib/index.js:198:18)
at corsMiddleware (/home/tuan-dd/repos/project_mentor/node_modules/cors/lib/index.js:204:12)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at expressInit (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/middleware/init.js:39:9)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
at process_params (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:349:6)
at next (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:280:10)
at query (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/middleware/query.js:44:9)
at handle (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/layer.js:94:21)
at trim_prefix (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:327:41)
at (/home/tuan-dd/repos/project_mentor/node_modules/express/lib/router/index.js:288:13)
localhost - - [25/Sep/2023:18:11:01 +0000] "GET / HTTP/1.1" - - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"'
When an event is captured by multiple event handlers, such as by having a @On('interactionCreate')
decorator, a new context will be created and sent to the various receiving parties.
While this is not bad or wrong it itself, it can cause an issue with global guards: If your guard replies or interacts to the interaction, as the guard will be executed multiple times, it can cause the message to be sent multiple times, or the second+ guard to trigger a discord error "Unknown interaction".
Note that even in the following code, as both interactions are technically a new context, interaction.replied
is false in both of them.
NecordExecutionContext.getInfo()
, with the entity on which the decorator is applied.interaction.replied
is properly populated.No response
No response
nest new necord_issue
app.module.ts
and main.ts
under src
folder)npm install necord discord.js
src
create folder discord
which will represent discord module of nest applicationdiscord
folder create discord.module.ts
file with following content and register this module inside app.module:import { GatewayIntentBits } from 'discord.js';
import { NecordModule } from 'necord';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot(),
NecordModule.forRoot({
token: process.env.DISCORD_BOT_TOKEN,
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMessageReactions,
],
development: [process.env.DISCORD_DEVELOPMENT_GUILD_ID],
}),
],
providers: [],
})
export class DiscordModule {}
discord.service.ts
with following content (to create slash command) and define it in discord.module.ts
inside providers arrayimport {
Context,
Options,
SlashCommand,
SlashCommandContext,
StringOption,
} from 'necord';
import { Injectable } from '@nestjs/common';
class TextDto {
@StringOption({
name: 'text',
description: 'Your text',
required: true,
})
text: string;
}
@Injectable()
export class DiscordService {
@SlashCommand({
name: 'length',
description: 'Get length of text',
})
public async onLength(
@Context() [interaction]: SlashCommandContext,
@Options() { text }: TextDto,
) {
return interaction.reply({ content: `Length of your text ${text.length}` });
}
}
npm i @nestjs/typeorm typeorm pg config @nestjs/config
app.module.ts
configure TypeOrmModule@Module({
imports: [
DiscordModule,
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.PG_HOST,
username: process.env.PG_USER,
password: process.env.PG_PASS,
database: process.env.PG_DATABASE,
ssl: true,
autoLoadEntities: true,
synchronize: true,
}),
],
controllers: [],
providers: [],
})
export class AppModule {}
E:\Learning\necord_issue\src\discord\discord.service.ts:29
return interaction.reply({ content: `Length of your text ${text.length}` });
^
TypeError: Cannot read properties of undefined (reading 'length')
at DiscordService.onLength (E:\Learning\necord_issue\src\discord\discord.service.ts:29:69)
at E:\Learning\necord_issue\node_modules\@nestjs\core\helpers\external-context-creator.js:69:29
at InterceptorsConsumer.intercept (E:\Learning\necord_issue\node_modules\@nestjs\core\interceptors\interceptors-consumer.js:12:20)
at target (E:\Learning\necord_issue\node_modules\@nestjs\core\helpers\external-context-creator.js:74:60)
at SlashCommandDiscovery.contextCallback (E:\Learning\necord_issue\node_modules\@nestjs\core\helpers\external-proxy.js:9:30)
at SlashCommandDiscovery.execute (E:\Learning\necord_issue\node_modules\necord\dist\context\necord-base.discovery.js:25:21)
at SlashCommandDiscovery.execute (E:\Learning\necord_issue\node_modules\necord\dist\commands\slash-commands\slash-command.discovery.js:45:22)
at Client.<anonymous> (E:\Learning\necord_issue\node_modules\necord\dist\commands\slash-commands\slash-commands.module.js:37:112)
at Client.emit (node:events:526:35)
at InteractionCreateAction.handle (E:\Learning\necord_issue\node_modules\discord.js\src\client\actions\InteractionCreate.js:97:12)
Link to repo with reproduction - https://github.com/iAmArbuzik/necord_issue
14.14.1
10.3.2
nodejs version - v20.10.0 typescript version - v5.3.3
OS Windows 11 (Version 10.0.22621)
High (immediate attention needed)
No Partials
GUILDS, GUILD_MESSAGES, GUILD_MESSAGE_REACTIONS
After v5.7.0, the commands that receive guilds
property are not registering this commands as Guild Application Commands, but as Global Application Commands.
At v5.6.1 it works fine.
No response
14.11.0
9.4.0
16.19.1
macOS
High (immediate attention needed)
No Partials
GUILDS, GUILD_MEMBERS, GUILD_MESSAGES
How to test the spec files ?
Looking for a guide that how to set this up with NestJs using Fastify. The simple configuration as mentioned in docs doesn't seem to work and raising errors.
C:\Users\Priyam\Documents\api-next\node_modules\@nestjs\platform-fastify\adapters\fastify-adapter.js:242
return !('status' in response);
^
TypeError: Cannot use 'in' operator to search for 'status' in undefined
at FastifyAdapter.isNativeResponse (C:\Users\Priyam\Documents\api-next\node_modules\@nestjs\platform-fastify\adapters\fastify-adapter.js:242:27)
at FastifyAdapter.reply (C:\Users\Priyam\Documents\api-next\node_modules\@nestjs\platform-fastify\adapters\fastify-adapter.js:117:35)
at ExceptionsFilter.catch (C:\Users\Priyam\Documents\api-next\dist\main.js:844:21)
at ExternalExceptionsHandler.invokeCustomFilters (C:\Users\Priyam\Documents\api-next\node_modules\@nestjs\core\exceptions\external-exceptions-handler.js:34:32)
at ExternalExceptionsHandler.next (C:\Users\Priyam\Documents\api-next\node_modules\@nestjs\core\exceptions\external-exceptions-handler.js:13:29)
at Object.execute (C:\Users\Priyam\Documents\api-next\node_modules\@nestjs\core\helpers\external-proxy.js:14:42)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
Node.js v17.1.0
.addGuilds()
.removeGuilds()
.hasGuild()
.
.
No response
No response
DJS collectors for :
abstract class :
methods on these classes
using interceptors, intercept the interactions/events and pass them to relevant contexts and methods
decorators based approach :
No response
Dynamic matching for customId of modals, similar to what is there for Components
pattern matching in ModalInteraction service
No response
No response
I didn't know this package existed until @jmcdo29 told me about it on the nestjs discord. It seems you support more than the @discord-nestjs/core
package. I made a recommendation to them about adding documentation for sharding, I created a simple explanation here.
I think adding something similar to your documentation would be extremely beneficial. It would also be worth your time to add examples using discord-hybrid-sharding
and discord-cross-hosting
packages I mentioned in the explanation above as this is super important for bots that require scale.
I would be more than happy to contribute to the documentation if this suits you!
So it's embarrassing to say this, but the PR #1117 I did yesterday has a bug...
I've been trying to find some way to fix this for 3h but I haven't found it
I did the PR on emotion and forgot to test before opening it ๐ฅ
In short, the client.user only stores the client user after it emits the Ready event, and the same goes for client.emojis , but seeing by this logic the GuildProvider(client.guilds) was not supposed to work but works
import { BaseGuildEmojiManager, Client, ClientUser } from "discord.js";
import { Module, OnApplicationBootstrap } from "@nestjs/common";
@Module({})
export class IssueModule implements OnApplicationBootstrap {
public constructor(
private readonly emojis: BaseGuildEmojiManager,
private readonly user: ClientUser,
private readonly client: Client
) {}
public onApplicationBootstrap () {
console.log(this.client.user)
console.log(this.user)
console.log(this.emojis.cache)
console.log(this.client.emojis.cache)
}
}
14.14.1
10.3.3
NodeJS v20.6.1 | TypeScript v5.4.2
Linux 5.15 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
Medium (should be fixed soon)
USER, CHANNEL, GUILD_MEMBER, MESSAGE, REACTION
GUILDS, GUILD_MEMBERS, GUILD_BANS, GUILD_EMOJIS_AND_STICKERS, GUILD_INTEGRATIONS, GUILD_WEBHOOKS, GUILD_INVITES, GUILD_VOICE_STATES, GUILD_PRESENCES, GUILD_MESSAGES, GUILD_MESSAGE_REACTIONS, GUILD_MESSAGE_TYPING, DIRECT_MESSAGES, DIRECT_MESSAGE_REACTIONS, DIRECT_MESSAGE_TYPING
A good addition would be to not have warning messages on newly scaffolded NestJS projects after adding Necord.
Add @nestjs/common
and @nestjs/core
^9.0.0
as optional peer dependency
No response
No response
When using command guilds
property, then changing name
after command has been registered doesn't remove the old one.
Maybe remove all guild commands and re-register all current one?
No response
No response
It is possible to get the discordjs client as a provider in others classes constructor? I didn't find about in documentation.
It would be good to see the sharding implementation using discord-hybrid-sharding and discord-cross-hosting packages. There are already mentions to those 2 packages in docs but no details.
Add configuration examples to docs.
No response
No response
@SlashGroup(name,description)
decorator on every subcommand method implementation. It would be really useful to minimize code repeatability while developing bots, also reduced source of developer related typo bugs.slash-command
|-subcommand-1
|-subcommand-2
|-subcommand-group-1
| |-subcommand-1
| |-subcommand-2
| |-subcommand-3
|-subcommand-group-2
|-subcommand-1
|-subcommand-2
|-subcommand-3
@SlashCommand
|--@SlashCommand-1
|--@SlashCommand-2
|--@SlashGroup-1
| @SlashCommand-1
|--@SlashGroup-1
| @SlashCommand-2
|--@SlashGroup-1
| @SlashCommand-3
|--@SlashGroup-2
| @SlashCommand-1
|--@SlashGroup-2
| @SlashCommand-2
|--@SlashGroup-2
| @SlashCommand-3
import {
Ctx,
SlashCommand,
SlashCommandContext,
SlashWithGroups,
Subcommand,
SubCommandGroup
} from 'necord';
@SubCommandGroup('utility', 'Basic utilities')
export class Utility {
@Subcommand('ping', 'Utility for checking network latency')
ping(@Ctx() [interaction]: SlashCommandContext) {
return interaction.reply('pong from subcommand in subcommand group');
}
}
@SlashCommand('help', 'Helpful information regarding bot')
export class SlashCommandWithSubcommands implements SlashWithGroups {
groups = [new Utility()];
@Subcommand('ping', 'pongs you !')
pingMe(@Ctx() [interaction]: SlashCommandContext) {
return interaction.reply('pong from subcommand');
}
}
No response
I am willing to submit a PR, I have a branch ready
defaultMemberPermissions
is allowed as configuration option for the @subcommand decorator, but does nothing when set.
import {
PermissionFlagsBits,
} from 'discord.js';
import {
Context,
SlashCommandContext,
Subcommand,
} from 'necord';
@Subcommand({
name: 'command',
description: 'Bla',
defaultMemberPermissions: [PermissionFlagsBits.Administrator],
})
public async onCommand(
@Context() [interaction]: SlashCommandContext,
): Promise<InteractionResponse<boolean>> {
// func
}
14.13.0
10.2.7
18.17.1
MacOS but running in docker with official alpine node image
Medium (should be fixed soon)
No Partials
GUILDS
The current @Button
decorator only accepts strings, which is limiting if we want to support dynamic button id's.
To store a bit of metadata within buttons, as they do not have a value
property, we need to store it within the id.
For example, if we want to have a button to approve or decline an event, they have the id approve:1234
, where approve
is the action, and 1234
the id of the even which we want to approve.
This is loosely equivalent to a route for /approve/:id
if it were a controller.
The idea behind this feature is to add support for dynamic matching.
The easiest solution would be to support string | regex
and to use buttonId.test(regex)
to match the routes.
The user can then access the id and find his own arguments using button.id
.
An enhancement would be to support named captures: @Button(/^approve:(?<id>\d+/)
, and add the captures or the match as a whole as an argument similarly to @Options
for @SlashCommands
.
To get a simpler solution not involving regex, there could be a matching system similar to routes in controllers, where the named arguments would be described within the string: approve/:id
to match ^approve/(?<id>.*)
Finally this could be accessed via a decorator such as @Param('id')
in the event listener.
This would require more work to convert strings to regexes to matches, but could be a simple approach compared to having users do their own regexes, and be similar to routes for controllers.
No response
As guild commands and global commands have a different timeout, the global ones being cached for up to an hour, development is best done with guild commands when possible.
For this purpose, I suggest a way to pass a development guild id to necord, which would do the same as adding the @Guilds
decorator on all commands, applying it globally.
I believe this would be best applied within the necord module configuration:
NecordModule.forRoot({
token: "token",
intents: [],
isDevelopment: false | "guild" | "guilds"[]
}),
No response
No response
Hello,
First and foremost thanks for releasing this, much appreciated!
I am building a new version of a bot I previously created with discord.js. One of the features I previously used was a centralised error catching for all my slash commands. This includes old commands that I removed, but are still pending in the guild.
Is there a place where to create this catchall for errors?
Thanks
...
No response
No response
Add support for multiple @Autocomplete
on a single command.
At the moment, to support multiple autocomplete fields, one must add this feature within the autocompleter itself, by using focused.name
to find out which component it needs to autocomplete.
switch(focused.name) {
case 'color':
...
case 'meal'
...
default:
[]
}
This makes it hard to reuse the same autocomplete logic across components: If many commands rely on the colorAutocomplete, but only one of them needs to also autocomplete the meal, you would need to manually merge both of them for this one command.
I would like to add support for autocomplete chaining:
@Autocomplete(colorAutocomplete, mealAutocomplete)
This would run all of the autocompletes until one returns data, allowing them to return a falsy value if the autocomplete is not made for this input.
This would also open the way for a Global autocomplete, filtering itself from of the input.name, to reduce boilerplate:
NecordModule.forRoot({
// ...
globalAutocomplete: [ colorAutocomplete ]
}),
No response
No response
Slash command arguments are currently sorted in the order they are in the class, and can't be reordered within necord.
I'd recommend to have an index: number
property added to the various command options (StringOption
, BooleanOption
, etc.) to specify the order in which we want them to appear.
Adding an index
property on the various comand options:
@StringOption({
name: "option",
description:
"The rsn for one of your accounts (defaults to all accounts if no rsn is provided)",
required: false,
autocomplete: true,
index: 2,
})
No response
No response
Hey! Currently NecordEvents has quite a lot of events that are really helpful, but most of ws-events are missing, and they are really useful for debugging and other stuff.
Allow the @on decorator to handle the missing ws-events.
No response
No response
Hi, do I need to manually set up /interactions route and direct requests to discord service? From reading documentation I was under the impression that it'd be done automatically by NecordModule during setup. Could you please clarify, many thanks.
I have three channels within different self-bot, and I want to listen multiple bot messages in a NestApp.
How can i add multiple bots within the same NestJs App?
Thanks for your help!
After v6.1.0
released, sub-commands weren't appearing as application commands. Downgrading to v6.0.0
fixed that.
import { Injectable } from '@nestjs/common';
import { Subcommand, createCommandGroupDecorator } from 'necord';
const DemoCommands = createCommandGroupDecorator({
name: 'demo',
description: 'Just a demo command group',
});
@Injectable()
@DemoCommands()
export class TestCommands {
@Subcommand({ name: 'first', description: 'First demo command' })
async demoFirst() {}
@Subcommand({ name: 'second', description: 'Second demo command' })
async demoSecond() {}
}
14.13.0
10.2.1
18.17.1
Ubuntu 22.04.3 LTS
Medium (should be fixed soon)
No Partials
GUILDS, GUILD_MEMBERS, GUILD_VOICE_STATES, GUILD_PRESENCES, GUILD_MESSAGES
This Issue relies on discordjs/discord-api-types#272 and discord/discord-api-docs#4253
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.