py recently and I would like the bot to send random messages mentioning the user but it gives me this error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'mention'
Here is the code:
#client.command()
async def randomroman(ctx, *,member: discord.Member=None):
mention = member.mention
variable=[
f'{mention} ama tanto roman!',
f'{mention} odia tanto roman!',
f'{mention} ama roman!',
f'{mention} odia roman!'
]
await ctx.message.channel.send(random.choice(variable))
So it would appear that you have set a default value, therefore you should check if a member has been mentioned before trying to send a message. Here are two different pieces of code that you could use.
#client.command()
async def randomroman(ctx, member: discord.Member=None):
if not member:
# We dont have anyone to mention so tell the user
await ctx.send("You need to mention someone for me to mention!")
return
variable=[
f'{member.mention} ama tanto roman!',
f'{member.mention} odia tanto roman!',
f'{member.mention} ama roman!',
f'{member.mention} odia roman!'
]
await ctx.send(random.choice(variable))
You can also simply use ctx.send()
Another thing you could do is have it mention the author if they dont call the command to mention anyone, like so
#client.command()
async def randomroman(ctx, member: discord.Member=None):
member = member or ctx.author
variable=[
f'{member.mention} ama tanto roman!',
f'{member.mention} odia tanto roman!',
f'{member.mention} ama roman!',
f'{member.mention} odia roman!'
]
await ctx.send(random.choice(variable))
In this situation, both of these will work. !randomroman and !randomroman #user will mention a user.
Hope this helps!
Related
I'm trying to create a code that takes a users id, then checks if it matches with one, if it does it sends a message...I keep getting the error TypeError: on_message() missing 1 required positional argument: 'message'...
#client.event
async def on_message(ctx,message):
member = message.author.id
if member == <userid>:
await ctx.send("yo whats up")
else:
return
await client.process_commands(message)
You're not defining your function the way it should be. on_message event only takes in one argument: message. You will have to work without the ctx argument in on_message events. By taking that into consideration, you can re-format your current function code from:
#client.event
async def on_message(ctx,message):
member = message.author.id
if member == <userid>:
await ctx.send("yo whats up")
else:
return
await client.process_commands(message)
to:
#client.event
# Only pass in "message" argument
async def on_message(message):
member = message.author.id
if member == <userid>:
# Use message.channel.send() instead of ctx.send()
await message.channel.send("yo whats up")
else:
return
await client.process_commands(message)
I'm making an Administration cog for my discord bot and my code wouldn't identify 'ctx'. PyCharm suggested to replace 'ctx' with 'self' and I have no idea what 'self' does. And from what PyCharm is saying, There are millions of other stuff which I have to write down what it is. PyCharm couldn't identify guild, send, author and channel and it also says that return ctx.author.guild_permissions.manage_messages is an unreachable code. As a note if this seems to be a really stupid question, I am a beginner who started 2 weeks ago.
As for the code:
class Administration(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_ready(self):
print("Admin cog ready")
async def cog_check(self, ctx):
admin = get(ctx.guild.roles, name="Admin")
return admin in ctx.author.roles
return ctx.author.guild_permissions.manage_messages
#commands.command(aliases=["purge"])
async def clear(ctx, amount=3):
"""Clears 3 messages"""
await ctx.channel.purge(limit=amount)
#commands.command(pass_context=True)
async def giverole(ctx, user: discord.Member, role: discord.Role):
"""Gives a role to a user"""
await user.add_roles(role)
await ctx.send(f"hey {ctx.author.name}, {user.name} has been giving a role called: {role.name}")
#commands.command(aliases=['make_role'])
#commands.has_permissions(manage_roles=True)
async def create_role(ctx, *, name):
"""Creates a role"""
guild = ctx.guild
await guild.create_role(name=name)
await ctx.send(f'Role `{name}` has been created')
#commands.command(name="slap", aliases=["warn"])
async def slap(ctx, members: commands.Greedy[discord.Member], *, reason='no reason'):
"""Warns someone"""
slapped = ", ".join(x.name for x in members)
await ctx.send('{} just got slapped for {}'.format(slapped, reason))
def setup(client):
client.add_cog(Administration(client))
In classes, (unless it's a staticmethod or classmethod) you always pass self as the first argument.
#commands.command(aliases=["purge"])
async def clear(self, ctx, amount=3): # Note how I put `self` as the first arg, do the same in all commands in the cog
"""Clears 3 messages"""
await ctx.channel.purge(limit=amount)
Also, this will never work
async def cog_check(self, ctx):
admin = get(ctx.guild.roles, name="Admin")
return admin in ctx.author.roles
return ctx.author.guild_permissions.manage_messages
The function will end no matter what when it reaches the first return, you can simply use the AND or OR logical operator if you want to also evaluate the second return statement
async def cog_check(self, ctx):
admin = get(ctx.guild.roles, name="Admin")
return admin in ctx.author.roles and/or ctx.author.guild_permissions.manage_messages
I want to make a mute command or any command that takes either a mention of a user id. both will work.
I really only need help with this part:
async def mute(ctx, member : discord.Member, *, reason=None):
so i can do /mute id or /mute #Member and both will work
all you have to do is :
#client.command(aliases=["m", "M", "Mute"]) #new one to karim
#commands.has_permissions(administrator=True)
async def mute(ctx, *, member: discord.Member):
command_name = "mute"
author = ctx.author
await member.edit(mute=True)
await ctx.send(f"{member.mention} is muted")
await ctx.message.add_reaction('✅')
and the unmute command :
#client.command(aliases=["unm", "UNM", "Unmute"]) #new one to karim
#commands.has_permissions(administrator=True)
async def unmute(ctx, *, member: discord.Member):
command_name = "unmute"
author = ctx.author
await member.edit(mute=False)
await ctx.send(f"{member.mention} is unmuted")
await ctx.message.add_reaction('✅')
I got it to work!
async def mute(ctx, member : discord.Member):
That piece of code was working I needed to turn intents on and turn on user tracking in the discord developer portal.
I don't know where to start like most things, but for example.
A user says "foo", the bot stores the message, and then says "bar". The closest I could get was this:
message = await channel.send('hmm…')
message_id = message.id
Though this stores the message sent by the bot, and not the user which triggered the function. It also doesn't store the message, just the ID. Please help.
Thanks in advance!
Edit: My goal is kinda like Sx4's suggest feature.
Hi :) not sure exactly what you want but seems like you are looking for the on message event? Here is an example. You should replace client with whatever you named your bot instance.
#client.event
async def on_message(message):
if message.author != client.user: # Avoids loops by checking that the message author is not the bot itself
# Code in here will run when a message is sent
await client.process_commands(message) # Runs all commands contained in the message
If you want to store every message, use something like this to set a variable that you can then do something with:
#client.event
async def on_message(message):
if message.author != client.user:
STORED_MESSAGE = message.content
# Do something with the variable here
await client.process_commands(message)
Or to respond to a message "foo" with "bar":
#client.event
async def on_message(message):
if message.author != client.user:
if message.content == "foo":
await message.channel.send("bar")
await client.process_commands(message)
I want to check if the user has given two arguments, the first being a user to ban (mentioned) and a reason.
If a user is not mentioned, it will show a message saying "You must mention a user you'd like to ban" and if a reason isn't given, it will ban the user with the message "No Reason Given".
I'd also like to make it so you can't ban yourself, if not already implemented by discord.py
I've tried using an if args == None: statement, but it doesn't work.
#commands.has_permissions(ban_members=True)
#client.command()
async def ban(ctx, member: discord.Member, *, arg):
embed = discord.Embed(title="Punishments", color=0x3b55e8)
embed.add_field(name=f"{member} has been banned for:", value=arg)
embed.set_footer(text=strftime("%Y-%m-%d %H:%M:%S", gmtime()))
await ctx.send(embed=embed)
await member.ban()
#ban.error
async def ban_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
embed = discord.Embed(title="Error", color=0x3b55e8)
embed.add_field(name="You do not have permission to use this command", value="If you think this is incorrect, please contact a server administrator")
embed.set_footer(text=strftime("%Y-%m-%d %H:%M:%S", gmtime()))
await ctx.send(embed=embed)
print(f"{ctx.author} has attempted to ban a player, but does not have the correct permissions")
I don't receive any errors.
You can set a default value for your reason, and add an error handler to handle the failure when a required argument is not passed:
#commands.has_permissions(ban_members=True)
#client.command()
async def ban(ctx, member: discord.Member, *, arg="No Reason Given"):
embed = discord.Embed(title="Punishments", color=0x3b55e8)
embed.add_field(name=f"{member} has been banned for:", value=arg)
embed.set_footer(text=strftime("%Y-%m-%d %H:%M:%S", gmtime()))
await ctx.send(embed=embed)
await member.ban()
#ban.error
async def ban_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
embed = discord.Embed(title="Error", color=0x3b55e8)
embed.add_field(name="You do not have permission to use this command", value="If you think this is incorrect, please contact a server administrator")
embed.set_footer(text=strftime("%Y-%m-%d %H:%M:%S", gmtime()))
await ctx.send(embed=embed)
print(f"{ctx.author} has attempted to ban a player, but does not have the correct permissions")
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send("You must mention a user you'd like to ban")
else:
raise error
Patrick Haugh has already answered the question but best you create an error.py and insert all the global errors there.
Link to the documentation (CommandErrors)
This can look like this:
import discord
from discord.ext import commands
class Error(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_command_error(self, ctx, error):
if isinstance(error, commands.CheckFailure):
await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f"You don't have the permission to execute this bot command!"))
if isinstance(error, commands.CommandNotFound):
await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f"The bot command doesn't exist!"))
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f"The command is incomplete, missing one or more parameters!"))
if isinstance(error, commands.BadArgument):
await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f"The command was entered incorrectly, one or more parameters are wrong or in the wrong place!"))
def setup(bot):
bot.add_cog(Error(bot))