Structure d’un module

Mode code

Un module en code enregistre des gestionnaires avec l’objet global module. Opale appelle le bon gestionnaire, avec un contexte ctx, chaque fois que quelque chose arrive.

Les gestionnaires

FonctionAppelée quand…À déclarer
module.command(nom, fn)quelqu’un tape /nomOui, dans Commandes et listes
module.on(événement, fn)un événement arrive sur le serveur (liste)Non
module.button(id, fn)quelqu’un clique sur un bouton envoyé par le moduleNon
module.select(id, fn)quelqu’un choisit dans un menu envoyé par le moduleNon
module.form(id, fn)quelqu’un envoie un formulaire ouvert par le moduleNon
module.autocomplete(commande, fn)quelqu’un remplit une option « autocomplete »La commande et l’option
module.userMenu(nom, fn)clic droit sur un membre › Applications › nomOui
module.messageMenu(nom, fn)clic droit sur un message › Applications › nomOui
module.action(id, fn)l’admin clique sur un bouton du dashboardOui
module.row(id, fn)l’admin clique sur le bouton d’une ligne de listeOui, sur la liste
module.every(id, quand, fn)à intervalle régulier ou à heure fixeNon
module.task(nom, fn)une tâche lancée par ctx.later arrive à échéanceNon
module.uses(...éléments)jamais : déclare une permission ou un site—
JavaScript
module.command('salut', async (ctx) => {
  await ctx.reply('Salut ' + ctx.member.name + ' !');
});

module.on('memberJoin', async (ctx) => {
  await ctx.dm(ctx.member, 'Bienvenue sur ' + ctx.server.name + ' !');
});

module.every('rappel-du-soir', { every: 'day', at: '20:00' }, async (ctx) => {
  if (ctx.config.salon) await ctx.send(ctx.config.salon, 'Il est 20 h : pensez à voter !');
});

Asynchrone

Presque toutes les fonctions de ctx renvoient une promesse : utilise await. Plusieurs appels indépendants peuvent partir en même temps avec Promise.all.

L’environnement

Ton code tourne dans un bac à sable isolé (une machine JavaScript séparée), sans accès au bot, au disque ni au réseau, sauf à travers ctx.

DisponiblePas disponible (et à la place)
JavaScript moderne : fonctions, classes, async/await, Math, Date, JSON, Map, Set, expressions régulières…require, import, export : tout est dans un seul fichier.
Les fonctions de ctxeval et Function : interdits.
Promise.all pour parallélisersetTimeout : utilise ctx.sleep(ms) (5 s max) ou ctx.later pour plus tard.
ctx.log(texte) pour le journalconsole.log : rien ne s’affiche.
ctx.storage, ctx.memory, ctx.collection pour garder des donnéesLes variables globales : elles ne survivent pas forcément d’un appel à l’autre.

Les erreurs

Si ton gestionnaire lance une erreur (ou si une action échoue), Opale l’écrit dans le journal du module et, après une commande ou un clic, l’affiche à la personne : « ⚠️ Mon module : … ». Lancer une erreur toi-même est donc une façon simple de refuser une action :

JavaScript
module.command('payer', async (ctx) => {
  if (Number(ctx.args.montant) <= 0) throw new Error('Le montant doit être positif.');
  // …
});

Après une commande ou un clic, si ton code ne répond rien, Opale répond « ✓ C’est fait. » pour que Discord ne montre pas d’erreur. Au-delà de 2 secondes sans réponse, Opale fait patienter le membre automatiquement.

Le fichier de types

L’éditeur connaît tout le SDK (fichier sdk.d.ts) : survole une fonction pour sa description, tape ctx. pour la liste. La référence du SDK reprend tout avec des exemples.

Structure d’un module · Documentation Opale