Having issue with my automod system in disocrd.py - discord.py

So, I'm trying to make an event that if anyone send any invite link, my BOT will detect, delete it and mute the user as well as send a log in my log channel tell that a user try to send an invite link in the server
This is my code so far:
#bot.event
async def on_message(ctx, message):
discordInviteFilter = re.compile("(...)?(?:https?://)?discord(?:(?:app)?\.com/invite|\.gg)/?[a-zA-Z0-9]+/?")
guild = ctx.guild
embed1=discord.Embed(title="Muted successfully", colour=red)
embed1.set_thumbnail(url=message.member.avatar_url)
embed1.add_field(name="Reason", value=f"Send invite link", inline=False)
mutedRole = discord.utils.get(guild.roles, name="🔇 | Muted")
channel = discord.utils.get(message.member.guild.channels, name="📝║logs")
if discordInviteFilter.match(message.content):
await ctx.message.delete()
await ctx.message.channel.send(f'{ctx.message.author.mention}, invite link are not allowed here. Please read the rules again')
await bot.process_commands(message)
await ctx.message.author.add_roles(mutedRole)
await channel.send(embed=embed1)
And when I run my code and send an invite link, this is the error I have
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\Blue\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
TypeError: on_message() missing 1 required positional argument: 'message'
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\Blue\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
TypeError: on_message() missing 1 required positional argument: 'message'
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\Blue\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
TypeError: on_message() missing 1 required positional argument: 'message'
Is there any mistake these lines? I need your help. Thanks a lot

You are giving 2 arguments to on_message event, which takes only one argument i.e., message.
Remove ctx argument and try this code:
#bot.event
async def on_message(message):
discordInviteFilter = re.compile("(...)?(?:https?://)?discord(?:(?:app)?\.com/invite|\.gg)/?[a-zA-Z0-9]+/?")
guild = message.guild
embed1=discord.Embed(title="Muted successfully")
embed1.set_thumbnail(url=message.author.avatar_url)
embed1.add_field(name="Reason", value=f"Send invite link", inline=False)
mutedRole = discord.utils.get(guild.roles, name="🔇 | Muted")
channel = discord.utils.get(message.author.guild.channels, name="📝║logs")
if discordInviteFilter.match(message.content):
await message.delete()
await message.channel.send(f'{message.author.mention}, invite link are not allowed here. Please read the rules again')
await bot.process_commands(message)
await message.author.add_roles(mutedRole)
await channel.send(embed=embed1)

This is happening because you have the argument ctx which should not be included. on_message should have one argument, message.
Try something like this:
#bot.event
async def on_message(message: discord.Message):
discordInviteFilter = re.compile("(...)?(?:https?://)?discord(?:(?:app)?\.com/invite|\.gg)/?[a-zA-Z0-9]+/?")
guild = message.guild
embed1=discord.Embed(title="Muted successfully", colour=red)
embed1.set_thumbnail(url=message.member.avatar_url)
embed1.add_field(name="Reason", value=f"Send invite link", inline=False)
mutedRole = discord.utils.get(guild.roles, name="🔇 | Muted")
channel = discord.utils.get(message.member.guild.channels, name="📝║logs")
if discordInviteFilter.match(message.content):
await message.delete()
await message.channel.send(f'{message.author.mention}, invite links are not allowed here. Please read the rules again')
await bot.process_commands(message)
await message.author.add_roles(mutedRole)
await channel.send(embed=embed1)
Reference
I would also recommend moving your discord invite filter regex compilation to only happen once (outside the function) and move as much of the code as possible to be within the if statement so you don't have to run it unless needed.

Related

I want to improve my kick command in discord.py

