Bot audio Discord

problème pour créer un système de queue

a marqué ce sujet comme résolu.

Bonjour à tous,

Je me suis lancé récemment dans le codage d’un bot audio pour Discord. J’utilise pour ce faire NodeJS et Discord.js. J’ai déjà un bon niveau en JavaScript.

J’ai commencé par coder deux commandes (play et stop, la base donc), qui fonctionnent bien. Elles permettent de streamer de l’audio depuis Youtube. Pour améliorer le bot, j’aimerais lui ajouter un système de playlist, mais je n’y arrive pas.

Voici mon code :

var discord = require('discord.js');
var bot = new discord.Client();

var ytdl = require('ytdl-core');

bot.login('ID');

bot.on('ready', function() {
  console.log("R2-DJ is ready");
  bot.user.setStatus('online');
});

bot.on('message', function(message) {

  var answer = '';

  var args = message.content.split(' ');
  var queue = new Array();

  function play(args) {
    if (args[1].match(/https|http.*(^|=|\/)([0-9A-Za-z_-]{11})(\/|&|$|\?|#)/)) {
      var id = args[1].match(/(^|=|\/)([0-9A-Za-z_-]{11})(\/|&|$|\?|#)/)[2];

      let voiceChannel = message.guild.channels
        .filter(function(channel) {
          return channel.type === 'voice'
        })
        .first()
      voiceChannel
        .join()
        .then(function(connection) {
          let stream = ytdl(id, {
            filter: 'audioonly'
          });
          message.delete();

          var dispatcher = connection.playStream(stream);

          var info = ytdl.getInfo(id, function(err, info) {
            if (err) throw err;
            answer = ` ▶ Tu écoutes actuellement ${'_' + info.title + '_'} (` + args[1] + `)`;
            message.channel.send(answer);
          });

          dispatcher.on('end', function() {
            voiceChannel.leave();
            if (args[0] === '?play') {
              message.channel.send('🎧 La musique est finie');
            }
          })
        })
    }
  }

  if (message.content.startsWith('?play')) {
    play(args);
  } else if (message.content.startsWith('?stop')) {
    let voiceChannel = message.guild.channels
      .filter(function(channel) {
        return channel.type === 'voice'
      })
      .first()
    voiceChannel.leave();
    if (args[0] === '?stop') {
      message.channel.send('⏹ Music stopped.');
    }
  } else if (message.content.startsWith('?add')) {
    if (args[1].match(/https|http.*(^|=|\/)([0-9A-Za-z_-]{11})(\/|&|$|\?|#)/)) {
      var id = args[1].match(/(^|=|\/)([0-9A-Za-z_-]{11})(\/|&|$|\?|#)/)[2];
    } else {
      message.channel.send('Blip bloup, tu n\'as pas entré une URL valide !');
    }
      queue.push(id);
      console.log(queue);
      var infoQueue = ytdl.getInfo(id, function(err, infoQueue) {
        if (err) throw err;
        message.channel.send(`${'_' + infoQueue.title + '_'} a été ajouté à la playlist !`);
      });
  } else if (message.content === '?queue') {
    console.log(queue);
    for (var i = 0; i < queue.length; i++) {
      message.channel.send(i + 1 + '. ' + queue[i]);
    }
  } else if (message.content === '?save') {
    // Sauvegarde la playlist dans un fichier
    fs.writeFile('./playlist.txt', queue + '\n', function (err) {
      if (err) throw err;
    });
  } else if ((message.content.startsWith('!')) && (user !== 'R2-DJ')) {
    answer = 'Blip bloup Je ne comprends pas ta demande... ⚠. Vérifie ta syntaxe et recommence ' + user + '.';
  }

  // Le bot réagit si l'une des conditions est vérifiée

  if ((answer !== '') && (user !== 'RD2-DJ')) {
    // Si le bot n'a pas de réponse a donner, il dit qu'il ne comprend pas
    message.channel.send(answer);
  } else if ((answer === '') && (message.content.includes('@R2-DJ')) && (user !== 'R2-DJ')) {
    message.channel.send("Erreur système : code d'erreur 1000, je n'ai pas compris ton message. ⚠");
  }
});

J’ai créé une variable queue, qui reprend tous les ID des vidéos Youtube ajoutées à la playlist, sous forme de tableau. L’ajout (via la commande ?add) s’effectue correctement. mais lorsque je veux afficher la playlist (commande ?queue), le console.log() me dit qu’elle est vide. J’en déduis donc que le contenu du tableau n’est pas sauvegardé, et je ne sais absolument pas pourquoi…

Sûrement une erreur de débutant :D .

Si vous avez une piste à me fournir, je suis preneur.

Merci et bonne fin de dimanche,

Mx47

@A-312: Toi t’as loupé la ligne 73.

Je n’ai jamais fais de bot discord mais je pense que la fonction anonyme déclarée ligne 13 est appelé à chaque message, une callback quoi.

Ce qui signifie que la variable queue est locale à cette fonction anonyme. Et donc qu’elle est redéfinie à chaque appel. À chaque appel, elle commence vide.

Bref, il faut qu’elle soit moins locale.

Edit: Sympa le nom R2-DJ ^^
À une époque j’avais fait un robot en déchet électronique. On l’avait appelé CT9.

+2 -0

Merci à vous ! Á la seconde où j’ai lu le message de Ache, je me suis maudit. Quelle bête erreur…

Du coup, j’ai fait des tests, et en effet, la playlist est sauvegardée, et j’arrive même à l’écrire dans un fichier, ce qui est plutôt encourageant.

Par contre, je n’arrive pas à faire lire la playlist au bot… :( . Voici mon code mis à jour :

var discord = require('discord.js');
var bot = new discord.Client();

var fs = require('fs');
var ytdl = require('ytdl-core');

bot.login('TOKEN');

bot.on('ready', function() {
  console.log("R2-DJ is ready");
  bot.user.setStatus('online');
});

// Créée une playlist vide
var queue = new Array();

bot.on('message', function(message) {

  var answer = '';

  // personnalisation des messages avec des prénoms

  if (message.author.username === 'Leroux47') {
    var user = 'Max';
  } else if (message.author.username === 'Paco') {
    user = 'Loïc';
  } else if (message.author.username === 'Sirorco') {
    user = 'Thomas';
  } else if (message.author.username === 'Kiochio') {
    user = 'Antoine';
  } else if (message.author.username === 'Rama') {
    user = 'Geoffrey';
  } else if (message.author.username === 'Antrol974') {
    user = 'Antoine';
  } else if (message.author.username === 'Kayex#8754') {
    user = 'Maxime';
  } else if (message.author.username === 'R2-DJ') {
    user = 'R2-DJ';
  }

  var args = message.content.split(' ');

  function play(args, queue) {
    if (args[1].match(/https|http.*(^|=|\/)([0-9A-Za-z_-]{11})(\/|&|$|\?|#)/)) {
      var id = args[1].match(/(^|=|\/)([0-9A-Za-z_-]{11})(\/|&|$|\?|#)/)[2];

      let voiceChannel = message.guild.channels
        .filter(function(channel) {
          return channel.type === 'voice'
        })
        .first()
      voiceChannel
        .join()
        .then(function(connection) {
          let stream = ytdl(id, {
            filter: 'audioonly'
          });
          message.delete();

          var dispatcher = connection.playStream(stream);

          var info = ytdl.getInfo(id, function(err, info) {
            if (err) throw err;
            answer = ` ▶ Tu écoutes actuellement ${'_' + info.title + '_'} (Youtube ID : ` + id + `)`;
            message.channel.send(answer);
          });

          dispatcher.on('end', function() {
            voiceChannel.leave();
          })
        })
    }
  }
// Commandes play, stop, play queue, save playlist
  if (message.content.startsWith('?p ')) {
    play(args, queue);
  } else if (message.content === '?p queue') {
    let voiceChannel = message.guild.channels
      .filter(function(channel) {
        return channel.type === 'voice'
      })
      .first()
    voiceChannel
      .join()
      .then(function(connection) {
        for (var i = 0; i < queue.length; i++) {
          let stream = ytdl(queue[i], {
            filter: 'audioonly'
          });
          message.delete();

          var dispatcher = connection.playStream(stream);

          var info = ytdl.getInfo(id, function(err, info) {
            if (err) throw err;
            answer = ` ▶ Tu écoutes actuellement ${'_' + info.title + '_'} (Youtube ID : ` + id + `)`;
            message.channel.send(answer);
          });
        }
      });
    dispatcher.on('end', function() {
      voiceChannel.leave();
    });
  } else if (message.content.startsWith('?stop')) {
    let command = 'stop';
    let voiceChannel = message.guild.channels
      .filter(function(channel) {
        return channel.type === 'voice'
      })
      .first()
    voiceChannel.leave();
    if (command === 'stop') {
      message.channel.send('⏹ ' + user + ' a arrêté la musique.');
    }
  } else if (message.content.startsWith('?add')) {
    if (args[1].match(/https|http.*(^|=|\/)([0-9A-Za-z_-]{11})(\/|&|$|\?|#)/)) {
      var id = args[1].match(/(^|=|\/)([0-9A-Za-z_-]{11})(\/|&|$|\?|#)/)[2];
    } else {
      message.channel.send('Blip bloup, tu n\'as pas entré une URL valide !');
    }
    queue.push(id);
    console.log(queue);
    var infoQueue = ytdl.getInfo(id, function(err, infoQueue) {
      if (err) throw err;
      message.channel.send(`${'_' + infoQueue.title + '_'} a été ajouté à la playlist !`);
    });
  } else if (message.content === '?q') {
    console.log(queue);
    for (var i = 0; i < queue.length; i++) {
      message.channel.send(i + 1 + '. ' + queue[i]);
    }
  } else if (message.content === '?save') {
    // Sauvegarde la playlist dans un fichier
    fs.writeFile('./playlist.txt', queue + '\n', function(err) {
      if (err) throw err;
    });
  } else if ((message.content.startsWith('?')) && (user !== 'R2-DJ')) {
    answer = 'Blip bloup Je ne comprends pas ta demande... ⚠. Vérifie ta syntaxe et recommence ' + user + '.';
  }

  // Le bot réagit si l'une des conditions est vérifiée

  if ((answer !== '') && (user !== 'RD2-DJ')) {
    // Si le bot n'a pas de réponse a donner, il dit qu'il ne comprend pas
    message.channel.send(answer);
  } else if ((answer === '') && (message.content.includes('@R2-DJ')) && (user !== 'R2-DJ')) {
    message.channel.send("Erreur système : code d'erreur 1000, je n'ai pas compris ton message. ⚠");
  }
});

En gros, j’ai déplacé la création de la playlist en-dehors du callback de l’évènement message, j’ai raccourci un peu le nom des commandes (mais ça, ce n’est rien), et j’ai tenté de faire lire la playlist au bot (instruction ?p queue). Je trouve bizarre qu’il n’arrive même pas à se connecter au voiceChannel, et qu’il ne me sorte aucune erreur…

Si vous avez une piste, je suis preneur.

Merci pour votre aide, bonne après-midi,

Mx47

PS: merci @Ache pour ton compliment pour le nom (vive Star Wars :lol: ).

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte