机器人加入并在公会的所有语音频道播放文件
Bot join and play file across all voice channels in a guild
我最近一直在制作我的第一个 discord 机器人,今天我遇到了一个小问题。
我需要我的机器人连接到服务器的所有语音通道并播放 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()
上使用等待,但我仍然遇到同样的问题。 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);
};
我可能已经找到(某种程度上)解决方案。我试图在 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();
});
});
}
}
试一试,让我知道结果如何。如果您有任何疑问,我很乐意为您提供帮助
这是我的解决方法。
我使用 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);
};
我最近一直在制作我的第一个 discord 机器人,今天我遇到了一个小问题。 我需要我的机器人连接到服务器的所有语音通道并播放 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()
上使用等待,但我仍然遇到同样的问题。 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);
};
我可能已经找到(某种程度上)解决方案。我试图在 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();
});
});
}
}
试一试,让我知道结果如何。如果您有任何疑问,我很乐意为您提供帮助
这是我的解决方法。
我使用 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);
};