Ir para o conteúdo principal

Slash Commands

Comandos de Golpe são a nova e emocionante maneira de construir e interagir com bots no Discord. Com Slash Commands, tudo que você tem que fazer é digitar / e você estará pronto para utilizar seu bot favorito. Você pode ver facilmente todos os comandos que um bot tem, e a validação e a manipulação de erros ajudam você a obter o comando corretamente na primeira vez.

Slash Commands

Comandos Globais

tip

Comandos globais são armazenados em cache por uma hora. Novos comandos globais vão se espalhar lentamente em todas as guildas e só será garantido que serão atualizados após uma hora. Comandos de servidor atualizam instantaneamente. Com isso, recomendamos que você use comandos baseados a servidores durante o desenvolvimento e publique eles como comandos globais quando eles estiverem prontos para o uso do público.

Leia mais sobre configuração modo dev

Crie o arquivo app.commands.ts e adicione um método com o decorador SlashCommand.

app.commands.ts
import { Injectable } from '@nestjs/common';
import { Context, SlashCommand, SlashCommandContext } from 'necord';

@Injectable()
export class AppCommands {
@SlashCommand({
name: 'ping',
description: 'Ping-Pong Command'
})
public async onPing(@Context() [interaction]: SlashCommandContext): Promise<void> {
await interaction.reply({ content: 'Pong!' });
}
}

Comandos de Servidor

Se você quer ter comandos específicos de um servidor, use a propriedade guilds no decorador SlashCommand

app.commands.ts
import { Injectable } from '@nestjs/common';
import { Context, SlashCommand, SlashCommandContext } from 'necord';

@Injectable()
export class AppCommands {
@SlashCommand({
name: 'ping',
description: 'Ping-Pong Command',
guilds: [process.env.DEV_GUILD!]
})
public async onPing(@Context() [interaction]: SlashCommandContext): Promise<void> {
await interaction.reply({ content: 'Pong!' });
}
}

Você pode usar decoradores em classes e métodos.

Opções

Use o decorador de opção para definir um parâmetro em um slash command, vamos criar a classe LengthDto:

length.dto.ts
import { StringOption } from 'necord';

export class TextDto {
@StringOption({
name: 'text',
description: 'Your text',
required: true
})
public readonly text!: string;
}

Tem apenas uma propriedade básica. Então, nós podemos usar o recém-criado DTO dentro do AppCommands:

app.commands.ts
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: 'Get length of text'
})
public async onLength(
@Context() [interaction]: SlashCommandContext,
@Options() { text }: TextDto
): Promise<void> {
await interaction.reply({ content: `Length of your text ${text.length}` });
}
}

Lista de todos os decoradores de opção incorporados:

DecoradorTipoDescrição
StringOptionstringUma opção de texto
NumberOptionnumberUma opção numérica
IntegerOptionnumberUma opção de inteiro
BooleanOptionbooleanUma opção booleana
UserOptionUserUma opção de usuário
MemberOptionGuildMemberUma opção de membro
ChannelOptionGuildChannelUma opção de canal
RoleOptionRoleUma opção de cargo
MentionableOptionGuildMember | Role | UserUma opção mencionável
AttachmentOptionAttachmentUma opção de anexo

Autocompletar

Para adicionar autocompletar ao seu slash command você precisará de um interceptor primeiro. Esta classe interceptará todas as solicitações do usuário depois de digitar o campo de opção de preenchimento automático

anime.interceptor.ts
import { Injectable } from '@nestjs/common';
import { AutocompleteInteraction } from 'discord.js';
import { AutocompleteInterceptor } from 'necord';

@Injectable()
export class AnimeAutocompleteInterceptor extends AutocompleteInterceptor {
public transformOptions(interaction: AutocompleteInteraction): Promise<void> {
const focused = interaction.options.getFocused(true);
const choices =
focused.name === 'anime' ? ['Hunter x Hunter', 'Naruto', 'One Piece'] : [];

return interaction.respond(
choices
.filter(choice => choice.startsWith(focused.value.toString()))
.map(choice => ({ name: choice, value: choice }))
);
}
}

Você terá que adicionar autoComplete: true para sua classe de opções:

anime.dto.ts
import { StringOption } from 'necord';

export class AnimeDto {
@StringOption({
name: 'anime',
description: 'The anime to look up',
autocomplete: true,
required: true
})
public readonly anime!: string;
}

E por último, mas não menos importante, aplicar o interceptor ao seu slash command

anime-commands.service.ts
import { Injectable, UseInterceptors } from '@nestjs/common';
import { Context, SlashCommand, Options, SlashCommandContext } from 'necord';
import { AnimeDto } from './anime.dto';
import { AnimeAutocompleteInterceptor } from './anime.interceptor';

@Injectable()
export class AnimeCommands {
@UseInterceptors(AnimeAutocompleteInterceptor)
@SlashCommand({
name: 'anime',
description: 'Lookup information about an anime'
})
public async onSearch(
@Context() [interaction]: SlashCommandContext,
@Options() { anime }: AnimeDto
): Promise<void> {
await interaction.reply({ content: `I found the anime ${anime}` });
}
}

Grupos

DICA

Para esses desenvolvedores que desejam fazer grupos de comandos mais organizados e complexos, procure apenas subgrupos e grupos.

Use decoradores SlashGroup em nível de classe (Grupo) e nível método (Subgrupo):

utils-commands.service.ts
import { Injectable } from '@nestjs/common';
import {
Context,
createCommandGroupDecorator,
SlashCommandContext,
Subcommand
} from 'necord';

export const UtilsCommandDecorator = createCommandGroupDecorator({
name: 'utils',
description: 'Utils group',
});

@UtilsCommandDecorator()
@Injectable()
export class UtilsCommands {
@Subcommand({
name: 'ping',
description: 'Ping-pong command'
})
public async onPing(@Context() [interaction]: SlashCommandContext): Promise<void> {
await interaction.reply({ content: 'Pong!' });
}
}

@UtilsCommandDecorator({
name: 'string',
description: 'String utility commands'
})
@Injectable()
export class UtilsStringCommands {
@Subcommand({
name: 'length',
description: 'String length command'
})
public async onLength(@Context() [interaction]: SlashCommandContext): Promise<void> {
await interaction.reply({ content: 'Use this subcommand to measure text.' });
}
}


Após os comandos serem registrados, o bot irá processar os comandos /utilidades ping e /utilidades texto tamanho, como aqui:

Comandos

Você pode ver um exemplo funcional aqui.