How to give own bot permission to see categories? - python-3.x

My bot has a Command that creates a Category, and inside it, a Text and Voice channel. On creating the Category I overwrite the permission to let only a certain role to see that category and its channels.
Everything until this works fine. My problem comes when I want my bot to see the text channel, so he can read and interact with messages. My bot doesn't have any extra role aside from the Discord App one.
So far, this are the solutions I tried:
Set Bot to Administrator: This solution works, but want to discart it, since I don't know if it is recommended to set your bot as Administrator, and I believed there should be other ways to solve the problem.
Add Permission to Category, setting my bot role to let him read and write messages, like this:
await category.set_permissions(bot_role, read_messages=True, send_messages=True, connect=True)
This throws an discord.errors.Forbidden: 403 Forbidden (error code: 50001): Missing Access error, which I don't understand since I have all permission set in my oauth page (see photo below).
I have also tried to give the same permissions to the text channel, but it throws the same error.
All I really want is my Bot to read messages in that text channel, since he won't respond to any command if the Bot can't see the channel.
Edit:
This is how I created the category and channels:
async def prepare_game(ctx):
guild = ctx.guild
role = await guild.create_role(name=role_name)
category = await guild.create_category('Game')
await category.set_permissions(role, read_messages=True, send_messages=True, connect=True, speak=True)
text_channel = await guild.create_text_channel('Board', category=category, sync_permissions=True)
voice_channel = await guild.create_voice_channel('Room', category=category, sync_permissions=True)
Then at the end, I added the await category.set_permissions(bot_role, read_messages=True, send_messages=True, connect=True)line, where bot_role is my app bot role

Try setting the permission overwrites for ctx.guild.me (the bot user itself).
From the docs, set_permissions will accept a Role or a Member.
For example:
async def prepare_game(ctx):
guild = ctx.guild
role = await guild.create_role(name=role_name)
category = await guild.create_category('Game')
await category.set_permissions(role, read_messages=True, send_messages=True, connect=True, speak=True)
await category.set_permissions(ctx.guild.me, read_messages=True, send_messages=True, speak=True)
text_channel = await guild.create_text_channel('Board', category=category, sync_permissions=True)
voice_channel = await guild.create_voice_channel('Room', category=category, sync_permissions=True)

Related

(discord.js v13) If channel exists

I'm making a ticketing system with buttons. I trying to if user opened a ticket, user can't open a new ticket. Im tried some code:
//ticket channel is created with **"help: " + interaction.user.username** name
if (interaction.guild.channels.fetch('channel name'))
//working with only id
if (interaction.guild.channels.cache.get(c=>c.name==='channel name'))
//reacted nothing
The discord.js channels cache is a Discord.Collection of values, meaning that it is a JS map with some extra quality of life methods added by Discord.js. Discord Collections are keyed using the snowflake id with the value being whatever object is being stored with that id (in this case the channel you want). This means that the method fetch on the collection of channels can always only be passed an ID as stated here in the docs. This would also mean that the Map.get() method you try to use in the second attempt will not return anything as the channel is not keyed by its name, its keyed by a snowflake id.
You can use a piece of code like this one I used in a discord moderation bot to find and return a channel by name if it exists in the cache.
/**
* Get the log channel for the provided guild.
* #param {Discord.Guild} guild The guild to get the log channel for.
*/
#getLogChannel = (guild) => {
const guildLogChannel = guild.channels.cache
.find(channel => channel.name === 'guild-logs');
if (!guildLogChannel) return false;
return guildLogChannel;
}
If the channel has not yet been cached you have no other option than to pass that channel into the interaction as an option, fetch the channel by its snowflake id, or fetch all channels for all guilds the bot is in inside your client.on('ready', () => {}) handler. The last option is what I chose to do for the bot that the above code snippet is taken from.

How to make a discord.py bot add a reaction to its own message

I am making a discord bot and I am trying to add a verify command where the person will use ".verify" then the bot will send me a dm with 2 reactions, a check mark, and an X. But I cant get the discord bot to add the reactions or give the role on the reaction of yes.
code:
#client.command()
async def verify(ctx):
verifier = ctx.author
jj = await client.fetch_user(270397954773352469)
await ctx.send(f'{verifier}... Awaiting Verification, you will recieve a dm when you are verified')
dm = await jj.send(f'{verifier.mention} is trying to be verified, do you know him/her?')
await dm.add_reaction(':white_check_mark:')
await dm.add_reaction(':no_entry_sign:')
Try entering the unicode version of the emoji's, For example
await dm.add_reaction("✅")
await dm.add_reaction("🚫")
Here is where you can find a lot of useful emojis: https://emojipedia.org/
You just copy them and paste them in your code, and they should turn into the discord version. I don't think it works with all emoji's though so keep that in mind

I keep getting an error in discord.js "discord is not defined" OR I get no response from the bot. Not even an error/

