user.status always returns "offline" - discord.py

I know that user.status should be used to return the user status. But it always returns the status of offline, regardless of the fact that I or other participants change the status.
Code:
#app_commands.command(name='user', description=f'Детальна інформація про користувача')
async def user_(self, interaction: discord.Interaction, user: discord.Member = None):
ctx = await self.bot.get_context(interaction)# Don't pay attention to it
if user is None:
user = ctx.author
print(user.status)
global user_status
user_status = None
if user.status == discord.Status.online:
user_status = "<:online:1038376483758030898>В мережі"
elif user.status == discord.Status.offline or user.status == discord.Status.invisible:
user_status = "<:ofline:1038376481774120970>Не в мережі"
elif user.status == discord.Status.idle:
user_status = "<:idle:1038376474958381056>Відійшов"
elif user.status == discord.Status.dnd or user.status == discord.Status.do_not_disturb:
user_status = "<:dnds:1048347246556626954>Не турбувати"
await interaction.response.send_message(embed=embed, ephemeral=True)
In another command (not a slash command), this status check is working properly. Intentions I have set up that
bot = commands.Bot(commands.when_mentioned_or('.'), intents = discord.Intents.all()).
And in the portal of the developers, too, seems to be right

It seems to be a bug that it shows up as offline everytime, but here's something you can do:
userstatus = interaction.guild.get_member(user.id).status
if userstatus == discord.Status.online:
user_status = "<:online:1038376483758030898>В мережі"
#rest of your checks here
ps: You don't need or user.status == discord.Status.do_not_disturb and or user.status == discord.Status.invisible because they mean the same thing as discord.Status.offline and discord.Status.dnd respectively.

Related

Discord.py, member.status isn't working as it should

#bot.tree.command(name="user", description="Shows some informations about the mentioned user.")
async def user(interaction: discord.Interaction, member:discord.Member=None):
if member == None:
member = interaction.user
roles = [role for role in member.roles if role.name != "#everyone"]
embed = discord.Embed(title=f"Details about the user, {member.name}",color=0xdaddd8, timestamp = datetime.datetime.utcnow())
embed.set_thumbnail(url=member.avatar) # Avatar Thumbnail
embed.add_field(name="👤 Name", value = f"{member.name}#{member.discriminator}") # Embeds
embed.add_field(name="🏷️ Nickname", value = member.display_name)
embed.add_field(name="🆔 User ID", value = member.id)
embed.add_field(name="📆 Created at", value = member.created_at.strftime("%D \n%I:%M %p"))
embed.add_field(name="👋🏻 Joined at", value = member.joined_at.strftime("%D \n%I:%M %p"))
embed.add_field(name="🟢 Status", value = member.status) #this line is'nt working as it should
embed.add_field(name="❤️‍🔥 Top role", value = member.top_role.mention)
bot_status = "Yes, it is" if member.bot else "No, They'snt"
embed.add_field(name="🤖 Bot?", value = bot_status)
embed.set_footer(text = interaction.user.name,icon_url = interaction.user.avatar)
await interaction.response.send_message(embed=embed)
I made a User information command and this command shows every person offline even itself how can i fix it?
This is likely due to lack of intents.
Add in your code, under the intents you define:
intents.members = True
intents.presences = True
Use member.raw_status instead of member.status. It will return a string value such as 'online', 'offline' or 'idle'.

Problem in embed-reaction system. Discord.py

So I wrote this code that sends an embed and changes its value/item once the user reacts to certain emoji. It works fine for a single embed but when user asks for same multiple embeds like you see in the image, reaction to a embed changes value of other similar embeds too.
Code part
#client.command()
async def embed(ctx):
current = 1
embed = discord.Embed(title = f'{current}')
buttons = [ u"\u25C0", u"\u25FC" , u"\u25B6" , u"\U0001F5D1"]
msg = await ctx.send(embed = embed)
for button in buttons:
await msg.add_reaction(button)
while True:
try:
reaction , user = await client.wait_for("reaction_add", check = lambda reaction,user: user == ctx.author and reaction.emoji in buttons, timeout = 180.0)
except asyncio.TimeoutError:
embed.set_footer(text= "Timeout.")
await msg.clear_reactions()
else:
previous_page = current
if reaction.emoji == u"\u25C0":
current -= 1
embed.add_field(name = None, value = f'{current}')
elif reaction.emoji == u"\u25FC":
if current > 0:
current = 0
embed.add_field(name = None, value = f'{current}')
elif reaction.emoji == u"\u25B6":
current += 1
embed.add_field(name = None, value = f'{current}')
elif reaction.emoji == u"\U0001F5D1":
await msg.edit(embed = embed)
await msg.clear_reactions()
for button in buttons:
await msg.remove_reaction(button, ctx.author)
if current != previous_page:
embed.add_field(name = None, value = f'{current}')
await msg.edit(embed = embed)
Images: https://imgur.com/a/fEpz9jD
NOTE: The code I've used in my bot is exactly same as this one. I haven't included that and screenshots of those embeds because it is being used for NSFW purposes/images.
Thanks.
This may be happening because of your check function (line 13)
check = lambda reaction,user: user == ctx.author and reaction.emoji in buttons
Here you are checking that the emoji are matching, and the user reacting is the same user that executed the command. But you don't check which message the reaction was added to. To solve this, you could check for the message id, by checking if reaction.message.id == ctx.message.id what results in :
check = lambda reaction,user: user == ctx.author and reaction.emoji in buttons and reaction.message.id == msg.id

