Boutons, menus et formulaires

Mode code

Les composants rendent un message interactif. Chaque clic, choix ou formulaire arrive dans le gestionnaire qui porte le même identifiant.

Boutons

JavaScript
module.command('sondage', async (ctx) => {
  const numero = String(await ctx.storage.increment('sondages'));
  await ctx.send(ctx.config.salon, {
    title: ctx.args.question,
    buttons: [
      { id: 'vote', label: 'Oui (0)', style: 'success', arg: numero + '-oui' },
      { id: 'vote', label: 'Non (0)', style: 'danger', arg: numero + '-non' },
    ],
  });
});

module.button('vote', async (ctx) => {
  const [numero, choix] = ctx.button.arg.split('-');
  await ctx.reply('Vote enregistré : ' + choix + ' au sondage ' + numero);
});
ChampDétail
idRepris par module.button(id). Minuscules, chiffres et tirets, 31 caractères.
labelTexte du bouton.
styleprimary (bleu), secondary (gris, par défaut), success (vert), danger (rouge).
emojiUn émoji.
argUne valeur libre (40 caractères, sans « : ») renvoyée dans ctx.button.arg. Idéal pour savoir quel élément est concerné.

ctx.setButtonLabels({ vote: 'Oui (3)' }) change le texte de boutons du message cliqué, par identifiant. ctx.edit(…) remplace tout le message.

JavaScript
await ctx.reply({
  text: 'Choisis ton jeu :',
  select: {
    id: 'jeu',
    placeholder: 'Ton jeu préféré',
    options: [
      { value: 'lol', label: 'League of Legends', emoji: '⚔️' },
      { value: 'mc', label: 'Minecraft', emoji: '⛏️' },
    ],
  },
});

module.select('jeu', async (ctx) => {
  await ctx.edit('Tu as choisi ' + ctx.select.value + '.');
});

En message brut, tous les menus Discord sont possibles (membres, rôles, salons, plusieurs choix) : leur custom_id est repris par module.select, et ctx.select.values contient tous les choix.

Formulaires

Simple : ctx.openForm

JavaScript
module.button('postuler', async (ctx) => {
  await ctx.openForm({
    id: 'candidature',
    title: 'Candidature',
    fields: [
      { key: 'pseudo', label: 'Ton pseudo en jeu', style: 'short' },
      { key: 'pourquoi', label: 'Pourquoi toi ?', max: 1000 },
    ],
  });
});

module.form('candidature', async (ctx) => {
  await ctx.send(ctx.config.staff, ctx.member.mention + ' : ' + ctx.form.values.pourquoi);
  await ctx.reply('Merci, ta candidature est envoyée !');
});

5 questions au maximum. style: 'short' pour une ligne, required: false pour une question facultative, placeholder pour un exemple. Le formulaire doit être la première réponse à la commande, au clic ou au menu.

Avancé : ctx.showModal

ctx.showModal envoie une fenêtre au format Discord brut : champs texte, et composants « label » (type 18) contenant un menu de choix.

JavaScript
await ctx.showModal({
  custom_id: 'avis',
  title: 'Ton avis',
  components: [
    { type: 18, label: 'Note', component: { type: 3, custom_id: 'note', options: [{ label: '5 ⭐', value: '5' }, { label: '3 ⭐', value: '3' }] } },
    { type: 18, label: 'Commentaire', component: { type: 4, custom_id: 'texte', style: 2 } },
  ],
});

module.form('avis', async (ctx) => {
  const note = ctx.form.values.note[0];
  await ctx.reply('Merci pour ta note de ' + note + ' !');
});

Identifiants

Opale préfixe automatiquement les identifiants de tes composants pour qu’ils n’entrent jamais en conflit avec un autre module. Tu écris vote, tu reçois vote. Un identifiant invalide (majuscules, espaces) est refusé à l’envoi.

Boutons, menus et formulaires · Documentation Opale