My code runs perfectly but I want my bot to be able to warn members by either id or mention like if i want to warn i can either use id or mention.
Currently i can only warn members by mentioning. IF i use two variables then it will assign the value to wrong variable like if i give it id but the first variable is user_mention variable then it would assign it to that variable.
here is my code
with open('reports.json', encoding='utf-8') as f:
try:
report = json.load(f)
except ValueError:
report = {}
report['users'] = []
@client.command(pass_context = True)
@commands.has_permissions(kick_members=True)
async def warn(ctx,user:discord.User, *reason:str):
# await ctx.send(f"msg sender top role position {ctx.message.author.top_role.position} the other members top role position {user.top_role.position}")
guild = ctx.guild
member = ctx.guild.get_member(user.id)
member_top_role = member.top_role
member_top_role_position = member_top_role.position
requester = ctx.message.author
requester_id = ctx.guild.get_member(requester.id)
requester_top_role = requester_id.top_role
requester_top_role_position = requester_top_role.position
if requester_top_role_position > member_top_role_position:
if not reason:
await client.say("Please provide a reason")
return
reason = ' '.join(reason)
for current_user in report['users']:
if current_user['name'] == user.name:
current_user['reasons'].append(reason)
break
else:
report['users'].append({
'name':user.name,
'reasons': [reason,]
})
with open('reports.json','w ') as f:
json.dump(report,f)
await ctx.send(f"<:classic_check_mark:1055182126103937155> {user.mention} has been warned!")
await user.send(f"<:warning_icon:1055184901919494195> You have been warned from {guild.name}\n\n<:warning_icon:1055184901919494195> Resone: {reason}")
elif requester_top_role_position < member_top_role_position:
await ctx.send(f"<:failed:1055182259054985306> {user.mention} has higher role than you. You can't warn that member!")
@warn.error
async def warn_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
await ctx.send("<:failed:1055182259054985306> You don't have permission to use this command.")
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send("<:syntax:1055182220140232704> Incorrect argument | --warn <@person> <reason>")
@client.command(pass_context = True)
@commands.has_permissions(kick_members=True)
async def warnings(ctx,user:discord.User):
for current_user in report['users']:
if user.name == current_user['name']:
await ctx.send(f"{user.name} has been reported {len(current_user['reasons'])} times : {','.join(current_user['reasons'])}")
break
else:
await ctx.send(f"{user.name} has never been reported")
CodePudding user response:
you can modify the command functin to take a string as the user, and then use the discord.utils.get
function to try to convert the string to a User
object.
Try it like this
@client.command(pass_context = True)
@commands.has_permissions(kick_members=True)
async def warn(ctx, user: str, *reason: str):
# Try to convert the user String to a User object
member = discord.utils.get(ctx.guild.members, mention=user)
if not member:
# If the argument is not a mention, try to convert it to a user ID
try:
user_id = int(user)
member = ctx.guild.get_member(user_id)
except ValueError:
pass
if not member:
await ctx.send("Invalid user argument")
return
# Use the `name` attribute of the `Member` object instead of the `str` object
for current_user in report['users']:
if member.name == current_user['name']:
current_user['reasons'].append(reason)
break
else:
report['users'].append({
'name': member.name,
'reasons': [reason,]
})
with open('reports.json', 'w ') as f:
json.dump(report, f)
await ctx.send(f"<:classic_check_mark:1055182126103937155> {member.mention} has been warned!")
await member.send(f"<:warning_icon:1055184901919494195> You have been warned from {guild.name}\n\")