Bot Exclusion discord.py

How can I make my Bot Exclude someone from the usage if a user's abusing it (like spamming commands and stuff)
#client.command(pass_context = True, aliases = ['bban'])
#commands.is_owner()
async def botban(ctx, member: discord.Member = None, banreason='Kein Grund angegeben!'):
if member is None:
em = discord.Embed(color = 0xff2200, title = "Argumente Fehlen!",
description = f"{ctx.author.mention} Bitte nenne den User, den du vom Bot ausschließen willst\n\n```py\no?botban [#nutzer / id] [(optional) Grund]\n```\n Optional: ```py\no?bban [#nutzer / id] [(optional) Grund]\n```",
footer = f'User-ID: ' + str(ctx.author.id) + ' Made by Ohnezahn DNC#8135 with discord.py')
em.set_author(name = f'{ctx.author.name}#{ctx.author.discriminator}',
icon_url = f'{ctx.message.author.avatar_url}')
return await ctx.send(embed = em)
elif message.author.id in 'blacklist.json': # Check if user already banned
return await ctx.send(
f"Der Nutzer {member.id} / {member.name} - {member.discriminator} ist bereits ausgeschlossen! Grund:\n\n{banreason}")
elif member.id not in 'ban.json':
with open('ban.json', 'w') as fp:
json.dump(banlist, fp)
emb = discord.Embed(color = 0xff2200, title = "Bot Ban ausgeführt",
description = f'{member.mention} / {member.name}#{member.discriminator} / {member.id} wurde von {ctx.author.name}#{ctx.author.discriminator} / {ctx.author.id} / {ctx.author.mention} vom Bot ausgeschlossen\n\nGrund: {banreason}',
footer = f'User-ID: ' + str(member.id) + '/ Made by Ohnezahn DNC#8135 with discord.py')
emb.set_author(name = f'{ctx.author.name}#{ctx.author.discriminator}',
icon_url = f'{ctx.message.author.avatar_url}')
return await ctx.send(embed = emb)
else:
# Add ban to dict
banlist[member.id] = banreason
# Update File
with open('ban.json', 'w') as fp:
json.dump(banlist, fp)
emb = discord.Embed(color = 0xff2200, title = "Bot Ban ausgeführt",
description = f'{member.mention} / {member.name}#{member.discriminator} / {member.id} wurde von {ctx.author.name}#{ctx.author.discriminator} / {ctx.author.id} / {ctx.author.mention} vom Bot ausgeschlossen\n\nGrund: {banreason}',
footer = f'User-ID: ' + str(member.id) + '/ Made by Ohnezahn DNC#8135 with discord.py')
emb.set_author(name = f'{ctx.author.name}#{ctx.author.discriminator}',
icon_url = f'{ctx.message.author.avatar_url}')
return await ctx.send(embed = emb)
#client.check
def check_commands(ctx):
# Check if user banned, convert id to str because json.load (line 9) load str id's.
return str(ctx.author.id) not in blacklisted_users()
That's how my ban.json looks like at the moment:
{
"blacklistedUsers": [
]
}
that's the codes I have right now... I'm working on this for felt ages right now...
Hello welcome to Stack overflow, There are something in commands called checks. You could add an array the check can see if the user is in that array. If it is don't let them run the command by stopping the command using return
Welcome!
You can do similar thing:
import discord, json
from discord.ext import commands
intents = discord.Intents.default()
bot = commands.Bot(command_prefix='?', intents=intents)
# Load banned data from json
with open('ban.json') as json_file:
bot.banneds = json.load(json_file)
#bot.event
async def on_ready():
print(f'Logged in as {bot.user} (ID: {bot.user.id})')
print('------')
#bot.command()
async def test(ctx): # Only random command for test
await ctx.send("Test okay!")
#bot.command()
#commands.is_owner()
async def ban(ctx, member: discord.Member = None, banreason = 'Empty Reason'):
if member.id in bot.banneds: # Check if user already banned
await ctx.send("Already banned.")
return
else:
# Add ban to dict
bot.banneds[member.id] = banreason
# Update File
with open('ban.json', 'w') as fp:
json.dump(bot.banneds, fp)
await ctx.send(f"{member} has been banned, because {banreason}!")
# Ban Check (Global)
#bot.check
def check_commands(ctx):
# Check if user banned, convert id to str because json.load (line 9) load str id's.
return str(ctx.author.id) not in bot.banneds
bot.run('key')
Create a ban.json at the first time with empty object
{}
Note that if user banned try use commands, you receive error "discord.ext.commands.errors.CheckFailure: The global check functions for command test failed.", add this to your error handler.

