Bot在行会的所有语音通道中加入并播放文件

时间:2019-01-24 10:20:09

标签: javascript bots discord discord.js

最近我一直在做我的第一个Disord机器人,今天我遇到了一个需要满足的问题。 我需要我的机器人连接到服务器的所有语音通道并播放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文件。

预先感谢您的帮助

编辑

我试图制作一个异步函数并在connection.playFile()上使用await,但是我仍然遇到同样的问题。 Bot会连接到所有语音通道,但不要等待文件播放。

这是我尝试的代码:

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 :(得分:0)

我可能已经找到了某种解决方案。我试图在JSFiddle中重新创建此问题,以便可以更轻松地对其进行测试。 Here is my solution

核心代码位于函数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();
      });
    });
  }
}

试试吧,让我知道结果如何。如果您有任何疑问,我们很乐意为您提供帮助

答案 1 :(得分:0)

这是我的工作环境。 我使用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);
};