Grabbing the permissions from a TextChannel - Discord.js - discord

Basically, I need to grab the permissions from the current text channel the user is in. I have already got the channel name, if I need to get the ID that should be pretty easy to do.
const Discord = require("discord.js");
module.exports.run = async (client, message, args) => {
let currentChannel = message.channel.name;
let category = message.channel.parent;;
message.guild.createChannel(currentChannel).then(mchannel => {
mchannel.setParent(category).then(() => {
message.channel.delete();
});
});
}
module.exports.help = {
name: "a.cleanchannel"
}
// Need the channel permissions to overwrite the new channel's permissions with the old ones
The expected results are that the channel should have the same permissions as the old one.

To answer your question directly, you can use GuildChannel#permissionOverwrites to create the new channel with the same permissions as the old one. For example...
message.guild.createChannel(message.channel.name, {
type: 'text',
permissionOverwrites: message.channel.permissionOverwrites
});
However, it looks like you're trying to clone a channel. To help make that easier, there's a method built into Discord.js for it - GuildChannel#clone(). You can use it like so...
message.channel.clone(undefined, true, true) // Same name, same permissions, same topic
.then(async clone => {
await clone.setParent(message.channel.parent);
await clone.setPosition(message.channel.position);
await message.channel.delete();
console.log(`Cloned #${message.channel.name}`);
})
.catch(console.error);

Related

How can I DM the user an embed before he is kicked (discord.js)

