Discordjs dans un navigateur web

Pour réaliser ce tutoriel, vous devez avoir au minimum un bot fonctionnel. Je vous conseille d’aller suivre ce tutoriel pour créer un bot si ce n’est pas le cas.

Vous avez un bot fait avec discordjs mais vous souhaitez implémenter une fonctionnalité sur votre site web ? C’est possible !
Cet article servira de base à de futurs articles plus spécifique qui présenterons des fonctionnalités à implémenter.

Création d’un serveur web

Pour que notre site puisse communiquer avec notre bot, ce dernier doit exposer un serveur web afin de recevoir des requêtes.
Reprenons donc notre bot discord et créons tout de suite un nouveau fichier nommé ws.js (pour web server).

Avant de continuer, on va installer quelques dépendances pour notre serveur web. Pour cela on va utiliser express.

npm install --save express ejs body-parser

Passons maintenant au code de notre serveur web. On va donc créer une classe qu’on va appeler dans notre code principal de notre bot.
Cela nous permettra de passer l’object discordjs au serveur pour effectuer des actions.

const express = require('express');
const bodyParser = require("body-parser");
const path = require('path');

/**
 * WebServer class.
 * @param {string}  token  Un token pour protéger l'accès
 * @param {number} port   Port du serveur web
 * @param {discord.Client} client Client Discord afin d'effectuer les actions
 */
class WebServer {

    constructor(token, port, client) {
        this.token = token
        this.port = port
        this.client = client
        this.app = express()
        this.guildId = null;

        // On défini ejs comme moteur de template
        this.app.set('view engine', 'ejs');

        // on défini le dossier des templates
        this.app.set('views', path.join(__dirname, 'views'))

        // On défini le dossier public qui contiendra les assets
        this.app.use(express.static(path.join(__dirname, 'public')))

        // On déclare bodyParser pour gérer le JSON dans les requêtes POST
        this.app.use(bodyParser.urlencoded({extended: false}));
        this.app.use(bodyParser.json());

        // On définie les routes
        this.registerRoutes()

        // On lance le serveur web
        this.server = this.app.listen(this.port, () => {
            console.log("Serveur lancé sur le port  " + this.port)
        })
    }

    /**
     * Vérifie le token et authentifie la requête du site web
     * @param {string} _token Le token envoyé par le site web
     * @returns {boolean} True Si le token correspond au token de sécurité
     */
    auth(_token) {
        return (_token === this.token)
    }

    /**
     * On récupère l'id de la guild à l'init (après que le bot se soit connecté)
     */
    init(){
        this.guildId = this.client.guilds.cache.first().id;
    }

    /**
     * Déclare les routes
     */
    registerRoutes() {

        // La route principale qui affiche la page web
        this.app.get('/', (req, res) => {
            const _token = req.query.token // On récupère le token de la requête
            if (!this.auth(_token)) {
                // Erreur, le token ne correspond pas !
                res.render('error', {title: "Echec de l'authentification !"})
                return;
            }

            // On va récupérer la liste des salons du serveur discord pour les renvoyer à la page web
            const channels = [];
            this.client.guilds.resolve(this.guildId).channels.cache
                .filter(c => c.type === 'text')
                .forEach(c => {
                    channels.push({id: c.id, name: c.name})
                });

            // On affiche la page web en lui passant le token de sécurité, un titre et la liste des salons
            res.render('index', {
                title: "Ma superbe page web",
                token: _token,
                channels
            });
        });

        // On définie la route qu'on appellera quand on enverra le formulaire sur la page web
        // Cette route récupérera le message à envoyé et l'enverra sur le channel choisi
        this.app.post('/send', (req, res) => {
            const _token = req.body.token;
            const channelId = req.body.channelId;
            const text = req.body.text;

            // Si il nous manque une info on renvoi une erreur
            if (!_token || !channelId || !text)
                return res.sendStatus(400);

            // Si le token est différent de celui de sécurité on renvoi une erreur
            if (!this.auth(_token))
                return res.sendStatus(401);

            // On récupère le channel demandé grâce à son id
            const channel = this.client.guilds.resolve(this.guildId).channels.resolve(channelId)

            //Si le salon est trouvé, on envoi le message dedans,
            // Sinon on renvoi une erreur
            if (channel) {
                channel.send(text);
                res.sendStatus(200);
            } else{
                res.sendStatus(404);
            }
        });
    }

}

module.exports = WebServer;

Configuration du serveur web

Maintenant que le serveur web est créé, il faut l’appeler au lancement de notre bot. Allons donc dans le fichier index.js de notre bot pour l’instancier:

const Discord = require('discord.js');
const { prefix, token, port, webToken } = require("./config.json");
// On importe la classe
const WebServer = require("./ws.js");

const client = new Discord.Client();

// On instancie la classe de notre serveur web
const ws = new WebServer(webToken, port, client);


client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
  ws.init();
});
client.on('message', msg => {
  if (msg.content === 'ping') {
    msg.reply('pong');
  }
});
client.login(token);

Voici le contenu du fichier config.json:

{
  "prefix": "&",
  "token": "votre-token",
 "webToken": "votre-token-web",
  "port": "3001"
}

C’est fini pour le serveur web !

Les templates et assets

Créons maintenant les templates qui seront appelé quand on utilise l’instruction res.render().
Pour cela, on créer deux dossiers toujours à la racine:

mkdir public views

Le premier contiendra les assets (javascript, css, images), le second les templates ejs.

Rendez vous dans le second dossier, et créons deux fichiers ejs:

touch index.ejs error.ejs

Contenu de index.ejs:

<form action="/send" method="POST" >
   <%# On affecte le token à un input invisible %>
    <input type="hidden" name="token" value="<%= token %>" />
   <%# Liste déroulante des channels %>
    <select name="channelId">
       <% for(var i=0; i<channels.length; i++) {%>
            <option value="<%= channels[i].id %>"><%= channels[i].name %></option>
        <% } %>
    </select>
    <%# Input pour le texte à envoyer %>
    <input type="text" name="text" placeholder="texte à envoyer">
    <%# bouton d'envoi %>
    <input type="submit" class="button" value="Envoyer">
</form>

Contenu de error.ejs:

<p>Erreur d'authentification !</p>

Lancement !

Tout est prêt ! Paré au lancement ! Lançons donc notre bot et notre serveur :

node index.js

Dans la console on obtiens:

Serveur lancé sur le port  3001
Ready!

Et voici notre page à l’url http://locahost?token=votre-web-token

Page d’envoi de message avec DiscordJs

On peux tester, entrez le message que vous voulez après avoir sélectionné le salon désiré et cliquez sur envoyer !

Admirez ensuite le rendu dans votre serveur discord, votre bot a réécris vos messages !

Message du bot
Message du bot

Conclusion

Vous voilà maintenant avec une base pour vos projets les plus fous !
On pourrais imaginer créer un backoffice pour gérer son discord depuis le web, ou même créer un chat web pour dialoguer sur discord.

Mais je ferais de prochains articles afin d’explorer toutes les possibilités qui peuvent s’offrir.

En attendant, bon code !


Sources


Articles récents

Discordjs dans un navigateur web

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Retour en haut