I'm using discord.js v13.
I want to disconnect all members from a voice channel. Using interaction.guild.channels.fetch(), I'm able to get voice channels and the members' information.
But when I switch the voice channel, the data is still wrong because it's not updating.
This is my code:
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const { commandName } = interaction;
switch (commandName) {
case 'channels':
const channelInput = interaction.options.getString('channelname');
const channelExist = (await interaction.guild.channels.fetch()).find(channel => {
return channel.name == channelInput && channel.isVoice()
})
if (!channelExist) {
await interaction.reply('no voice channel');
break;
}
console.log(channelExist.members)
console.log('===========')
break;
}
});
How can I fix this problem?
To receive updates from voice channels on who is joining and leaving which channels you need to supply you client with the GUILD_VOICE_STATES intent. That will allow your data to update.
Related
Is there any way how to count messages of specified user in specified Discord channel in discord.js? When I use:
const countMyMessages = async (channel, member) => {
const messages = await channel.messages.fetch()
const myMessages = message.filter(m => m.author.id === member.id)
console.log(myMessages.size)
}
Only 50 messages are fetched, so I can't count all messages of user. And option limit can have max value 100. /guilds/guild_id/messages/search API on the other hand is not available for bots.
You will need to use a storage system to keep this kind of statistics on Discord.
I recommend you to use SQLite at first (like Enmap npm package).
I can quickly draw a structure for you based on this one.
const Enmap = require("enmap");
client.messages = new Enmap("messages");
client.on("message", message => {
if (message.author.bot) return;
if (message.guild) {
const key = `${message.guild.id}-${message.author.id}`;
client.messages.ensure(key, {
user: message.author.id,
guild: message.guild.id,
messages: 0
});
client.messages.inc(key, "messages");
// Do your stuff here.
console.log(client.messages.get(key, "messages"))
}
});
bot.on('channelCreate', async channel => {
if (!channel.guild) return;
const fetchedLogs = await channel.guild.fetchAuditLogs({
limit: 1,
type: 'CHANNEL_CREATE',
});
const logbook = channel.guild.channels.cache.get("ChannelID")
const deletionLog = fetchedLogs.entries.first();
if (!deletionLog) return logbook.send(`A channel was updated but no relevant autid logs were found`);
const { executor, user } = deletionLog;
if (user.id) {
logbook.send(`${executor.tag} created a channel`);
} else {
logbook.send(`A channel was created but idk who did.`);
}
});
I am a newbie when it comes to fetching actions through Discord Audit Logs; so I am experimenting and somehow came up with this code. However, when I create a channel, it does not send any messages saying that a channel has been created by #user. I have no idea what my next step will be. All I wanted to do was to know who created the channel.
Discord.JS: v12.2.0
client.on("channelCreate", async channel => {
if (!channel.guild) return false; // This is a DM channel.
const AuditLogFetch = await channel.guild.fetchAuditLogs({limit: 1, type: "CHANNEL_CREATE"}); // Fetching the audot logs.
const LogChannel = client.channels.cache.get("722052103060848664"); // Getting the loggin channel. (Make sure its a TextChannel)
if (!LogChannel) return console.error(`Invalid channel.`); // Checking if the channel exists.
if (!AuditLogFetch.entries.first()) return console.error(`No entries found.`);
const Entry = AuditLogFetch.entries.first(); // Getting the first entry of AuditLogs that was found.
LogChannel.send(`${Entry.executor.tag || "Someone"} created a new channel. | ${channel}`) // Sending the message to the logging channel.
});
If the code I provided is not working, please make sure the bot has access to view AuditLogs.
I'm making a discord bot and I came across a problem, if I type $join into chat, I want the bot to join the voice channel I'm in and play a sound. That is working but when the bot is already in the voice channel and I type $join again, it just plays the sound again and I want it to play the sound only once when it connects to the channel. I tried to solve it with some if, else and return functions but it didn't work, thanks for help.
This is my code working like I described.
message.delete({
timeout: 5000
})
const voiceChannel = message.member.voice.channel
if (voiceChannel) {
const connection = await voiceChannel.join()
const dispatcher = connection.play("./sounds/xxx.mp3")
dispatcher.setVolume(0.5)
} else {
message.reply("you need to be in a voice channel!").then(message => {
message.delete({
timeout: 5000
})
})
}
You need to check whether the channel of your voice connection is the same you're about to join: if so, you don't need to do anything (you're already in the channel), otherwise you join, make the sound etc...
You can do this with VoiceConnection.channel
Here's how I would do it:
const voiceChannel = message.member.voice.channel
if (voiceChannel) {
// Check if any of the ALREADY EXISTING connections are in that channel, if not connect
if (!client.voice.connections.some(conn => conn.channel.id == voiceChannel.id)) {
const connection = await voiceChannel.join()
const dispatcher = connection.play("./sounds/xxx.mp3")
dispatcher.setVolume(0.5)
} // else: you're already in the channel
} else {
let m = await message.reply("You need to be in a voice channel!")
m.delete({ timeout: 5000 })
}
I want my bot to join the voice channel where the commanding person is located and say something then leave, I tried to do this but I failed. The bot joins the sound channel but does not say anything. How can I do that?
Codes:
client.on('message', async message => {
if (!message.guild) return;
if (message.content.toLowerCase() === prefix + "bruh" ) {
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
} else {
message.reply('First of all you have to join an audio channel !');
const ytdl = require('ytdl-core');
connection.play(ytdl('https://www.youtube.com/watch?v=2ZIpFytCSVc', { filter: 'audioonly' }));
}
}
});
Your bot is not playing that YouTube video because you did not tell it to since you put the play() method in the else statement, not the if statement where it belongs.
Also, when importing a package, it is important you do so at the top of your file, not within the code, this is bad practice.
const ytdl = require('ytdl-core');
client.on('message', async message => {
if (!message.guild) return;
if (message.content.toLowerCase() === prefix + "bruh") {
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
connection.play(ytdl('https://www.youtube.com/watch?v=2ZIpFytCSVc', { filter: 'audioonly' }));
} else {
message.reply('First of all you have to join an audio channel !');
}
}
});
When a user joins the server, the bot sends a welcome message, i want to take that welcome message's ID and make the bot delete it if the users leaves after he joins. I tried to save the message's id in a variable and make the bot delete the message when the user leaves but without success. I already took a look at the docs, but I really can't understand how to make it.
Define an object to hold the welcome messages by guild and user. You may want to use a JSON file or database (I'd highly recommend the latter) to store them more reliably.
When a user joins a guild...
Send your welcome message.
Pair the the message's ID with the user within the guild inside of the object.
When a member leaves the guild...
Fetch their welcome message.
Delete the message from Discord and the object.
Example setup:
const welcomeMessages = {};
client.on('guildMemberAdd', async member => {
const welcomeChannel = client.channels.get('channelIDHere');
if (!welcomeChannel) return console.error('Unable to find welcome channel.');
try {
const message = await welcomeChannel.send(`Welcome, ${member}.`);
if (!welcomeMessages[member.guild.id]) welcomeMessages[member.guild.id] = {};
welcomeMessages[member.guild.id][member.id] = message.id;
} catch(err) {
console.error('Error while sending welcome message...\n', err);
}
});
client.on('guildMemberRemove', async member => {
const welcomeChannel = client.channels.get('channelIDHere');
if (!welcomeChannel) return console.error('Unable to find welcome channel.');
try {
const message = await welcomeChannel.fetchMessage(welcomeMessages[member.guild.id][member.id]);
if (!message) return;
await message.delete();
delete welcomeMessages[member.guild.id][member.id];
} catch(err) {
console.error('Error while deleting existing welcome message...\n', err);
}
});
To do this you would have to store the id of the welcome message and the user that it is tied to (ideally put this in an object). And when the user leaves you would use those values to delete that message.
Example code:
const Discord = require('discord.js');
const client = new Discord.Client();
const welcomeChannel = client.channels.find("name","welcome"); // Welcome is just an example
let welcomes = [];
client.on('message', (message) => {
if(message.channel.name === 'welcome') {
const welcomeObj = { id: message.id, user: message.mentions.users.first().username };
welcomes.push(welcomeObj);
}
});
client.on('guildMemberRemove', (member) => {
welcomes.forEach(welcome, () => {
if(welcome.user === member.user.username) {
welcomeChannel.fetchMessage(welcome.id).delete();
}
});
});
This only works if the welcome message includes a mention to the user so make sure that's in the welcome message.
Also I can't test this code myself at the moment so let me know if you encounter any problems.