Boutons
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);
});| Champ | Détail |
|---|---|
id | Repris par module.button(id). Minuscules, chiffres et tirets, 31 caractères. |
label | Texte du bouton. |
style | primary (bleu), secondary (gris, par défaut), success (vert), danger (rouge). |
emoji | Un émoji. |
arg | Une 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.
Menus de choix
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
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.
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.