Pular para o conteúdo principal

Decorators

Referência seca. A explicação de como usar está em Eventos e Comandos.

import {
NescordModule, NescordHandler,
On, Once, SlashCommand, UseNescordGuards,
Ctx, Options, Opt, Rest,
InjectConcordClient,
NescordService, NescordCommandRegistry, NescordExplorer,
type EventContext, type SlashCommandContext, type CommandContext,
} from 'nescord';

Módulo​

NescordModule.forRoot(options?)​

@Module({
imports: [
NescordModule.forRoot({
token: process.env.CONCORD_TOKEN,
baseUrl: process.env.CONCORD_URL,
presence: '',
commands: { prefix: '/', ignoreBots: true },
}),
],
providers: [MeuHandler],
})
export class AppModule {}

Aceita tudo que o ClientOptions do concord.js aceita, mais:

OpçãoPadrãoO que é
tokenprocess.env.CONCORD_TOKENToken de sessão
commandsver abaixoDespacho de comandos por mensagem
client—Reaproveita um Client já criado (teste, bot dentro de app maior)
autoLogintruefalse quando o bootstrap é manual
logger—Logger do concord.js

O módulo registra o Client, o explorer e o despachante. O login acontece em onApplicationBootstrap, depois de ligar os handlers — assim nenhum evento se perde entre o ready e o bind.

NescordModule.forRootAsync(options)​

NescordModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
token: config.getOrThrow('CONCORD_TOKEN'),
baseUrl: config.get('CONCORD_URL'),
}),
});

Também aceita useClass / useExisting com uma NescordOptionsFactory:

@Injectable()
export class NescordConfig implements NescordOptionsFactory {
createNescordOptions(): NescordModuleOptions {
return { token: process.env.CONCORD_TOKEN };
}
}

NescordCommandOptions​

CampoPadrãoO que é
prefix'/'Prefixo dos comandos de texto
allowMentiontrueTambém aceita @meubot comando
ignoreBotstrueIgnora mensagens de bot (evita laço)
caseInsensitivetrueNome do comando sem distinção de caixa
unknownCommandReplynullResposta a comando inexistente. null cala a boca
interactionInboxdesligado{ enabled, intervalMs? } — fonte REST por polling

Decorators de método​

@On(event)​

Liga o método a um evento do Client. Pode repetir no mesmo método.

@On('messageCreate')
onMessage(@Ctx() [message]: EventContext<'messageCreate'>) {}

@Once(event)​

Igual, mas desliga depois da primeira vez.

@Once('ready')
onReady(@Ctx() [client]: EventContext<'ready'>) {}

@SlashCommand(meta)​

Comando de texto despachado de messageCreate.

CampoPadrãoO que é
name—Obrigatório
description—Obrigatório. Aparece no /help
aliases—Apelidos
options—SlashCommandOptionMeta[]
permissions—Bits exigidos de quem chamou
serverOnlytrueRecusa em DM
ownerOnlyfalseSó o dono do servidor
cooldown0Segundos entre chamadas por pessoa

SlashCommandOptionMeta:

CampoPadrãoO que é
name—Obrigatório
description—Obrigatório
type'string'string, integer, number, boolean, user, channel, rest
requiredfalse
choices—Valores aceitos

rest engole o resto da linha, então só pode ser a última opção.

@UseNescordGuards(...guards)​

Vale em método e em classe.

@Injectable()
export class SoDeDia implements NescordGuard {
canActivate(ctx: CommandContext): boolean {
return new Date().getHours() >= 8;
}
}
@UseNescordGuards(SoDeDia)
@SlashCommand({ name: 'barulho', description: 'Toca algo alto' })
async barulho(@Ctx() [ctx]: SlashCommandContext) {}

Decorators de parâmetro​

DecoratorInjeta
@Ctx()A tupla do contexto: [args…] do evento, ou [ctx] do comando
@Options()Todas as opções convertidas, como objeto
@Opt(name)Uma opção pelo nome
@Rest()A linha crua depois do nome do comando
@SlashCommand({
name: 'mover',
description: 'Move alguém para outro canal de voz',
options: [
{ name: 'quem', description: 'A pessoa', type: 'user', required: true },
{ name: 'para', description: 'O canal', type: 'channel', required: true },
],
})
async mover(
@Ctx() [ctx]: SlashCommandContext,
@Opt('quem') quem: User,
@Opt('para') para: Channel,
) {}

Decorator de classe​

@NescordHandler()​

Marca a classe como alvo do explorer. É opcional: um @Injectable() registrado em providers já é varrido.

Injeção​

@InjectConcordClient()​

@Injectable()
export class MeuHandler {
constructor(@InjectConcordClient() private readonly client: Client) {}
}

Equivale a @Inject(NESCORD_CLIENT).

Serviços injetáveis​

NescordService​

@Injectable()
export class Admin {
constructor(private readonly nescord: NescordService) {}

async reconectar() {
await this.nescord.destroy();
await this.nescord.login();
}
}

Expõe client, commands, login(token?) e destroy().

NescordCommandRegistry​

registry.commands; // ReadonlyMap<string, SlashCommandMeta>
registry.get('play');
await registry.publish(); // anuncia à aplicação e, com installToken, à instalação

publish() manda a lista para PUT /api/applications/@me/commands quando o cliente usa token de bot — é o que o seletor do chat mostra ao digitar / — e para POST /api/bots/commands quando há installToken. O nescord chama isso sozinho ao subir. Nunca falha: Concord sem a rota só gera um aviso no log.

NescordExplorer​

explorer.handlers;
// [{ event: 'messageCreate', once: false, provider: 'PingHandler', method: 'onMessage' }, …]

O que ficou ligado. Serve para teste e para o log de inicialização. Um handler que estoura é capturado e vira evento error do Client — nunca derruba o processo.

Contexto​

export type Context<T extends readonly unknown[]> = T;
export type EventContext<K extends ClientEventName> = Context<ClientEvents[K]>;
export type SlashCommandContext = Context<[CommandContext]>;

CommandContext está detalhado em Comandos.

Tokens de injeção​

SímboloO que é
NESCORD_OPTIONSAs opções do módulo
NESCORD_CLIENTO Client
NESCORD_HANDLERMetadado de handler, lido pelo explorer
NESCORD_COMMANDMetadado de comando
NESCORD_GUARDSMetadado de guards

Os três últimos são detalhe interno: só o explorer os lê.