Necord
Necord 是一个强大的模块,可简化 Discord 机器人的创建过程,实现与 NestJS 应用的无缝集成。
注意 Necord 是第三方包,并非由 NestJS 核心团队官方维护。如遇任何问题,请提交至 官方仓库 。
安装
开始使用前,需安装 Necord 及其依赖项 Discord.js
。
$ npm install necord discord.js
使用方法
要在项目中使用 Necord,请导入 NecordModule
并使用必要的选项进行配置。
@@filename(app.module)
import { Module } from '@nestjs/common';
import { NecordModule } from 'necord';
import { IntentsBitField } from 'discord.js';
import { AppService } from './app.service';
@Module({
imports: [
NecordModule.forRoot({
token: process.env.DISCORD_TOKEN,
intents: [IntentsBitField.Flags.Guilds],
development: [process.env.DISCORD_DEVELOPMENT_GUILD_ID],
}),
],
providers: [AppService],
})
export class AppModule {}
info 提示 您可以在此处 here 找到可用意图的完整列表。
通过此设置,您可以将 AppService
注入到提供者中,轻松注册命令、事件等功能。
@@filename(app.service)
import { Injectable, Logger } from '@nestjs/common';
import { Context, On, Once, ContextOf } from 'necord';
import { Client } from 'discord.js';
@Injectable()
export class AppService {
private readonly logger = new Logger(AppService.name);
@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);
}
}
理解上下文
你可能已经注意到上面例子中的 @Context
装饰器。这个装饰器会将事件上下文注入到你的方法中,让你能够访问各种事件特定数据。由于存在多种事件类型,上下文类型是通过 ContextOf<type: string>
类型推断的。你可以轻松地通过使用 @Context()
装饰器来访问上下文变量,该装饰器会用与事件相关的参数数组填充变量。
文本命令
警告 文本命令依赖于消息内容,而该功能即将对已验证机器人和拥有超过 100 个服务器的应用程序弃用。这意味着如果你的机器人无法访问消息内容,文本命令将无法工作。了解更多关于此变更的信息请点击此处 。
下面展示如何使用 @TextCommand
装饰器为消息创建一个简单的命令处理器。
@@filename(app.commands)
import { Injectable } from '@nestjs/common';
import { Context, TextCommand, TextCommandContext, Arguments } from 'necord';
@Injectable()
export class AppCommands {
@TextCommand({
name: 'ping',
description: 'Responds with pong!',
})
public onPing(
@Context() [message]: TextCommandContext,
@Arguments() args: string[],
) {
return message.reply('pong!');
}
}
应用命令
应用命令为用户提供了一种在 Discord 客户端内与您的应用交互的原生方式。可通过不同界面访问三种类型的应用命令:聊天输入命令、消息上下文菜单命令(通过右键点击消息访问)和用户上下文菜单命令(通过右键点击用户访问)。