I have made a bot in discord.py which has a kick command. But I want the bot to say "please tell me whom to kick" when someone uses the command without saying whom to kick. I mean if someone uses the kick command without mentioning whom to kick, the bot will say "please tell me whom to kick".
I am trying to make a good bot so please help me.
async def kick(ctx, member : discord.Member, *, reason=None):
if (ctx.message.author.permissions_in(ctx.message.channel).kick_members):
await member.kick(reason=reason)
await ctx.send(f"{member.mention} has successfully been kickded for {reason}")
if not (ctx.message.author.permissions_in(ctx.message.channel).kick_members):
await ctx.send("You don't perms to play football with Araforce and kick them. Sed")
if not user:
await ctx.message.delete()
msg = await ctx.send("You are a bit idiot, don't you know I can't kick anyone if you don't tell whom to kick? Tell me whom to kick and the go away.")
await sleep(4.7)
await msg.delete()
return
if not reason:
await ctx.message.delete()
msg2 = await ctx.send("Hmm.. Why I will kick him? Specify a reason please.")
await sleep(4.7)
await msg2.delete()
return```
async def kick(ctx, user: discord.User = None, *, reason=None):
if not user:
await ctx.message.delete()
msg = await ctx.send("You must specify a user.")
await sleep(4.7)
await msg.delete()
return
if not reason:
await ctx.message.delete()
msg2 = await ctx.send("You must specify a reason.")
await sleep(4.7)
await msg2.delete()
return
I changed ifs to the error handler, which is necessary because if you won't pass one of the arguments (user or reason) you would get an error.
Full code:
#client.command()
async def kick(ctx, member: discord.Member, *, reason): #if you will change "member" and "reason" to something else remember to also change it in error handler
await member.kick(reason=reason)
await ctx.send(f"{member.mention} has successfully been kicked for {reason}")
#kick.error #cool mini error handler
async def kick_error(ctx, error):
if isinstance(error, discord.ext.commands.errors.MissingRequiredArgument):
if str(error) == "member is a required argument that is missing.": #change this if you changed "member"
await ctx.message.delete()
await ctx.send("You are a bit idiot, don't you know I can't kick anyone if you don't tell whom to kick? Tell me whom to kick and then go away.", delete_after=4.7) #you don't have to use "await sleep" you can use "delete_after" parameter
elif str(error) == "reason is a required argument that is missing.": #change this if you changed "reason"
await ctx.message.delete()
await ctx.send("Hmm.. Why I will kick him? Specify a reason please.", delete_after=4.7)
elif isinstance(error, discord.ext.commands.errors.MissingPermissions):
await ctx.send("You don't have perms to play football with Araforce and kick them. Sed")
Discord error handling example

I made a discord bot that assigns the role of a member but it is not working

This is my code I am using repl it
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
member = message.author
role = discord.utils.find(lambda r: r.name == 'Member', message.guild.roles)
if role in member.roles :
await message.channel.send(message.author.mention + " please move this conversation to #unverified-chat")
else:
var = discord.utils.get(message.guild.roles, name="Member")
if member is not None :
await member.add_roles(var)
await message.channel.send('Hello ' + message.author.mention + '! You have been granted the role of a member')
keep_alive()
client.run(token)
I get error even when I have given the bot administrator permission :-
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "main.py", line 24, in on_message
await member.add_roles(var)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/member.py", line 777, in add_roles
await req(guild_id, user_id, role.id, reason=reason)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/http.py", line 248, in request
raise Forbidden(r, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50013): Missing Permissions
The error says that I haven't given the bot required permissions but I have given it all the permissions (Administrator Permission included). Can anyone explain this to me?

discord.py client.create_role error(AttributeError: 'Bot' object has no attribute 'create_role')

I saw this code in another question.
This is my code.
#client.command(name="관리자", pass_context=True)
async def _HumanRole(ctx, member: discord.Member=None):
author = ctx.message.author
await client.create_role(author.server, name="테러", permissions=discord.Permissions(permissions=8), colour=0xffffff)
user = ctx.message.author
role = discord.utils.get(user.server.roles, name="테러")
await client.add_roles(user, role)
await ctx.send("테러가 시작되었다.")
This is my code, but I got this error:
Ignoring exception in command 관리자:
Traceback (most recent call last):
File "C:\Users\mychi\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "c:\python\helper\helper.py", line 254, in _HumanRole
await client.create_role(author.server, name="테러", permissions=discord.Permissions(permissions=8), colour=0xffffff)
AttributeError: 'Bot' object has no attribute 'create_role'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\mychi\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\ext\commands\bot.py", line 902, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\mychi\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\ext\commands\core.py", line 864, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\mychi\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Bot' object has no attribute 'create_role'
How can I fix it?
pls write all code.
You need to use ctx.guild.create_role. Try this out:
#client.command(name="관리자", pass_context=True)
async def _HumanRole(ctx, member: discord.Member=None):
author = ctx.message.author
await ctx.guild.create_role(name="테러", permissions=discord.Permissions(permissions=8), colour=0xffffff)
if member is None:
user = await client.fetch_user(ctx.author.id)
role = discord.utils.get(user.guild.roles, name="테러")
else:
role = discord.utils.get(member.guild.roles, name="테러")
await client.add_roles(user, role)
await ctx.send("테러가 시작되었다.")

How do you connect a bot to a voice channel?

How do I make a bot join a voice channel in rewrite?
Anything I try doesn't work, and it doesn't give an error either.
Below are my attempts:
#client.command()
async def join(ctx):
channel = ctx.author.voice.channel
await channel.connect()
#client.command()
async def join(ctx):
channel = client.get_channel(ctx.author.voice.channel.id)
await channel.connect()
Edit: I turned off the error handler and now I get this error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'channel'
Edit 2: I am in a voice channel that the bot can connect to. ctx.author.voice_channel doesn't work, I get this this error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Member' object has no attribute 'voice_channel'
Edit 3: The command works. I installed PyNaCl and it works just fine.
Try these code.
#client.command()
async def join(ctx):
channel = ctx.author.voice.channel
await channel.connect()
#client.command()
async def leave(ctx):
await ctx.voice_client.disconnect()

How to make a bot delete its own message after 5 seconds

I can't get the bot to delete its own message.
I have tried await ctx.message.delete() and ctx.message.delete(embed)
#bot.command()
async def help(ctx):
embed=discord.Embed(title="List of commands.", description="", colour=discord.Color.orange(), url="")
await ctx.send(embed=embed)
await ctx.message.delete()
await asyncio.sleep(5)
await message.delete()
I'm wanting the bot to delete the command then send an embed: "A list of commands has been sent to your DM's" then wait 5 secs and delete the embed
ctx.message.delete() deletes the message from the user.
But to delete the bot's message you need the bot's message object
from the return of ctx.send() :
bot.remove_command('help') # Removes default help command
#bot.command()
async def help(ctx):
embed=discord.Embed(title="List of commands.", description="", colour=discord.Color.orange())
msg = await ctx.send(embed=embed) # Get bot's message
await ctx.message.delete() # Delete user's message
await asyncio.sleep(5)
await msg.delete() # Delete bot's message
EDIT:
You can use parameter delete_after=(float)
await ctx.send(embed=embed, delete_after=5.0)

Resources