I made code such that if someone connects to a particular channel, the bot will create a channel with their name and then move them in it. I want the bot to auto-delete the channel when this user disconnects and no one else connects to this channel. I have this code but I don't know how to delete the channel.
bot.on('voiceStateUpdate', (oldMember, newMember) =>{
let mainCatagory = '604259561536225298';
let mainChannel = '614954752693764119';
if(newMember.voiceChannelID === mainChannel){
newMember.guild.createChannel(`${newMember.user.username}'s Channel`,'voice')
.then(temporary => {
temporary.setParent(mainCatagory)
.then(() => newMember.setVoiceChannel(temporary.id))
}).catch(err =>{
console.error(err);
})
}
});
I tried to do if(newMember.voiceChannel.members.size === 0){temporary.detele}; but temporary is not defined.
Create an array to write the ID of the temporary channel and the server on which this channel was created, in front of the body of the event.
var temporary = []
bot.on('voiceStateUpdate', (oldMember, newMember) =>{
const mainCatagory = '604259561536225298';
const mainChannel = '614954752693764119';
if(newMember.voiceChannelID == mainChannel){
// Create channel...
await newMember.guild.createChannel(`${newMember.user.username}'s channel`, {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!
if(ch.members.size <= 0){
await ch.delete()
// Channel has been deleted!
return temporary.splice(i, 1)
}
}
})
You could try defining an empty variable first, like temp and then assign it the temporary channel when returning the createChannel() promise, like so:
bot.on('voiceStateUpdate', (oldMember, newMember) =>{
let mainCatagory = '604259561536225298';
let mainChannel = '614954752693764119';
let temp;
if(newMember.voiceChannelID === mainChannel){
newMember.guild.createChannel(`${newMember.user.username}'s Channel`,'voice')
.then(temporary => {
temp = temporary
temporary.setParent(mainCatagory)
.then(() => newMember.setVoiceChannel(temporary.id))
}).catch(err =>{
console.error(err);
})
}
if(newMember.voiceChannel.members.size === 0){temp.delete()};
});
This is based on Raifyks' answer, but updated for Discord.js v12/v13 and has a few improvements.
const mainCategory = '604259561536225298';
const mainChannel = '614954752693764119';
// A set that will contain the IDs of the temporary channels created.
/** #type {Set<import('discord.js').Snowflake>} */
const temporaryChannels = new Set();
bot.on('voiceStateUpdate', async (oldVoiceState, newVoiceState) => {
try {
const {channelID: oldChannelId, channel: oldChannel} = oldVoiceState;
const {channelID: newChannelId, guild, member} = newVoiceState;
// Create the temporary channel
if (newChannelId === mainChannel) {
// Create the temporary voice channel.
// Note that you can set the parent of the channel in the
// createChannel call, without having to set the parent in a
// separate request to Discord's API.
const channel = await guild.channels.create(
`${member.user.username}'s channel`,
{type: 'voice', parent: mainCategory}
);
// Add the channel id to the array of temporary channel ids.
temporaryChannels.add(channel.id);
// Move the member to the new channel.
await newVoiceState.setChannel(channel);
}
// Remove empty temporary channels
if (
// Is the channel empty? (thanks to Rakshith B S for pointing this out)
!oldChannel.members.size &&
// Did the user come from a temporary channel?
temporaryChannels.has(oldChannelId) &&
// Did the user change channels or leave the temporary channel?
oldChannelId !== newChannelId
) {
// Delete the channel
await oldChannel.delete();
// Remove the channel id from the temporary channels set
temporaryChannels.delete(oldChannelId);
}
} catch (error) {
// Handle any errors
console.error(error);
}
});
Related
I want to make a log system for my server. Ban/Kick log.
It is working but there is a bug that, when I kick a member, It sends 1 message; but when I ban a member it sends 2 different messages.
When I kick a member:
When I ban a member:
I wrote some code:
const { AuditLogEvent } = require('discord.js');
// ban detector
client.on('guildBanAdd', async (ban) => {
const fetchedLogs = await ban.guild.fetchAuditLogs({
limit: 1,
type: 'MEMBER_BAN_ADD',
});
const banLog = fetchedLogs.entries.first();
if (!banLog) return;
const { executor, target } = banLog;
if (target.id === ban.user.id) {
const channel = client.channels.cache.get("954475961234116719");
channel.send(`<#${ban.user.id}> was Banned by <#${executor.id}>`)
} else {
return;
}
});
And another one:
// kick detector
client.on('guildMemberRemove', async (member) => {
const fetchedLogs = await member.guild.fetchAuditLogs({
limit: 1,
type: 'MEMBER_KICK',
});
const kickLog = fetchedLogs.entries.first();
if (!kickLog) return;
const { executor, target } = kickLog;
if (target.id === ban.user.id) {
const channel = client.channels.cache.get("954475961234116719");
channel.send(`<#${member.user.id}> was kicked by <#${executor.id}>`)
} else return;
});
Notes: I am using Node.js v16+ and discord.js v13
It shouldn't do that, both MEMBER_KICK and MEMBER_BAN_ADD are different. Do note that audit logs are not guaranteed to be generated immediately
If you are still using this code, then I see 1 error. You are checking ban.user.id in both MEMBER_BAN_ADD and MEMBER_KICK event.
So, I wanted to add command /custom and after that, user would enter they nicknames through messages. Bot should check if ther nickname is in game (async function checkIfSummonerExist(m)) and if it does exist, bot should collect their name and data and push to array (async function getSummonerProfile(m.content)). Now I wanted to add bot reactions to those messages, if nickname exist, it should add one reaction (for example thumbs up), and if name does not exist one should add thumbs down. So I tried with m.react(), but it does not work. I also tried with m.reply("User approved")but I don't get reply. I am new to making discord bot.
const { SlashCommandBuilder } = require("#discordjs/builders");
const { getSummonerProfile } = require("./../functions/summonerData");
const { calculateRank } = require("./../functions/calculateRank");
let arrayOfSummoners = [];
async function checkIfSummonerExist(m) {
const test = await getSummonerProfile(m.content);
if (test) {
return true;
} else {
return false;
}
}
module.exports = {
data: new SlashCommandBuilder()
.setName("custom")
.setDescription(
"Enter the name of the user."
),
async execute(interaction) {
await interaction.deferReply();
// `m` is a message object that will be passed through the filter function
const filter = (m) => checkIfSummonerExist(m);
const collector = interaction.channel.createMessageCollector({
filter,
time: 15000,
});
collector.on("collect", (m) => {
m.reply('User approved');
m.react('😄');
arrayOfSummoners.push(getSummonerProfile(m.content));
});
collector.on("end", (collected) => {
// return interaction.editReply(`Collected ${collected.size} items`);
// calculateRank(arrayOfSummoners);
});
// return interaction.editReply();
},
};
When I'm online the bot gives me a role, as soon as I go offline the bot removes that role from me.
When it removes the role, I want the bot to give the role to a specific user. How can I do that?
I have my current code below:
client.on('presenceUpdate', (oldPresence, newPresence) => {
const member = newPresence.member;
if (member.id === 'user.id') {
if (oldPresence.status !== newPresence.status) {
var gen = client.channels.cache.get('channel.id');
if (
newPresence.status == 'idle' ||
newPresence.status == 'online' ||
newPresence.status == 'dnd'
) {
gen.send('online');
member.roles.add('role.id');
} else if (newPresence.status === 'offline') {
gen.send('offline');
member.roles.remove('role.id');
}
}
}
});
You could get the other member by its ID. newPresence has a guild property that has a members property; by using its .fetch() method, you can get the member you want to assign the role to. Once you have this member, you can use .toles.add() again. Check the code below:
// use an async function so we don't have to deal with then() methods
client.on('presenceUpdate', async (oldPresence, newPresence) => {
// move all the variables to the top, it's just easier to maintain
const channelID = '81023493....0437';
const roleID = '85193451....5834';
const mainMemberID = '80412945....3019';
const secondaryMemberID = '82019504....8541';
const onlineStatuses = ['idle', 'online', 'dnd'];
const offlineStatus = 'offline';
const { member } = newPresence;
if (member.id !== mainMemberID || oldPresence.status === newPresence.status)
return;
try {
const channel = await client.channels.fetch(channelID);
if (!channel) return console.log('Channel not found');
// grab the other member
const secondaryMember = await newPresence.guild.members.fetch(secondaryMemberID);
if (onlineStatuses.includes(newPresence.status)) {
member.roles.add(roleID);
secondaryMember.roles.remove(roleID);
channel.send('online');
}
if (newPresence.status === offlineStatus) {
member.roles.remove(roleID);
secondaryMember.roles.add(roleID);
channel.send('offline');
}
} catch (error) {
console.log(error);
}
});
This is my code
bot.on("guildMemberRemove", async (member) => {
const tlog = await member.guild.fetchAuditLogs({
limit: 1,
type: "MEMBER_KICK",
});
const klog = tlog.entries.first();
const { executor, target } = klog;
const rs = tlog.entries.first().reason;
const emb = new Discord.MessageEmbed()
.setTitle("Új KICK!") //New Kick Title
.addField("Kickelt neve", target.user) //The kicked member name
.addField("Kickelő neve", executor) //The member who kicked the other member
.addField("Indok", rs) //Reason
.setTimestamp()
.setColor(15158332)
addToLog(emb);
})
addToLog Function
const channell = "792743591017316413"; //Channel id
function addToLog(message){
const szoba = bot.channels.cache.get(channell); //szoba means room
return szoba.send(message);
};
I looked more websites for the solution, but I completely copy the code and nothing happens.
If you take a look at the docs for TextChannel.send(). It returns a promise, you need to resolve this promise with either an await or .then().
I edited your code into:
function addToLog(message, channel) {
return channel.send(message);
};
bot.on("guildMemberRemove", async (member) => {
const tlog = await member.guild.fetchAuditLogs({
limit: 1,
type: "MEMBER_KICK",
});
const klog = tlog.entries.first();
const { executor, target } = klog;
const rs = tlog.entries.first().reason;
const channell = "Your channel ID"; //Channel id
const szoba = bot.channels.cache.find(ch => ch.id === channell);
const emb = new Discord.MessageEmbed()
.setTitle("Új KICK!") //New Kick Title
.addField("Kickelt neve", target.user) //The kicked member name
.addField("Kickelő neve", executor) //The member who kicked the other
member
.addField("Indok", rs) //Reason
.setTimestamp()
.setColor(15158332)
addToLog(emb, szoba);
})
I used a second parameter channel, which in this case is your szoba. So you initialize the two constants channell and szoba outside of the function. Then you provide a message and your constant szoba (thats the channel you want your log been sent to). Inside of the function addToLog() you simply want the provided message sent to the provided channel (szoba).
How do I make it so that when someone reacts with the first emoji in this command, the bot deletes the message and sends it to another channel?
Current Code:
const Discord = require("discord.js");
module.exports.run = async (bot, message, args) => {
if (!message.member.hasPermission("MANAGE_MESSAGES"))
return message.channel.send("You are not allowed to run this command.");
let botmessage = args.join(" ");
let pollchannel = bot.channels.cache.get("716348362219323443");
let avatar = message.author.avatarURL({ size: 2048 });
let helpembed = new Discord.MessageEmbed()
.setAuthor(message.author.tag, avatar)
.setColor("#8c52ff")
.setDescription(botmessage);
pollchannel.send(helpembed).then(async msg => {
await msg.react("715383579059945512");
await msg.react("715383579059683349");
});
};
module.exports.help = {
name: "poll"
};
You can use awaitReactions, createReactionCollector or messageReactionAdd event, I think awaitReactions is the best option here since the other two are for more global purposes,
const emojis = ["715383579059945512", "715383579059683349"];
pollchannel.send(helpembed).then(async msg => {
await msg.react(emojis[0]);
await msg.react(emojis[1]);
//generic filter customize to your own wants
const filter = (reaction, user) => emojis.includes(reaction.emoji.id) && user.id === message.author.id;
const options = { errors: ["time"], time: 5000, max: 1 };
msg.awaitReactions(filter, options)
.then(collected => {
const first = collected.first();
if(emojis.indexOf(first.emoji.id) === 0) {
msg.delete();
// certainChannel = <TextChannel>
certainChannel.send(helpembed);
} else {
//case you wanted to do something if they reacted with the second one
}
})
.catch(err => {
//time up, no reactions
});
});