斜杠命令
斜杠命令是以结构化方式与用户互动的绝佳途径。它们允许您创建具有精确参数和选项的命令,从而显著提升用户体验。
要使用 Necord 定义斜杠命令,可以使用 SlashCommand
装饰器。
@@filename(app.commands)
import { Injectable } from '@nestjs/common';
import { Context, SlashCommand, SlashCommandContext } from 'necord';
@Injectable()
export class AppCommands {
@SlashCommand({
name: 'ping',
description: 'Responds with pong!',
})
public async onPing(@Context() [interaction]: SlashCommandContext) {
return interaction.reply({ content: 'Pong!' });
}
}
提示 当你的机器人客户端登录时,它会自动注册所有已定义的命令。请注意全局命令最多会被缓存一小时。为避免全局缓存问题,请使用 Necord 模块中的 development
参数,该参数会将命令可见性限制在单个服务器中。
选项
你可以使用选项装饰器为斜杠命令定义参数。为此我们创建一个 TextDto
类:
@@filename(text.dto)
import { StringOption } from 'necord';
export class TextDto {
@StringOption({
name: 'text',
description: 'Input your text here',
required: true,
})
text: string;
}
然后你就可以在 AppCommands
类中使用这个 DTO:
@@filename(app.commands)
import { Injectable } from '@nestjs/common';
import { Context, SlashCommand, Options, SlashCommandContext } from 'necord';
import { TextDto } from './length.dto';
@Injectable()
export class AppCommands {
@SlashCommand({
name: 'length',
description: 'Calculate the length of your text',
})
public async onLength(
@Context() [interaction]: SlashCommandContext,
@Options() { text }: TextDto,
) {
return interaction.reply({
content: `The length of your text is: ${text.length}`,
});
}
}
要查看完整的内置选项装饰器列表,请查阅此文档 。
自动补全
要为斜杠命令实现自动补全功能,您需要创建一个拦截器。该拦截器将处理用户在自动补全字段中输入时的请求。
@@filename(cats-autocomplete.interceptor)
import { Injectable } from '@nestjs/common';
import { AutocompleteInteraction } from 'discord.js';
import { AutocompleteInterceptor } from 'necord';
@Injectable()
class CatsAutocompleteInterceptor extends AutocompleteInterceptor {
public transformOptions(interaction: AutocompleteInteraction) {
const focused = interaction.options.getFocused(true);
let choices: string[];
if (focused.name === 'cat') {
choices = ['Siamese', 'Persian', 'Maine Coon'];
}
return interaction.respond(
choices
.filter((choice) => choice.startsWith(focused.value.toString()))
.map((choice) => ({ name: choice, value: choice })),
);
}
}
您还需要用 autocomplete: true
标记您的选项类:
@@filename(cat.dto)
import { StringOption } from 'necord';
export class CatDto {
@StringOption({
name: 'cat',
description: 'Choose a cat breed',
autocomplete: true,
required: true,
})
cat: string;
}
最后,将拦截器应用到您的斜杠命令:
@@filename(cats.commands)
import { Injectable, UseInterceptors } from '@nestjs/common';
import { Context, SlashCommand, Options, SlashCommandContext } from 'necord';
import { CatDto } from '/cat.dto';
import { CatsAutocompleteInterceptor } from './cats-autocomplete.interceptor';
@Injectable()
export class CatsCommands {
@UseInterceptors(CatsAutocompleteInterceptor)
@SlashCommand({
name: 'cat',
description: 'Retrieve information about a specific cat breed',
})
public async onSearch(
@Context() [interaction]: SlashCommandContext,
@Options() { cat }: CatDto,
) {
return interaction.reply({
content: `I found information on the breed of ${cat} cat!`,
});
}
}
用户上下文菜单
用户命令出现在右击(或点击)用户时显示的上下文菜单中。这些命令提供直接针对用户的快速操作。
@@filename(app.commands)
import { Injectable } from '@nestjs/common';
import { Context, UserCommand, UserCommandContext, TargetUser } from 'necord';
import { User } from 'discord.js';
@Injectable()
export class AppCommands {
@UserCommand({ name: 'Get avatar' })
public async getUserAvatar(
@Context() [interaction]: UserCommandContext,
@TargetUser() user: User,
) {
return interaction.reply({
embeds: [
new MessageEmbed()
.setTitle(`Avatar of ${user.username}`)
.setImage(user.displayAvatarURL({ size: 4096, dynamic: true })),
],
});
}
}
消息上下文菜单
右键点击消息时,上下文菜单中会显示消息命令,可快速执行与该消息相关的操作。
@@filename(app.commands)
import { Injectable } from '@nestjs/common';
import { Context, MessageCommand, MessageCommandContext, TargetMessage } from 'necord';
import { Message } from 'discord.js';
@Injectable()
export class AppCommands {
@MessageCommand({ name: 'Copy Message' })
public async copyMessage(
@Context() [interaction]: MessageCommandContext,
@TargetMessage() message: Message,
) {
return interaction.reply({ content: message.content });
}
}
按钮
按钮是可在消息中包含的交互元素。点击时,它们会向您的应用程序发送一个交互 。
@@filename(app.components)
import { Injectable } from '@nestjs/common';
import { Context, Button, ButtonContext } from 'necord';
@Injectable()
export class AppComponents {
@Button('BUTTON')
public onButtonClick(@Context() [interaction]: ButtonContext) {
return interaction.reply({ content: 'Button clicked!' });
}
}
选择菜单
选择菜单是消息中出现的另一种交互组件,它为用户提供类似下拉框的界面来选择选项。
@@filename(app.components)
import { Injectable } from '@nestjs/common';
import { Context, StringSelect, StringSelectContext, SelectedStrings } from 'necord';
@Injectable()
export class AppComponents {
@StringSelect('SELECT_MENU')
public onSelectMenu(
@Context() [interaction]: StringSelectContext,
@SelectedStrings() values: string[],
) {
return interaction.reply({ content: `You selected: ${values.join(', ')}` });
}
}
如需查看内置选择菜单组件的完整列表,请访问此链接 。
模态框
模态框是弹出式表单,允许用户提交格式化的输入内容。以下是使用 Necord 创建和处理模态框的方法:
@@filename(app.modals)
import { Injectable } from '@nestjs/common';
import { Context, Modal, ModalContext } from 'necord';
@Injectable()
export class AppModals {
@Modal('pizza')
public onModal(@Context() [interaction]: ModalContext) {
return interaction.reply({
content: `Your fav pizza : ${interaction.fields.getTextInputValue('pizza')}`
});
}
}
更多信息
访问 Necord 官网获取更多信息。