Trying to set up permissions for a discord bot but can't seem to be able to - discord

So I'm making a discord bot for a server that I use and wanted to add a censor feature so that if a user said something in the "bannedWords" list while not in a specific channel (working) it would edit the message to have "[redacted]" in its place. I believe the code itself is working but I get this error message every time I test it. I've tried adding permissions via the Discord Developer Portal (selecting "OAuth2," choosing the "bot" scope, and the manage roles, view channels, send messages, manage messages, read message history, and mention everyone permissions), copied the link and added it to my testing server but it still didn't seem to work along with having the proper permissions via role.
Full Error:
Traceback (most recent call last):
File "C:\Users\Me\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "C:\Users\Me\Desktop\Productive\Programming Projects\Python 3\Other\MyBot\bot.py", line 32, in on_message
await message.edit(content = editedMessage)
File "C:\Users\Me\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\message.py", line 843, in edit
data = await self._state.http.edit_message(self.channel.id, self.id, **fields)
File "C:\Users\Me\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\http.py", line 241, in request
raise Forbidden(r, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50005): Cannot edit a message authored by another user
Code
import discord
bot=discord.Client()
#bot.event
async def on_ready():
print('Logged in')
print("Username: %s" % (bot.user.name))
print("Userid: %s" % (bot.user.id))
#bot.event
async def on_message(message):
if message.author.id == bot.user.id:
return
bannedWords=['chink','dyke','fag','ook','molest','nig','rape','retard','spic','zipperhead','tranny']
print(str(message))
print(str(message.content))
if "name='no-rules-lol'" not in str(message): #probably a better way to do this but it works
for word in bannedWords:
if word in message.content.lower():
await message.channel.send('{0.author.mention}, you have used a word that is black-listed please read <#754763230169006210> to get a full list of black-listed words'.format(message))
#await message.edit(content = message + 'this has been edited')
editedMessage=str(message.content.replace(word,'[redacted]'))
await message.edit(content = editedMessage)
bot.run(Token)

You cannot edit a message that is not sent by the bot.
Instead, just try deleting the message.
await message.delete()
It is as easy as that.
If you are adding more commands into your bot, you can just add this to your on_message at last:
await bot.process_commands(message)
Thank you.

Related

Discord.py wait_for command when user adds reaction

So I need some help!
So far I have the code do the following... Someone inputs the !stage command and then their stage(int)... It sends a message in another where the FTO will react to the message. When reacted the FTO will get a DM with info!
So my question is how do I use wait_for for the user who originally sent the command to be contacted by the bot when the FTO clicks the reactions. Like I need the bot to send that original command user a DM with who clicked the reaction.
#client.command()
async def stage(ctx, *, stage):
ftochannel = client.get_channel(1043289756794093639)
logchannel = client.get_channel(1037550844935147622)
embed=discord.Embed(title=f"{ctx.author.mention} has requested ride along for stage **{stage}**",description=f"If you want to assist this member with their requested stage react below!", color=0x660066)
log=discord.Embed(title=f"Discord Log // User Requested Ride Along in BCSO Discord",description=f'Ran By: {ctx.author.mention}\nActual Command Finish: {ctx.author.mention} has just requested the following stage: {stage}! ',color=0x660066)
emoji = "\N{Large Yellow Circle}"
msg = await ftochannel.send(embed=embed)
await msg.add_reaction(emoji)
await ctx.send("When an FTO member answers me You will get a message from me with more information! Please be patient!")
await logchannel.send(embed=log)
#client.event
async def on_raw_reaction_add(payload):
if str(payload.emoji) == "\N{Large Yellow Circle}":
member = payload.member
sendEmbedToUser = discord.Embed(title=f'Hello', description=f'You have accepted THIS PERSONS Stage RIDE ALONG!\nPlease Arrive in <#1038926472259313732> within **10 Minutes**!\n\nHere is some helpful documentation for your ride along:\n[LINK SHORTNER 1]\n[LINK SHORTNER 1]\n[LINK SHORTNER 1]\n[LINK SHORTNER 1]')
await member.send(embed=sendEmbedToUser)
[]
With some help from friends I no know I need to used wait_for somewhere in the stage command but I have no clue how to do it!