Getting input from reactions not working discord.py

I wanted to make a rock paper scissor game for my bot:
The bot creates an embed with instructions and reacts with a "rock", "paper", and "scissor" emoji, which the user has to click to input his/her choice.
But the problem is that the code doesn't go any further and shows an error.
Here is the code:
#client.command(aliases = ["rock_paper_scissors","rps"])
async def _rps(ctx): #rps is short for rock, paper, scissor
emojis = ['✊', '🖐️', '✌️']
embedVar = discord.Embed(title="CHOOSE YOUR WEAPON!",description = "Choose between rock, paper, or scissors, {}." . format(ctx.author.mention), color = 0xff9900)
embedVar.add_field(name=":fist: ROCK", value="React with :fist: emoji to choose rock.", inline = False)
embedVar.add_field(name=":hand_splayed: PAPER", value="React with :hand_splayed: emoji to choose paper.", inline = False)
embedVar.add_field(name=":v: SCISSORS", value="React with :v: emoji to choose scissors.", inline = False)
emb = await ctx.send(embed = embedVar)
for emoji in emojis:
await emb.add_reaction(emoji)
def chk(reaction):
return reaction.emb == emb and reaction.channel == ctx.channel
react = await client.wait_for('reaction_add', check=chk)
if react == '✊':
await ctx.send("You chose rock!")
elif react == '🖐️':
await ctx.send("You chose paper!")
elif react == '✌️':
await ctx.send("You chose scissors!")
I am getting this error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: chk() takes 1 positional argument but 2 were given
I tried many fixes but in vain.
Also, I want the bot to accept the input only from the user who had asked for the rock paper scissor game by the command in the first place (the author of the message, in other words), But I am not sure how to implement that, I tried, but it did not work.
How can I fix this?
reaction_add gives a tuple of a reaction and a user so in the chk function you need to have both the reaction and user. You should also use and user == ctx.author within the chk function to ensure the user is the same.
#client.command(aliases = ["rock_paper_scissors","rps"])
async def _rps(ctx): #rps is short for rock, paper, scissor
emojis = ['✊', '🖐️', '✌️']
embedVar = discord.Embed(title="CHOOSE YOUR WEAPON!",description = "Choose between rock, paper, or scissors, {}." . format(ctx.author.mention), color = 0xff9900)
embedVar.add_field(name=":fist: ROCK", value="React with :fist: emoji to choose rock.", inline = False)
embedVar.add_field(name=":hand_splayed: PAPER", value="React with :hand_splayed: emoji to choose paper.", inline = False)
embedVar.add_field(name=":v: SCISSORS", value="React with :v: emoji to choose scissors.", inline = False)
emb = await ctx.send(embed = embedVar)
for emoji in emojis:
await emb.add_reaction(emoji)
def chk(reaction, user):
return reaction.emb == emb and reaction.channel == ctx.channel and user == ctx.author
react, user = await client.wait_for('reaction_add', check=chk)
if react == '✊':
await ctx.send("You chose rock!")
elif react == '🖐️':
await ctx.send("You chose paper!")
elif react == '✌️':
await ctx.send("You chose scissors!")

discord.py rewrite | Problem with getting author message

I've been making a number game command in my server, and someone recommended I add difficulties. So, I have 3 difficulties for the user to chose from.
I have already got a bit of code which got the author's response and worked, so I re-used it in my code, and now I am stumped. It may be glaringly obvious, but I cannot find it:
#client.command(name='numgame',
brief='Guess a number between 1 and 100',
pass_ctx=True)
async def numgame(ctx):
if ctx.author.id != 368442355382222849:
await ctx.send('Command currently disabled')
return
await ctx.send('Difficulties: a] 1-10 b] 1-50 c] 1-100')
msg = await client.wait_for('message', check=check(ctx.author), timeout=30)
diff = str(msg.content)
if diff == 'a':
max = 10
number = random.randint(1,10)
await ctx.send('You have 5 guesses')
await ctx.send('Pick a number between 1 and 10')
elif diff == 'b':
max = 50
number = random.randint(1,50)
await ctx.send('You have 5 guesses')
await ctx.send('Pick a number between 1 and 50')
elif diff == 'c':
max = 100
number = random.randint(1,100)
await ctx.send('You have 5 guesses')
await ctx.send('Pick a number between 1 and 100')
else:
ctx.send('Please try the command again...')
return
msg = None
This is the check I am using:
def check(author):
def inner_check(message):
# author check
if message.author != author:
return False
# inner check
try:
int(message.content)
return True
except ValueError:
return False
When I respond to the bot in-chat with "a", "b" or "c", I get no response.
I disabled the command for everyone but me whilst I tried to fix it, but I have no idea how to start.
I would appreciate an answer, as I don't see the solution myself, thanks!
[I didn't show the actual number game, because it is irrelevant and long]
Just create a new check function that does what you want.
def abc_check(author):
def inner_check(message):
return author == message.author and message.content in ('a', 'b', 'c')
return inner_check

Resources