Documentação/Base do Core
BASE DO CORE / INTERAÇÕES

Interações

Entenda respostas, modais, autocomplete e o contexto normalizado usado em todos os fluxos interativos.

RepliesModalAutocomplete

O ciclo de uma resposta#

Uma interação pode receber uma resposta inicial e depois ser editada ou acompanhada por mensagens adicionais.

MétodoQuando usar
reply()Primeira resposta imediata
deferReply()Reserva a resposta quando o trabalho demora
editReply()Finaliza ou atualiza a resposta reservada
followUp()Envia uma resposta adicional
deleteReply()Remove a resposta original
TSresposta demorada
Client.slash({  data: new SlashCommandBuilder()    .setName('relatorio')    .setDescription('Gera um relatório detalhado.'),  execute: async interaction => {    await interaction.deferReply({ flags: 64 })    const report = await generateReport(interaction.guildId)    await interaction.editReply('Relatório pronto: ' + report.url)    await interaction.followUp({      content: 'A exportação expira em 24 horas.',      flags: 64    })  }})

Contexto normalizado#

O Core fornece uma superfície comum e mantém a interação original em interaction.interaction quando você precisa estreitar o tipo.

U

Identidade

user, member, guild, guildId, channel e channelId.

R

Resposta

reply, deferReply, editReply, followUp e estado da resposta.

C

Core

promptRequest, paginatorRequest, configuração e contexto isolado.

D

Discord.js

A propriedade interaction preserva a interação nativa completa.

TSacesso à configuração da guild atual
Client.slash({  data: new SlashCommandBuilder()    .setName('canal-suporte')    .setDescription('Mostra o canal configurado.'),  execute: async interaction => {    const config = Client.appConfig()    const supportChannel = Client.getAppChannels().support    await interaction.reply({      content: 'Canal: ' + (supportChannel?.toString() ?? 'não configurado'),      flags: 64    })  }})

Abrindo um modal#

O comando constrói o modal; um módulo separado registra o handler para o mesmo customId.

TSDiscord/Commands/Feedback.ts
import {  ActionRowBuilder,  ModalBuilder,  SlashCommandBuilder,  TextInputBuilder,  TextInputStyle} from '@ninenity/core'import Client from '../../Shared/Settings/Client'Client.slash({  data: new SlashCommandBuilder()    .setName('feedback')    .setDescription('Abre o formulário de feedback.'),  execute: async interaction => {    const input = new TextInputBuilder()      .setCustomId('message')      .setLabel('Como podemos melhorar?')      .setStyle(TextInputStyle.Paragraph)      .setMinLength(10)      .setMaxLength(1000)      .setRequired(true)    const modal = new ModalBuilder()      .setCustomId('feedback-modal')      .setTitle('Enviar feedback')      .addComponents(new ActionRowBuilder<TextInputBuilder>().addComponents(input))    await interaction.interaction.showModal(modal)  }})
TSDiscord/Interactions/FeedbackModal.ts
import Client from '../../Shared/Settings/Client'Client.modal({  customId: 'feedback-modal',  execute: async interaction => {    const text = interaction.fields.getTextInputValue('message')    await saveFeedback({      authorId: interaction.user.id,      guildId: interaction.guildId,      text    })    await interaction.reply({      content: 'Obrigado pelo feedback!',      flags: 64    })  }})

Autocomplete#

Declare a opção com autocomplete no comando e responda com até 25 sugestões.

TSDiscord/Commands/Search.ts
Client.slash({  data: new SlashCommandBuilder()    .setName('buscar')    .setDescription('Busca um projeto.')    .addStringOption(option => option      .setName('projeto')      .setDescription('Nome do projeto')      .setAutocomplete(true)      .setRequired(true)),  autocomplete: async interaction => {    const query = interaction.options.getFocused().toLowerCase()    const choices = projects      .filter(project => project.name.toLowerCase().includes(query))      .slice(0, 25)      .map(project => ({ name: project.name, value: project.id }))    await interaction.respond(choices)  },  execute: async interaction => {    const projectId = interaction.options.getString('projeto', true)    await interaction.reply('Projeto escolhido: ' + projectId)  }})

Prompts e paginações registrados#

Depois de registrar uma definição uma vez, qualquer slash ou prefix pode iniciar uma instância isolada para o usuário.

TSDiscord/Commands/Flows.ts
Client.slash({  data: new SlashCommandBuilder()    .setName('confirmar')    .setDescription('Abre um prompt.'),  execute: async interaction => {    await interaction.promptRequest('delete-prompt', { ephemeral: true })  }})Client.prefix({  data: new PrefixCommandBuilder().setName('confirmar'),  execute: async interaction => {    await interaction.promptRequest('delete-prompt', { ephemeral: true })  }})Client.slash({  data: new SlashCommandBuilder()    .setName('catalogo')    .setDescription('Abre o catálogo paginado.'),  execute: async interaction => {    await interaction.paginatorRequest('catalog-pages', {      ephemeral: true,      pageIndex: 0    })  }})

A criação das definições fica em Discord/Interactions. Consulte as páginas Prompts e Paginação para montar templates, callbacks e controles personalizados.