AttributeError: 'function' object has no attribute 'send' - Discord,py Bot error

channel = client.get_channel
if message.content.lower().startswith('experiment'):
moji = await client.get_channel.send("https://c.tenor.com/R_itimARcLAAAAAd/talking-ben-yes.gif")
emoji = [":blue_circle:"]
for experiment in emoji:
await client.add_reaction(emoji)
What I want the bot to do is when the user types 'experiment' the bot will send the link to the photo and it will attach the emoji to it. It gives me this error.
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\13129\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "c:\Users\13129\Desktop\Python Bot\Ben.py", line 50, in on_message
moji = await client.get_channel.send("https://c.tenor.com/R_itimARcLAAAAAd/talking-ben-yes.gif")
AttributeError: 'function' object has no attribute 'send'
I tried changing a few things on line 20 but nothing seems to be working!
Bot.get_channel is a method which takes a channel_id as a positional argument and gets you a Union[StageChannel, VoiceChannel, CategoryChannel, TextChannel, Thread (if you are on master)] if the ID you pass to it matches one it has in its internal cache (this requeires members intent)
you can't do
get_channel.send(), get_channel is a method, or in other words, a bound function to Bot class.
here is an example usage:
channel = bot.get_channel(CHANNEL_ID)
await channel.send("hello there!")
also,
client.add_reaction(emoji) is not a thing
Message.add_reaction is. await channel.send() returns a Message object which you can store in a variable and then add your emoji
message = await channel.send("hello there!")
for emo in emoji:
await message.add_reaction(emo)
and I am pretty sure that you need the unicode of that emoji and the string would raise UnknownEmoji error, but if it doesn't then it's fine. If it does though, just use "\N{Large Blue Circle}" instead :blue_circle: and that should fix it.
You should be doing client.get_channel() with something in the brackets like a channel ID, not client.get_channel If not how will they know what channel to send it to.
For Prefixed Commands
#client.command()
async def command_name(ctx)
await ctx.send()
# Sends to what ever channel the command was sent in

#commands.has_permissions(administrator=True) not working properly?

I am trying to make a simple moderator bot.
the code looks something like this.
import discord
from discord.ext import commands
from random import choice
import os
client = commands.Bot(command_prefix=commands.when_mentioned_or("%"), description='A simple Moderator bot')
def colour():
l = [ 1752220, 3066993, 3447003, 10181046, 15844367, 15105570, 15158332, 3426654, 16580705 ]
return choice(l)
#client.event
async def on_ready():
change_status.start()
print("The Bot is online!")
#client.command()
#commands.has_permissions(administrator=True)
async def kick(ctx, user : discord.Member = None, *,reason = "No reason provided"):
await user.kick(reason = reason)
await ctx.send("Kicked the user.")
#client.command()
#commands.has_permissions(administrator=True)
async def ban(ctx, user : discord.Member = None, *,reason = "No reason provided"):
await user.ban(reason = reason)
await ctx.send("Banned the user")
#client.command()
#commands.has_permissions(administrator=True)
async def warn(ctx, user : discord.Member = None, *,reason = "No reason provided"):
await user.send(f"You have been **Warned** by **{ctx.author.name}** in the **{ctx.guild.name}** for the reason: **{reason}** ")
await ctx.send("Warned the user")
client.run(os.environ['token'])
In this only warn command is working successfully rest all the commands throws an error which looks like this.
Ignoring exception in command kick:
Traceback (most recent call last):
File "main.py", line 140, in kick
await user.kick(reason = reason)
File "/app/.heroku/python/lib/python3.6/site-packages/discord/member.py", line 524, in kick
await self.guild.kick(self, reason=reason)
File "/app/.heroku/python/lib/python3.6/site-packages/discord/guild.py", line 1886, in kick
await self._state.http.kick(user.id, self.id, reason=reason)
File "/app/.heroku/python/lib/python3.6/site-packages/discord/http.py", line 241, in request
raise Forbidden(r, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50013): Missing Permissions
It is throwing a missing permission but I am the owner of the server and even added the bot as an admistrator.
Even tried by making an administrator role and giving all the permissions to it but still no luck.
This error is coming again and again.
Even if anyone know how to check between multiple roles like if anyone has administrator or kick member permission then do this, please let me know how to do that.
Thanks in advance for the help.
If any more information needed, do let me know.
The error you are getting on the last line from your console; discord.errors.Forbidden: 403 Forbidden (error code: 50013): Missing Permissions Is because the bot is missing permissions to perform these actions against the given permissions the bot currently has.
This could occur from the following;
Sufficient Bot permissions haven't been enabled from the invite link
The member has a higher or equal role than the bot
The #everyone role has no permissions
Moreover, these issues aren't at fault with the code you have written and is something that can be fixed in your server with the role hierarchy or bot invite link permissions.
I would also recommend comparing roles to make sure users can't attempt moderation on a higher level member in the first place, this could also help to mitigate the problem
With this, you can use >= and the top_role attribute which would compare the roles that the user compared to the member you are attempting to take moderation on, if your permissions are lower than the member you are attempting to moderate, it will prevent the rest of the code running. Here is a simple way of doing this,
if member.top_role >= ctx.author.top_role:
await ctx.send(f"You can only moderate members below your role")
return

