Wait for Message on_member_join using checks (discord.py) | SOLVED - discord

I want to wait for a private message that was sent only by the member. I am trying to use the check parameter for the client.wait_for() method but I can not seem to get it. I tried putting the check as the response.author but will not work since I just assigned response. Also I am executing this when a member joins using on_member_join which takes in a member argument (like this async def on_member_join(member). Anyone know how to properly do this? Any answers would be greatly appreciated!
Here is the code for this:
await member.send('What is your student number? ')
response = await client.wait_for('message')
student_number = response.content

When adding a check function to wait_for, that check function will get the received message as an argument. This means that it will check every single message the bot gets, pass all of them to your check function, and wait until one of them makes the check return True.
#client.event()
async def on_member_join(member):
def check(message):
return message.author.id == member.id and message.guild is None
await member.send('What is your student number?')
response = await client.wait_for('message', check=check)
student_number = response.content
Note how my example also makes sure the guild is None, as you explicitly mentioned waiting for a private message.

Related

I want to send a list of users who reacted to my message but the list always shows empty

I searched it up and saw someone do it like this but it always returns an empty list
#bot.command()
async def spinthewheel(ctx,msg:discord.Message=None):
guild=ctx.guild
if msg==None:
em=discord.Embed(title="SPIN THE WHEEL!!", description="React to this message with ⚡ to enter!",color=discord.Color.from_str('#ff00ff'))
msg=await ctx.send(embed=em)
await msg.add_reaction('⚡')
else:
await msg.add_reaction('⚡')
await ctx.send("Reaction has been added",delete_after=10)
await asyncio.sleep(5)
users = list()
for reaction in msg.reactions:
if reaction.emoji == '⚡':
async for user in reaction.users():
if user != bot.user:
users.append(user.name)
user_list="\n".join(user.name for user in users)
await ctx.send(f"users: {user_list}")
I tried using this one too but same results
users = [user async for user in reaction.users()]
Can you pls tell me how to fix this? Thanks <3
The issue is that msg.reactions is empty - this is because it's the message representation at the time it was created and hasn't been updated since with the reaction information. This is easily fixable with a:
msg = await msg.fetch()
This will fetch the message anew from the channel. Just put it after your asyncio.sleep and before you loop over the reactions.

How I can edit followUp message (discord.py)?

I have this code, however I don't understand how it is possible to edit the followup message. Thanks!
#bot.command()
async def button(ctx):
view=View()
button_create = Button(label="CREATE", style=discord.ButtonStyle.green)
view.add_item(button_create)
await ctx.send(view=view)
async def button_callback(interaction):
await interaction.response.defer()
await asyncio.sleep(delay=1)
await interaction.followup.send("Hi", ephemeral=True) # How can i edit this message? -_-
button_create.callback = button_callback
I tried to use "interaction.followup.edit_message("Something")", but i got error:
discord.errors.HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In message_id: Value "Something" is not snowflake.
followup.send() returns the WebhookMessage object that it sent if you set the wait kwarg to True, so you can store it in a variable and call .edit() on it.
From the send docs:
wait (bool) – Whether the server should wait before sending a response. This essentially means that the return type of this function changes from None to a WebhookMessage if set to True.

If I want to remove an ID-specified role within a function, how can I do that?

If I want to remove an ID-specified role within a function, how can I do that?
#bot.command()
async def aa(ctx,member:discord.Member):
role_muted = discord.utils.get(ctx.guild.roles, name='test01')
await member.remove_roles(role_muted)
What I want is to specify an ID in a function like this.
#bot.command()
async def aa(ctx):
member = 414087251992117211 #ID User
role_muted = discord.utils.get(ctx.guild.roles, name='test01')
await member.remove_roles(role_muted)
how can i do it The reason I have to do this is because I will continue to develop such as When you receive this Role within 3 days if not online it will remove your Role.
Use Guild.get_member(id) to get a member by their ID. You can get the Guild either from the ctx if you want it to run in the guild where you call the command, or from a Guild ID that you store somewhere using Bot.get_guild(id).
If you want to pass the ID in as an argument to the function and have it convert to a member automatically, use a Converter.
Can you give an example? I tried to do as you said. but an error occurred
#bot.command()
async def aa(ctx):
member = discord.Guild.get_member(414087251992117211)
role_muted = discord.utils.get(ctx.guild.roles, name='test01')
await member.remove_roles(role_muted)
Error
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'remove_roles'
#UpFeR Pattamin, please comment on a reply instead of posting a new one. You're getting this error because you're not specifying which guild you are talking about. If you want to get the one that the command was executed in, I'm pretty sure you need to do ctx.guild.get_member().

How do I implement a wait_for function into my command?

I am trying to make a bot that will pick a word from a text file and then scramble it and then the user unscrambles the word and types it. But I do not know how to implement the wait_for function into the command.
#client.command()
async def start(ctx):
await ctx.send('Time for chaos')
Unscrambled_word = random.choice(list(open('C:\\Users\\user\\Desktop\\Discord Bots\\Fake Speedjar\\words.txt')))
I suggest reading the documentation here
It comes with a good simple example.
There is another library called dpytools that has a helper (wait_for_author) for this kind of simple cases you can check it here
Basically the wait_for method will wait for something and then return it to you. In this case a "message".
def check(msg):
return msg.author == ctx.author and msg.channel == ctx.channel
message = await client.wait_for('message', check=check)
The check function takes only the awaited object(s) and returns a bool indicating if the message Is what you're expecting.
Please check the documentation for further information.

how to add reaction to a specifc user?

I've been working on this piece of code:
#client.event
async def lol(message,ctx):
if ctx.author.id == <user_id>:
await message.add_reaction('❤️')
else:
return
I am pretty sure that it is developed correctly, yet I am not getting the desired results.
I am pretty sure that if you check the console, an HTTP error would have been encountered. That's because you directly pasted the emoji in the function parameter. You have to add its unicode value. In your case:
await message.add_reaction(u'\u2764')
You are using an event decorator rather than a command, unless you were trying to detect if the user reacted, but its still completely off. What it looks like, the command that is called will send a message and the bot will react to it.
#client.command()
async def lol(ctx):
message = await ctx.send(f"{ctx.author.mention}, lol")
await message.add_reaction('😂')
If you then want to detect if the user had reacted to the emoji, you can use a event, but an on_reaction_add:
#client.event
async def on_reaction_add(reaction, user):
if reaction.emoji == '😂':
await user.send("Lol")

Resources