When the check_achievement function is called, I get the error AttributeError: module 'discord.member' has no attribute 'mention'. How can I fix this?
async def check_achievement(discord_id: int, message_count: int):
if message_count >= 25:
existing_achievement = await connection.fetchval("SELECT COUNT(*) FROM achievements WHERE discord_id = $1 AND achievement_name = 'Test'", discord_id)
if existing_achievement == 0:
await connection.execute("INSERT INTO achievements (discord_id, achievement_name) VALUES ($1, 'test')", discord_id)
print(f"User with ID {discord_id} has earned the 'test' achievement!")
channel = bot.get_channel(1034698950369874010)
await channel.send(f"{member.mention}, test message")
Related
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")
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\")
#voice.command()
#commands.has_permissions(administrator=True)
async def setup(self, ctx, member: discord.Member = None ):
conn = sqlite3.connect('voice.db')
c = conn.cursor()
guildID = ctx.guild.id
id = ctx.author.id
if ctx.author.id == ctx.guild.owner.id or ctx.author.id == 189887758192476162:
def check(m):
return m.author.id == ctx.author.id
await ctx.channel.send("**You have 60 seconds to answer each question!**")
await ctx.channel.send(f"**Enter the name of the category you wish to create the channels in:(e.g Voice Channels)**")
try:
category = await self.bot.wait_for('message', check=check, timeout = 60.0)
except asyncio.TimeoutError:
await ctx.channel.send('Took too long to answer!')
else:
new_cat = await ctx.guild.create_category_channel(category.content)
await ctx.channel.send('**Enter the name of the voice channel: (e.g Join To Create)**')
try:
channel = await self.bot.wait_for('message', check=check, timeout = 60.0)
except asyncio.TimeoutError:
await ctx.channel.send('Took too long to answer!')
else:
try:
channel = await ctx.guild.create_voice_channel(channel.content, category=new_cat)
c.execute("SELECT * FROM guild WHERE guildID = ? AND ownerID=?", (guildID, id))
voice=c.fetchone()
if voice is None:
c.execute ("INSERT INTO guild VALUES (?, ?, ?, ?)",(guildID,id,channel.id,new_cat.id))
else:
c.execute ("UPDATE guild SET guildID = ?, ownerID = ?, voiceChannelID = ?, voiceCategoryID = ? WHERE guildID = ?",(guildID,id,channel.id,new_cat.id, guildID))
await ctx.channel.send("**You are all setup and ready to go!**")
except:
await ctx.channel.send("You didn't enter the names properly.\nUse `.voice setup` again!")
else:
await ctx.channel.send(f"{ctx.author.mention} only the owner of the server can setup the bot!")
conn.commit()
conn.close()
Spacing is all correct. It give me the error stated in the title and does not tell me what line the error is on. If anyone could offer some feedback that would be amazing. I just don't know what "id" it could be talking about.
I'm pretty sure it's the ctx.guild.owner.id, in which case is not a proper way to retrieve the guild owner
If you want to find the guild's owner id you should enable intents and use ctx.guild.owner_id from here
#client.command(aliases=["lb"])
async def leaderboardie(ctx, x=1):
users = await get_bank_data()
leader_board = {}
total = []
for user in users:
name = int(user)
total_amount = users[user]["wallet"] + users[user]["bank"]
leader_board[total_amount] = name
total.append(total_amount)
total = sorted(total, reverse=True)
em = discord.Embed(title=f"Top {x} Richest People",
description="This is decided on the basis of raw money in the bank and wallet", color=discord.Color(0xfa43ee))
index = 1
for amt in total:
id_ = leader_board[amt]
member = client.get_user(id_)
name = member.name
em.add_field(name=f"{index}. {name}", value=f"{amt}", inline=False)
if index == x:
break
else:
index += 1
await ctx.send(embed=em)
Error i keep getting:
Command raised an exception: AttributeError: 'NoneType' object has no attribute 'name'
It's basically about a leaderboard based on users wallets, but every time i get this error for some reason, if you know the solution tell me.
If you are doing client.get_user(_id), you need to turn on the server members gateway intent in the developer portal. If you do not want to turn on this intent, you can use:
await client.fetch_user(id)
guys so I'm working on a Filter that removes swear words. My problem is I'm getting a 'NoneType' object is not subscriptable error. Could anyone explain why and how to fix it? I know that is error is costed by getMutedValue = curs.fetchone()[0] but if I would remove the [0] its wouldn't work.
#client.event
async def on_message(message):
curs.execute('SELECT muted FROM user WHERE userID = (%s)', (message.author.id,))
getMutedValue = curs.fetchone()[0]
curs.execute('SELECT word FROM filter')
getWord = curs.fetchone()
curs.execute('SELECT immunity FROM user WHERE userID = (%s)', (message.author.id,))
getImmunityValue = curs.fetchone()[0]
if getMutedValue == 1:
muted = message.author.mention + ' You are currently muted!'
await message.channel.send(muted)
await message.delete()
if getImmunityValue == 0:
for word in getWord:
if getMutedValue == 0:
if message.content.count(word) > 0:
channel = client.get_channel(729267888539828255)
id = message.author.id
curs.execute('SELECT username FROM user WHERE userID = (%s)', (id,))
getUsername = curs.fetchone()[0]
curs.execute(f'UPDATE user SET warning = +1 WHERE userID = {id}')
db.commit()
curs.execute('SELECT warning FROM user WHERE userID = (%s)', (id,))
getWarning = curs.fetchone()[0]
await message.delete()
await message.channel.send(f'{message.author.mention} Please do not use an swear words. If you continue you will get punished!')
Embed = discord.Embed(
title=f'{getWarning}x Warning from {getUsername}',
color=discord.Colour.red(),
timestamp=datetime.utcnow()
)
Embed.add_field(name='Blacklist Wort:', value=word, inline=False)
Embed.add_field(name='Channel-ID:', value=message.channel.id, inline=False)
Embed.add_field(name='Channel:', value=message.channel, inline=False)
await channel.send(embed=Embed)
await client.process_commands(message)
The fetchone() method can return None if there are no rows to fetch. (Documentation.) What the should the program do next? In the case where you're checking if a user is muted, the most sensible thing is probably to assume that they aren't muted.
For example:
row = curs.fetchone()
if row is not None:
getMutedValue = row[0]
else:
getMutedValue = 0
In the case where you get None back, you have a fallback value, 0. If you get a value back, then you use that value.
I was creating a discord bot, and when I used a command(!buy #Role), it crashed with:
cursor.execute("UPDATE users SET cash = cash - {} WHERE id = {}".format(("SELECT cost FROM shop WHERE role_id = {}".format(role.id)).fetchone()[0], ctx.author.id))
AttributeError: 'str' object has no attribute 'fetchone'
I don't understand what's up, because role id is integer! Here code is:
import discord
from discord.ext import commands
import sqlite3
client = commands.Bot(command_prefix='!')
client.remove_command('help')
connection = sqlite3.connect('server.db')
cursor = connection.cursor()
#client.event
async def on_ready():
cursor.execute("""CREATE TABLE IF NOT EXISTS shop (
role_id INT,
id INT,
cost BIGINT
)""")
#client.command(aliases = ['buy', 'buy-role'])
async def __buy(ctx, role: discord.Role = None):
if role is None:
await ctx.send(f"**{ctx.author}**, choose a role, which you want to buy!")
else:
if role in ctx.author.roles:
await ctx.send(f"**{ctx.author}**, you already have this role!")
elif cursor.execute("SELECT cost FROM shop WHERE role_id = {}".format(role.id)).fetchone()[0] > cursor.execute("SELECT cash FROM users WHERE id = {}".format(ctx.author.id)).fetchone()[0]:
await ctx.send(f'**{ctx.author}**, not enough money!')
else:
await ctx.author.add_roles(role)
cursor.execute("UPDATE users SET cash = cash - {} WHERE id = {}".format(("SELECT cost FROM shop WHERE role_id = {}".format(role.id)).fetchone()[0], ctx.author.id))
connection.commit()
await ctx.message.add_reaction('✅')
client.run('MY TOKEN')
PLEASE HELP!
Try to use
cursor.execute("UPDATE users SET cash = %s WHERE id = %s", [value1, value2])
and you can create a variable for the coins in the database and then subtract the price.