Бот присоединяется и воспроизводит файл по всем голосовым каналам в гильдии - PullRequest
0 голосов
/ 24 января 2019

Недавно я делал свой первый бот для разногласий, и сегодня я столкнулся с проблемой небольшого требования. Мне нужен мой бот для подключения ко всем голосовым каналам сервера и воспроизведения mp3-файла. Это для предупреждения.

Сначала я провел базовый тест с этим кодом для воспроизведения mp3 на канале, к которому подключен пользователь, запускающий команду:

exports.run = async (client, message, args, level) => {
  if (message.member.voiceChannel) {
    message.member.voiceChannel.join()
    .then(connection => {
        const dispatcher = connection.playFile('/home/pi/.discordbots/TARVIS/1.mp3');
        dispatcher.on("end", end => {message.member.voiceChannel.leave()});
    })
    .catch(console.error);
  }
};

Код выше работает отлично

Итак, я попытался сделать это для всех голосовых каналов:

  let voiceChannels = message.guild.channels.filter(channel => channel.type == 'voice');

  voiceChannels.forEach(channel =>
    channel.join()
      .then(connection => {
        const dispatcher = connection.playFile('/home/pi/.discordbots/TARVIS/1.mp3');
        dispatcher.on("end", end => { channel.leave() });
      })
      .catch(console.error)
  );

Проблема в том, что бот подключается к первому каналу, а затем напрямую подключается ко второму, не успев воспроизвести файл на первом канале.

Думаю, мне нужно взглянуть на client.createVoiceBroadcast(); метод. Я пытался использовать это, но я не смог найти хороший пример. Вот что я пробовал, но тоже не работает:

exports.run = (client, message, args, level) => {
  let voiceChannels = message.guild.channels.filter(channel => channel.type == 'voice');
  const broadcast = client.createVoiceBroadcast();
  broadcast.playFile('/home/pi/.discordbots/TARVIS/1.mp3');

  voiceChannels.forEach(channel =>
    channel.join()
      .then(connection => {
        const dispatcher = connection.playBroadcast(broadcast);
        dispatcher.on("end", end => { channel.leave() });
      })
      .catch(console.error)
  );

Ожидаемый результат: бот подключается к каждому голосовому каналу один за другим и воспроизводит mp3-файл.

Заранее благодарю за помощь

EDIT

Я попытался создать асинхронную функцию и использовать ожидание на connection.playFile(), но у меня все еще остается та же проблема. Бот подключается ко всем голосовым каналам, но не ждет, пока файл будет воспроизведен.

Вот код, который я пробовал:

exports.run = async (client, message, args, level) => {

  async function play(voiceChannel) {
    console.log(voiceChannel.name + ` Type:` + voiceChannel.type + ` (` + voiceChannel.id + `)`);
    voiceChannel.join().then(async function (connection) {
      dispatcher = await connection.playFile('/home/pi/.discordbots/TARVIS/sncf.mp3');
      dispatcher.on('end', function () {
        voiceChannel.leave()
      });
    });
  }
  let voiceChannels = message.guild.channels.filter(channel => channel.type == 'voice');

  voiceChannels.map(vc => play(vc));

};

Я почти уверен, что решение близко ... но я застрял ... Может ли кто-нибудь помочь мне найти правильный синтаксис?

РЕДАКТИРОВАТЬ 2

Вот что я попробовал с вашим решением:

exports.run = async (client, message, args, level) => {

  async function play(voiceChannels) {
    for (let channel of voiceChannels) {
      console.log('Joining channel ' + channel.name);

      await channel.join().then(async (connection) => {
        console.log('Joined channel');

        let dispatcher = connection.playFile('/home/pi/.discordbots/TARVIS/sncf.mp3');
        await dispatcher.on('end', function () {
          channel.leave();
        });
      });
    }
  }

  let channels = message.guild.channels.filter(channel => channel.type == 'voice');
  console.log(channels);
  play(channels);

};

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Вот мой обходной путь.Я использовал setTimeout, чтобы поставить в очередь голос канала с таймером 10 с, я знаю, что он немного грязный, но он работает

exports.run = async (client, message, args, level) => {

  async function play(channel) {
    await channel.join().then(async (connection) => {
      let dispatcher = await connection.playFile('/home/pi/.discordbots/TARVIS/offline.m4a');
      await dispatcher.on('end', function () {
        channel.leave();
      });
    });
  }

  let timer = 1000;
  client.ShowSuccess('Démarrage des annonces vocales');
  message.guild.channels.forEach(async (channel) => {
    if (channel.type == 'voice' && channel.members.size > 0) {
      client.ShowSuccess('Annonce dans le salon ' + channel.name + ' pour ' + channel.members.size + ' membre(s)', message.channel);
      client.logger.log('Annonce dans le salon ' + channel.name + ' pour ' + channel.members.size + ' membre(s)');
      setTimeout(function () {
        play(channel);
      }, timer);
      timer = timer + 10000;
    }
  });
  setTimeout(function () {
    client.ShowSuccess('Annonces vocales terminées');
  }, timer);
};
0 голосов
/ 25 января 2019

Я мог бы найти (несколько) решение. Я попытался воссоздать эту проблему в JSFiddle, чтобы мне было проще ее проверить. Вот мое решение .

Код ядра находится в функции joinChannels, которую также можно увидеть ниже

async function joinChannels () {
  for (let channel of channels) {
    await new Promise((resolve) => {
      console.log('Joining channel ' + channel.name);

      resolve(new Promise((resolve) => {
        setTimeout(() => {
          console.log('Done with channel ' + channel.name);
          resolve();
        }, 1000);
      }));
    });
  }
}

Теперь, чтобы переписать это в решение, основанное на вашем контексте, вот моя попытка (которая не проверена и, следовательно, может потребовать некоторой настройки)

async function play(voiceChannels) {
  for (let channel of voiceChannels) {
    console.log('Joining channel ' + channel.name);

    await channel.join().then(async (connection) => {
      console.log('Joined channel');

      let dispatcher = connection.playFile('/home/pi/.discordbots/TARVIS/sncf.mp3');
      await dispatcher.on('end', function () {
        voiceChannel.leave();
      });
    });
  }
}

Попробуй и дай мне знать, как это получается. Если у вас есть вопросы, я с радостью помогу

...