How can I delete a message in discord.py after a command was executed by an user?

I am trying to program a function that deletes the message with the command sent by the user.
E.g.:
User sends command /delmes
Bot sends a response to the command
Bot deletes the message sent by the user
Everything I was able to find until now (that would help me) was this Stack Overflow Thread: discord.py delete author message after executing command
But when I used the code, as described in the solutions, I only received AttributeError: 'Bot' object has no attribute 'delete_message'.
The discord.py API Reference (https://discordpy.readthedocs.io/en/latest/migrating.html#models-are-stateful / https://discordpy.readthedocs.io/en/latest/api.html?highlight=delete%20message#message) only revealed that some of the code had changed with newer versions.
So to speak client.delete_message would change to Message.delete(), if I interpreted it correctly!
After changing the code to what I thought it must be I received: NameError: name 'Message' is not defined
This is my code at the very last moment. (I am relatively new to discord.py and only used Python in school)
import discord
from discord.ext import commands
import random
import json
client = commands.Bot(command_prefix = '/', case_insensitive=True)
#client.command(pass_context=True)
async def delcommes(ctx):
await ctx.send("This is the response to the users command!")
await Message.delete(ctx.message, delay=3)
I couldn't understand your question very good but as far as I understand, when command executed, then after bot sends message, you want to delete the command message, in that case it's /delmes. You can use await ctx.message.delete().
#client.command(pass_context=True)
async def delcommes(ctx):
await ctx.send("This is the response to the users command!")
await ctx.message.delete()

{discord.py} Delete a specific message from a specific user

I want to delete a specific message from a specific user using discord.py
The user's id is: 462616472754323457
The message that he can't send: lmao
So if he sends lmao, it deletes the message and send "You can't do that <#462616472754323457>
Try discord.TextChannel.purge.
#client.event
async def on_message(message):
if len(await message.channel.purge(limit=200, check=lambda x: ('lmao' in x.content.strip().lower()) and x.author.id == 462616572754323457)) > 0:
await message.channel.send('You are not allowed to do that, <#462616572754323457>')
Accounting for when the bot is offline, the bot will check 200 messages before the current message and delete any that are from 462616572754323457 and have 'lmao' in the contents. (You can further enhance this by using re.)
You can use the on_message event, which triggers whenever a message is sent.
#bot.event
async def on_message(message):
await bot.process_commands(message) # add this if also using command decorators
if message.author.id == 462616472754323457 and "lmao" in message.content.lower():
await message.delete()
await message.channel.send(f"You can't do that, {message.author.mention}")
References:
discord.on_message()
Message.delete()
Bot.process_commands()
Member.mention

Resources