I'm trying to make a blacklist command, and how do I make it so it sends an embed instead of normal message.
(Also, I'm new to discord.js)
Here's my script:
module.exports = {
data: new SlashCommandBuilder()
.setName('blacklist')
.setDescription('Blacklist someone from the server')
.addUserOption((option) => option.setName('member')
.setDescription('Who are you blacklisting?')),
async execute(interaction) {
await interaction.deferReply();
const member = interaction.options.getMember('member');
if (!interaction.member.roles.cache.some(r => r.name === "Blacklist perms")) {
return interaction.editReply({ content: 'You do not have permission to use this command!' });
}
member.send("You have been blacklisted!")
member.kick().catch(err => {
interaction.editReply({ content: `I do not have enough permissions to do that.`})
})
await interaction.editReply({ content: `${member} has been succesfully blacklisted!` });
},
};```
Since your function is already async, simply await sending the message before you call kick.
await member.send("You have been blacklisted!")
member.kick().catch(err => {
interaction.editReply({ content: 'I do not have enough permissions to do that.'})
})
You might also wanna catch() on the send method because users can have DMs from server members disabled or blocked your bot.
You also might consider banning the user instead, because this system would fail if your bot ever happens to go offline when a blacklisted user tries to join. Additionally, depending on how fast your bot reacts, the user may still have time to spam in channels or do something harmful before your bot is able to kick them.
To send an embed either use an EmbedBuilder or a plain JavaScript object with the correct embed structure.
Example:
member.send({ embeds:[{
title: "Title",
description: "Hello World!"
}] })

Discord.js Filter Discord Events From Only 1 Server

I am working on trying to filter events for only 1 server rather than all servers the bot is in, but I'm trying to figure out how to exactly save each guild the bot is in as an collection so I can just filter events based on a guild ID I desire. Is this even possible? This is a snippet of the code I have to date, it's able to display the server names and ID's the bot is currently in, the events are working properly but triggering for all servers rather than the one I desire, how would I go about filtering for one guild collection?
const Discord = require('discord.js')
const bot = new Discord.Client()
const config = require('./config.json')
bot.on('ready', () => {
console.log(`Logged in as ${bot.user.tag}!`);
//Sets Activity
//client.user.setStatus('invisible')
bot.user.setActivity("Discord Cooks", { type: "WATCHING"})
console.log("Set User Activity!");
//Online Webhook
const webhookClient = new Discord.WebhookClient('','');
const embed = new Discord.MessageEmbed()
.setTitle(`${bot.user.tag} is online`)
.setColor('#FFFF00')
.setTimestamp()
webhookClient.send(embed);
bot.guilds.cache.forEach((guild) => {
console.log(guild.name, guild.id);
});
});
bot.on("channelCreate", (channel) => {
console.log(`channelCreate: ID: ${channel.id} Name: ${channel.name}`);
});
bot.on("channelUpdate", (oldChannel, newChannel) => {
console.log(`channelUpdate -> ${oldChannel.name} to ${newChannel.name}`);
});
bot.on("channelDelete", (channel) => {
console.log(`channelDelete: ID: ${channel.id} Name: ${channel.name}`);
});
bot.login(config.bottoken)
You can only execute code if event happened on exact server in much easier way:
if(guild.id == "GUILD_ID") {
// code
}
Also as #MrMythical said, you can just use if (message.guild.id !== "GUILD_ID") return; if you only need to run your code for 1 guild!

Guild Members TImeout: Members didn't arrive in time

So I have this command that shows the riches users in a server this command worked yesterday however recently it has stopped working.
const { MessageEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
const { prefix } = require("../../botconfig.json");
const db = require('quick.db')
let bal = require('../../database/balance');
let rep = require('../../database/rep');
let work = require('../../database/works');
module.exports = {
config:{
name: "rich",
aliases: ["r"],
category: "currency",
description: "Tells who is rich",
usage: ""
},
run: async (client, message, args) => {
// Get all members of the server before doing anything
message.guild.members.fetch().then(guildMembers => {
let board = [];
for (let key of Object.keys(bal)) {
// Checks if the collection of GuildMembers contains the key.
if (guildMembers.has(key)) {
let value = Object.assign({user: guildMembers.get(key).user}, bal[key]);
board.push(value);
}
}
const emojis = [':first_place:', ':second_place:', ':third_place:', ':small_blue_diamond:', ':small_blue_diamond:']
board = board.sort((a,b) => b.balance-a.balance).splice(0, 5);
let top = board.map((x, i) => `${emojis[i]} **${x.balance.toLocaleString()}** - ${x.user.tag}`).join('\n');
let embed = new MessageEmbed()
.setColor("RANDOM")
.addField(`Richest users in **${message.guild.name}**`, `${top}`)
.setFooter('Switch Version 1.1');
return message.channel.send(embed);
}).catch(console.error)
}
}
The error code when the !rich command is used is as follows:
Guild_Members_Timeout: Members didn't arrive in time
I don't know if this is an issue within the bot or if it is an issue with discord.
Okay I have found the answer to my own problem it seems I needed to add intents to my discord bot to fetch the members.
All I did was add this line of code and it worked.
const intents = new Intents([
Intents.NON_PRIVILEGED, // include all non-privileged intents, would be better to specify which ones you actually need
"GUILD_MEMBERS", // lets you request guild members (i.e. fixes the issue)
]);
const client = new Client({ ws: { intents } });
None of my discord.js guildmember events are emitting, my user caches are basically empty, and my functions are timing out? . In this post it is explained in great detail and that helped me out a lot.TLDR:go to discord developer portal on your particular application ,go to bot , on bot permissions tick whatever is needed and copy the number.Then use this number as a constructor parameter for new Discord.Intents('insert the number here').This worked for me.

How to get the channelid or name of a newly created channel

I have a command with my discord bot to make a channel, but I'm trying to figure out how to get the id or name of the channel right after its made.
Line of code that makes the channel:
message.guild.channels.create('ticket ' + message.member.displayName, { parent: '744477882730020965' });
The reason is that since displayname can have characters not possible in a channel name and discord will just automatically remove those characters there's no actual way to predict what the channel name will be in some cases. There's probably a simple solution I'm missing, and thanks in advance for any help.
The GuildChannelManager#create method returns a Promise with the channel that was just created. You can use Promise.then() to get the channel.
Guild.channels.create(`ticket-${message.member.displayName}`, {
parent: "744477882730020965"
}).then(channel => {
message.channel.send(`I've created the channel ${channel.name}!`);
}).catch(error => {
console.error(error);
message.channel.send(`Couldn't create the channel. Check the console for the error.`);
});
If you are creating the channel in an async function, you can use await to avoid .then() for readability.
const Channel = await Guild.channels.create(`ticket-${message.member.displayName}`, {
parent: "744477882730020965"
}).catch(error => {
console.error(error);
message.channel.send(`Couldn't create the channel. Check the console for the error.`);
});
What do you need the ID for? You can use a then function to do whatever to edit the channel.
Try this?
let role = message.guild.roles.find("name", "#everyone");
message.guild.channels.create('ticket ' + message.member.displayName, { parent: '744477882730020965' }).then(c => {
c.overwritePermissions(role, {
SEND_MESSAGES: false,
READ_MESSAGES: false
});
c.overwritePermissions(message.author, {
SEND_MESSAGES: true,
READ_MESSAGES: true
});
message.reply(`Application created!`)
c.send(`Wait for support staff`)
}).catch(console.error);

DiscordJS Backdoor Command

I have had reports off my support server of my discord js bot of my bot being abused in multiple ways.
I want to have a way upon launch of my bot to see a list of servers as well as invite links to those servers. I do not know the id of server or anything.
The most I've managed to find out how to do is this
var server = client.guilds.get("idk the id part");
console.log('I am in the following servers:');
server.createInvite().then(invite =>
console.log(server.name + "-" + invite.url)
);
});```
In your ready event (client.on('ready', () => {}), add the following lines:
client.guilds.tap(guild => {
console.log(`Name: ${guild.name} ID: ${guild.id}`);
})
This should output
Name: Test1 ID: 00000000000000
in the console for each server.
Also, considering that making a lot of invites might clog up your bot, and is generally more of a hindrance than help to server admins, you might consider making a createinvite command:
const svID = args[0];
const guild = client.guilds.find(guild => guild.id === svID);
const channel = guild.channels.find(channel => channel.position === 1);
channel.createInvite()
.then(invite => message.reply(invite.code));
You can either wait for the bot to emit it's ready event and loop through the guild collection:
client.once('ready', () => {
// client.guilds should be ready
});
or handle each guild individually:
client.on('guildCreate', (guild) => {
// The guild the bot just joined/connected to
// Should also be emitted when the bot launches
});
Either should work, but my recommendation would be the second approach, as this will also allow you to track join events whilst the bot is running.

Resources