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

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.

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 to make a slash command bot do not reply messages

#slash.slash(name='spam', description='I will spam your content for times!', options=optionsspam, guild_ids=[847769978308526090])
async def spam(ctx, text: str, times: int="15"):
if bool(times):
Times = 15
else:
Times = times
for i in range(int(Times)):
await ctx.send(text)
await asyncio.sleep(.7)
And the result is:
It keeps replying to the first message that the bot sent. I don’t want the bot to reply. I want it to just send a normal message. How?
An interaction (slash-command) will always require a direct response towards the user. If you do not use ctx.send(str), the interaction will fail.
You've got 2 options to make it seem, like you are not responding to the slash command
Hide the response
You can post a hidden answer ctx.send('ok', hidden=True) and then send the intented message into the channel ctx.channel.send(str).
This will make the initial 'ok' only visible for the invoking users and all other members of the server will neither see the request, nor the first response.
Delete the response
Your second option is to automatically delete the answer after a very short period (ctx.send('ok', delete_after=1)), followed by a normal message into the channel ctx.channel.send(str).
Defering the response
You might need to defer your response if you can't respond within 3 seconds of the invocation. Defering an interaction (ctx.defer(hidden=True) or ctx.defer()) must be called with the same hidden attribute as your future ctx.send().
If you want to hide your respons ctx.send('ok', hidden=True), you need to defer in the same state ctx.defer(hidden=True).
You could get the channel and send message to the channel directly. However, you then must use something like ctx.defer() so that the interaction doesn't get displayed as failed.
#slash.slash(name='spam', description='I will spam your content for times!', options=optionsspam, guild_ids=[847769978308526090])
async def spam(ctx, text: str, times: int="15"):
channel = ctx.channel
if bool(times):
Times = 15
else:
Times = times
for i in range(int(Times)):
if channel != None:
await channel.send(text)
await asyncio.sleep(.7)
await ctx.send("Done")

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")

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

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.

Respond to user and continue to run async functions

I want to respond to user as soon as I received the request, then continue to save data to database
async def index(request):
data = await request.post()
response.write("done")
async with request.app.mysqlpool.acquire() as conn:
async with conn.cursor() as cur:
await cur.execute("INSERT INTO ...")
If I try to wrap the part after request.write to separate function and than call it with run_in_executor - it doesn't allow awaitable functions inside (TypeError: coroutines cannot be used with run_in_executor())
Is there a way to do it in aiohttp?
Push await response.drain() just after response.write(...) call.
It doesn't exactly guarantee that data are sent through the wire but it's the closest solution.

Resources