I am coding a discord bot using discord.js.
FOR SOME REASON it says Discord not defined error or the bot has no response. Please could you help me? I have never had this error before. Here's the code.
I have include this command in the same main.js file:
if(cmd === `${prefix}help`){
reporthelp = "Report a user. Requires a channel named `reports`to work!";
kickhelp = "Kick a user from the server. Requires a channel named `incidents` to work; you must have the manage messages permission.";
banhelp = "Ban a user from the server. Requires a channel named `incidents` to qork; toy need the BAN MEMBERS permission to use this command!";
warnhelp = "**COMMAND COMING SOON!**";
requiredperms = "**Embed Links, channel named `incidents`; channel named `reports`; channel named `suggestions`; Kick Members, Ban Members, Manage Roles, Manage Members.**"
helpEmbed = new Discord.RichEmbed()
.setDescription(" 💬 **__Help Is Here!__** 💬")
.setColor("#936285")
.addField("**/report #user <reason>**", reporthelp)
.addField("**(COMING SOON)** /warn #user <reason>", warnhelp)
.addField("**/kick #user <reason>**", kickhelp)
.addField("**/ban #user <reason>**", banhelp)
.addField("**/mytag**", "Shows you **your** discoord username#discrim and your user ID. Requires Embed Links permission.")
.addField("**/invite**", "Get a linkto incite meto our server, and an invite link to my suppoer server")
.addField("**/owner**", "see who currently owns the bot")
.addField("**/git**", "**SOURCE CODE AVAILIBLE SOON**")
.addField("**/token**", "View the bot's super secret bot token!")
.addField("**/serverinfo**", "displays some basic server information!")
.addField("**/botinfo**", "displays basic bot information!")
.addField("**/ping**", "Get the bot to respond with `pong` ")
.addField("**/hosting**", "Bot finds a good website for bot/web hosting")
.addField("**/quotes**", "bot responds with some lovely quotes!")
.addField("**__Required Permissions__**", requiredperms)
// .addField("**COMING SOON!**/suggest <suggestion>", "suggest something. Requires channel named `suggestions`")
.setTimestamp()
.setFooter("Use /invite to invite me to your server!")
return message.channel.send({embed: helpEmbed});
}
This is how I've defined everything:
const botconfig = require("./botconfig.json");
const tokenfile = require("./token.json");
const Discord = require("discord.js");
const bot = new Discord.Client({disableEveryone: true});
bot.on("ready", async () => {
console.log(`${bot.user.username} is active in ${bot.guilds.size} servers!`);
bot.user.setActivity("rewriteing main.js...", {type: "WATCHING"});
//bot.user.setGame("Lookin' out for ya!");
});
bot.on("message", async message => {
if(message.author.bot) return;
if(message.channel.type === "dm") return;
const prefix = botconfig.prefix;
const messageArray = message.content.split(" ");
const cmd = messageArray[0];
const args = messageArray.slice(1);
const bicon = bot.user.displayAvatarURL;
I either get no response/error, or I get the error discord is not defined.
I'm also very new here, sorry If I didn't ask a question clearly...
The code is correct, but I had redfined discord in a different part of the file....
my advice would be to alays read the code over again!

Check if the user adding a reaction has a role

I want to check if the user reacting to a message has a role or not, so that if the user dont have a rank the bot will ignore the rest of the command, but I dont know how.
example: if a user with the admin rank reacted with :eggsa: emoji, the bot would continue with the command, but if i only had member rank the bot would ignore me.
client.on('messageReactionAdd', reaction => {
const eggsa = client.emojis.find(emoji => emoji.name === "eggsa");
if (reaction.emoji.name === 'eggsa') {
const message = reaction.message;
const kanal = reaction.message.guild.channels.find('name', 'sitater');
var embed = new Discord.RichEmbed()
.setAuthor(reaction.message.content)
.setTimestamp()
.setFooter(reaction.message.author.username, reaction.message.author.avatarURL)
kanal.send({embed});
}
});
the code works in this stage, only everyone can use it
I would be really grateful if someone could help me >:)
If you look at the messageReactionAdd docs you can see that along with the reaction, you can also get the user which added the reaction. So instead of
client.on('messageReactionAdd', reaction => {
You'd have
client.on('messageReactionAdd', (reaction, user) => {
So then you have the user and which is of type User. Because the user isn't of type GuildMember you first need to fetch the correct Guild member before you can check his/her role.
The easiest way to do this is by getting the Message to which the reaction was added with const msg = reaction.message;. Then you can get the guild from the message with const guild = msg.guild;. Now you can access the guild members with const guildMembers = guild.members;. Lastly you'd need to find the correct member with const guildMember = guildMembers.get(user.id);.
Now that you have your Guild Member you can access his/her Roles and thus check whether he/she has or does not have a certain role

Discord.js Backdoor command

I've seen my bot join many more servers, but it seems like some are abusing it.
I want the bot to make a one time use invite to a server that I am not on, but my bot is. Once I am on the server I can just remove it. It would be like so:
^backdoor "guild id". I am very new to coding. Thanks!
There are 2 possible ways of doing this, but both are reliant on the permissions that the bot has in that guild.
guildid has to be replaced with an ID or an variable equivilant to the ID
Way 1:
let guild = client.guilds.get(guildid):
if (!guild) return message.reply("The bot isn't in the guild with this ID.");
guild.fetchInvites()
.then(invites => message.channel.send('Found Invites:\n' + invites.map(invite => invite.code).join('\n')))
.catch(console.error);
Way 2:
let guild = client.guilds.get(guildid):
if (!guild) return message.reply("The bot isn't in the guild with this ID.");
let invitechannels = guild.channels.filter(c=> c.permissionsFor(guild.me).has('CREATE_INSTANT_INVITE'))
if(!invitechannels) return message.channel.send('No Channels found with permissions to create Invite in!')
invitechannels.random().createInvite()
.then(invite=> message.channel.send('Found Invite:\n' + invite.code))
There would also be the way of filtering the channels for SEND_MESSAGE and you could send a message to the server.
Instead of entering the guild and then removing it, it would be simpler to just make the bot leave the guild, using Guild.leave()
// ASSUMPTIONS:
// guild_id is the argument from the command
// message is the message that triggered the command
// place this inside your command check
let guild = client.guilds.get(guild_id);
if (!guild) return message.reply("The bot isn't in the guild with this ID.");
guild.owner.send("The bot has been removed from your guild by the owner.").then(() => {
guild.leave();
});

Resources