I'm trying to make a bot which will create temporary voice channles
Code:
var temporary = []
client.on('voiceStateUpdate', (oldMember, newMember) => {
const mainCatagory = '677192265491415041';
const mainChannel = '677875869351542803';
if (newMember.voiceChannelID == mainChannel) {
newMember.guild.createChannel(`${newMember.user.username} 5vs5`, { type: 'voice', parent: mainCatagory })
.then(async channel => {
temporary.push({ newID: channel.id, guild: channel.guild })
// A new element has been added to temporary array!
await newMember.setVoiceChannel(channel.id)
})
}
if (temporary.length >= 0) for (let i = 0; i < temporary.length; i++) {
// Finding...
let ch = temporary[i].guild.channels.find(x => x.id == temporary[i].newID)
// Channel Found!
ch.setUserLimit(5)
if (ch.members.size <= 0) {
ch.delete(1000)
// Channel has been deleted!
return temporary.splice(i, 1)
}
}
})
Why it doesn't work?
it worked fine before i reinstalled system
node: 13.10.1
Win: 10
I can see you are having issues with asynchronous code. You have the following line:
await newMember.setVoiceChannel(channel.id)
That is not getting awaited as you are expecting it to because it falls within the block of a .then. The await only affects the code in that async block in the .then statement, and since nothing occurs after that line, it's not functionally doing anything different than it would if you didn't await it.
You should try to avoid mixing .then and async/await if possible (there are reasons you might mix but you need to know what you are doing). In this case I suggest setting the entire event handler to be async and await both.
Note: The following assumes you are using discord.js v11, which is consistent with your earlier code sample. If you are using v12 you should be using guild.channels.create(), guild.channels.cache.find(), and newMember.voice.setChannel() instead. You said you just installed a new instance of node and presumable discord.js so you may in fact be on v12 now and that could be part of your issue.
client.on('voiceStateUpdate', async (oldMember, newMember) => {
const mainCatagory = '677192265491415041';
const mainChannel = '677875869351542803';
if (newMember.voiceChannelID == mainChannel) {
let channel = await newMember.guild.createChannel(`${newMember.user.username} 5vs5`, { type: 'voice', parent: mainCatagory })
temporary.push({ newID: channel.id, guild: channel.guild })
// A new element has been added to temporary array!
await newMember.setVoiceChannel(channel.id)
}
// The rest of your code.
}
Related
I'm looking to register for all guilds globally instead of registering for just my guild ID, just so I can use slash commands in my friend's server (plus any other server it's in), yet I don't know how. I'm a bit new to discord.js.
I was wondering if someone could help me register for all guilds globally...
Extra information - I'm following reconlx's Discord.js v13 tutorials.
This is the part of my code which I need help looking at and modifying. There's a line in his command handler talking about registering for all guilds at await client.application.commands.set(arrayOfSlashCommands);, yet I'm not sure what it means...
client.on("ready", async () => {
// Register for a single guild
const guild = client.guilds.cache.get("938823675535319050")
await guild.commands.set(arrayOfSlashCommands).then((cmd) => {
const getRoles = (commandName) => {
const permissions = arrayOfSlashCommands.find(
(x) => x.name === commandName
).userPermissions;
if(!permissions) return null;
return guild.roles.cache.filter(
(x) => x.permissions.has(permissions) && !x.managed
);
};
const fullPermissions = cmd.reduce((accumulator, x) => {
const roles = getRoles(x.name);
if(!roles) return accumulator;
const permissions = roles.reduce((a, v) => {
return [
...a,
{
id: v.id,
type: 'ROLE',
permission: true,
},
];
}, []);
return [
...accumulator,
{
id: x.id,
permissions,
},
];
}, []);
guild.commands.permissions.set({ fullPermissions });
});
// Register for all the guilds the bot is in
// await client.application.commands.set(arrayOfSlashCommands);
});
Looking forward to some solutions, if you could assist, it would help a lot.
You can register global commands using the Client.application.commands.set() method, passing in an Array of ApplicationCommandDataResolvables into the method. However, please be aware a caveat of global commands is that they take up to an hour for changes to reflect across Discord.
See this:
client.application.commands.set(commands)
// ^^^ ^^^^^^^^
// Client is your Discord.Client Commands is the list of commands
I have a suggest command and I'm trying to make it so that when i react with emoji "x" message get's deleted. Can someone help me?
owner.send(embed).then(m => {
m.react("✅")
m.react('❌')
})
To listen react change on message is sent you need to using createReactionCollector() guide here
This code is what you are looking for
Note: Your exec or run function must be async function
const newMsg = await owner.send(embed);
await newMsg.react('❌');
const filter = (reaction, user) => {
return user.id === msg.author.id; // Note msg is start commands message
};
let collector = await newMsg.createReactionCollector(filter, {
time: 30000,
});
collector.on('collect', async (r) => {
if (r.emoji.name ==='❌') {
collector.stop('delete');
await newMsg.delete();
}
});
client.on("channelDelete", async channel => {
let channelg = await db.fetch(`channel_${channel.guild.id}`);
if (channelg == "on") {
const logs = await channel.guild.fetchAuditLogs({ type: 'CHANNEL_DELETE' }).then(audit => audit.entries.first())
const deleter = await channel.guild.members.fetch(logs.executor.id);
if(deleter.id == channel.guild.owner.user.id) return;
channel.clone(undefined, true, true, "channel delete system").then(async klon => {
await klon.setParent(channel.parent);
await klon.setPosition(channel.position);
channel.guild.owner.send(`channel: **${channel.name}** channel it occurred again.`)
console.log('correct')
})
}
})
allows you to create a channel back when it is deleted
how to make discord js V11 version compatible, V12 was prepared for release.
can you help? I hope everything is clear
You have to replace guild.members.fetch() with guild.fetchMember()
Also, the first argument of Channel.clone() must be an Object.
Instead of undefined, just provide an empty Object, as all options in the first parameter are optional.
channel.clone({}, true, true, "channel delete system")
I'm currently making a Discord bot. The code I've provided below is supposed to get data from Hypixel to display guild info. It's getting the correct info, but I want to send all the names as one message instead of one person per message.
This is my code:
const fetch = require('node-fetch');
module.exports = {
name: 'hguild',
aliases: ['hg'],
description: 'Shows info about a hypixel guild!',
guildOnly: true,
args: true,
usage: '<player>',
execute(message, args) {
var ruuid = [];
const guildName = args[0];
message.channel.send('Please wait, checking API').then((msg) => {
fetch(`https://api.hypixel.net/guild?key=[REMOVED]&name=${guildName}`)
.catch((err) => message.channel.send(err))
.then((res) => res.json())
.catch((err) => message.channel.send(err))
.then((json) => {
console.log(json);
msg.edit('Here is about your guild!');
for (const guild of json.guild.members) {
const rawUsername = guild.uuid;
fetch(`https://api.mojang.com/user/profiles/${rawUsername}/names`)
.catch((err) => message.channel.send(err))
.then((res) => res.json())
.catch((err) => message.channel.send(err))
.then((json) => {
console.log(json[0].name);
if (json.name == null || json.status == 'ERR') {
}
var testList = [json[0].name];
message.channel.send(testList);
});
}
});
});
},
};
Currently its showing all the names, but sends one name per message. I want to group all these names together.
Instead of executing these two lines:
var testList = [json[0].name];
message.channel.send(testList);
And then closing the for loop, try pushing the results to an array initialized before the loop, then send that. Example:
var testList = [];
const getUsernames = async () => {
for await (const guild of json.guild.members) {
const rawUsername = guild.uuid;
fetch(`https://api.mojang.com/user/profiles/${rawUsername}/names`)
.catch((err) => message.channel.send(err))
.then((res) => res.json())
.catch((err) => message.channel.send(err))
.then((json) => {
console.log(json[0].name);
if (json.name == null || json.status == 'ERR') {
}
testList.push(json[0].name);
});
}
};
await getUsernames();
message.channel.send(testList.join('\n'));
Make sure you change the execute(message, args) line at the top of your code to async execute(message, args) so that await is possible.
As a disclaimer, I am not knowledgable in the Minecraft API area, and do not know how the object returned from your request is structured. This is just my best guess.
#Lioness100 Also unfamiliar with the Minecraft API.
I'm curious about the loop, seems like your initial fetch to the api with guild info returns what you're looking for.
Are you deconstructing names to test the functionality to eventually push entire profiles to discord? or are you content with just names?
(For the latter, instead of the loop have you tried)
message.channel.send(json.guild.members)
Otherwise another thing to consider would be utilizing the loop to generate an array of URLs that you could resolve together with a Promise.all. Wondering if the undesired output is a result of asynchronous behavior. Here's the api docs for reference:
https://javascript.info/promise-api
Hope that works, friend!
I am using ytdl-core and node-opus to add music functionality to my bot. I am also following a tutorial. Up until I started to add queuing functionality, the bot worked fine. As I integrated the queuing, the bot could still join and leave voice channels, but can't play music. It outputs (node:22116) UnhandledPromiseRejectionWarning: ReferenceError: play is not defined
As per comments on the video, I have tried switching play to playstream. This worked originally, but doesn't help, only outputting that it is not defined.
Here is the command:
if (!message.member.voiceChannel) return message.channel.send("You must be connected to a voice channel.");
if (!args[0]) return message.channel.send("You must supply a __valid__ URL.");
let validate = await ytdl.validateURL(args[0]);
if (!validate) return message.channel.send("You must supply a __valid__ URL.");
let info = await ytdl.getInfo(args[0]);
let data = active.get(message.guild.id) || {};
if (!data.connection) data.connection = await message.member.voiceChannel.join();
if (!data.queue) data.queue = [];
data.guildID = message.guild.id;
data.queue.push ({
songTitle: info.title,
requester: message.author.tag,
url: args[0],
announceChannel: message.channel.id
});
if (!data.dispatcher) play();
else {
message.channel.send(`Added song to queue: ${info.title} || Requested by: ${message.author.id}`);
active.set(message.guild.id, data);
I'd like to be able to still follow the tutorial to fully integrate the queuing.
You didn't define the play() function in previous code, so you also can't use it.
Here is an example of how your play() function could look:
const queue = msg.client.queue;
const ytdl = require('ytdl-core');
async function play(guild, song) {
const serverQueue = await queue.get(guild.id);
if (!song) {
await serverQueue.voiceChannel.leave();
await queue.delete(guild.id);
return;
}
const stream = await ytdl(song.url, {
filter: 'audioonly'
});
const dispatcher = await serverQueue.connection.playStream(stream)
.on('end', async reason => {
if (reason === 'Stream is not generating quickly enough.');
serverQueue.songs.shift('Stream is not generating quickly enough');
await play(guild, serverQueue.songs[0]);
})
.on('error', error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
}
My queue is constructed as following:
const queueConstruct = {
textChannel: msg.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 2,
playing: true
};
It could be that you have to change some lines of code, so that it works for your bot!