pycord icon indicating copy to clipboard operation
pycord copied to clipboard

feat: Implement with_response For Interaction Callbacks

Open Icebluewolf opened this issue 1 year ago • 6 comments

Summary

Implements with_response for interaction callbacks.

This will update Interaction._original_response to avoid needing to make an API request when calling Interaction.original_response() It also adds InteractionCallback which contains .is_loading() and .is_ephemeral() and is referenced through Interaction.callback

It was decided to always enable with_response instead of allowing the user to specify if they want it per #discussion on Discord.

The #type: ignore comment is because I copy pasted that code from somewhere else. They did not specify why they were ignoring.

Information

  • [ ] This PR fixes an issue.
  • [x] This PR adds something new (e.g. new method or parameters).
  • [ ] This PR is a breaking change (e.g. methods or parameters removed/renamed).
  • [ ] This PR is not a code change (e.g. documentation, README, typehinting, examples, ...).

Checklist

  • [x] I have searched the open pull requests for duplicates.
  • [x] If code changes were made then they have been tested.
    • [x] I have updated the documentation to reflect the changes.
  • [x] If type: ignore comments were used, a comment is also left explaining why.
  • [x] I have updated the changelog to include these changes.

Icebluewolf avatar Feb 11 '25 03:02 Icebluewolf

After testing, I found that:

  • interaction.is_loading() is always returning False, regardless of context.
  • I might be misunderstanding its purpose or usage.

I tested interaction.is_loading() in several scenarios:

  • After deferring a command
  • After deferring a component interaction
  • After a normal message interaction

In all cases, the result was still False.

  • interaction.message returns correctly ✅
  • interaction.is_ephemeral works as expected ✅

if there is something else to test pls tell me

Lumabots avatar May 28 '25 12:05 Lumabots

perhaps a large change, but it might be better if we had a proper InteractionCallback object that users can referenced via interaction.callback, which can be used for processing

NeloBlivion avatar May 28 '25 14:05 NeloBlivion

@Lumabots I cannot reproduce. I am getting the correct values for .is_loading()

@bot.command()
async def with_response(ctx: discord.ApplicationContext):
    i = await ctx.defer()
    print("Loading: " + str(ctx.interaction.is_loading()))

Icebluewolf avatar May 29 '25 22:05 Icebluewolf

perhaps a large change, but it might be better if we had a proper InteractionCallback object that users can referenced via interaction.callback, which can be used for processing

~~I dont really think this is needed, let me know if you think it would be much better for it to be a separate attribute.~~ Nevermind it probably is for the best. I am not going to bother exposing the message via this route though because it will already be exposed through original_response

~~It may be better for is_loading() and is_ephemeral() to return None before the interaction has been responded to.~~ The callback object will be None instead.

Icebluewolf avatar May 29 '25 22:05 Icebluewolf

When component interactions are deferred with invisible=True (py-cords default) it does not count as loading based on Discords response. Not sure if this is intended behavior on Discords side.

Icebluewolf avatar May 29 '25 23:05 Icebluewolf

When component interactions are deferred with invisible=True (py-cords default) it does not count as loading based on Discords response. Not sure if this is intended behavior on Discords side.

Remind me later. I'm gonna check up with staff

Lulalaby avatar Jun 02 '25 03:06 Lulalaby

@Lulalaby status? This would be nice to have in 2.7

Icebluewolf avatar Aug 31 '25 13:08 Icebluewolf

can u resolve the merge conflicts. i'll check out the rest meanwhile

Lulalaby avatar Aug 31 '25 13:08 Lulalaby

What's the reason the new message isn't attached to the message attribute rather than having to await the original_response method?

Soheab avatar Sep 01 '25 14:09 Soheab

What's the reason the new message isn't attached to the message attribute rather than having to await the original_response method?

Interaction.message is the message that the interaction originates from. Interaction.original_response() is

  • The same as Interaction.message if the interaction response type was UPDATE_MESSAGE
  • A different message if the interaction response type was CHANNEL_MESSAGE_WITH_SOURCE
  • Any other interaction response types have it fall back to the same message as Interaction.message. This case is how it was and is not affected by the PR.

Icebluewolf avatar Sep 01 '25 17:09 Icebluewolf

When component interactions are deferred with invisible=True (py-cords default) it does not count as loading based on Discords response. Not sure if this is intended behavior on Discords side.

Remind me later. I'm gonna check up with staff

This is not the case anymore, was something changed or did I test wrong ?

Test Code
from discord import *
from dotenv import load_dotenv
import os
import logging
logging.basicConfig(level=logging.INFO)

load_dotenv()

bot = Bot(intents=Intents.all())

@bot.slash_command()
async def test(ctx: ApplicationContext):
    await ctx.defer()
    await asyncio.sleep(6)
    m = await ctx.respond(f"Hello, world!, loading: {ctx.interaction.callback.is_loading()}, ephemeral: {ctx.interaction.callback.is_ephemeral()}")
    await m.reply(f"Hello again, world!, loading: {ctx.interaction.callback.is_loading()}, ephemeral: {ctx.interaction.callback.is_ephemeral()}")

bot.run(os.getenv("TOKEN_2"))

Paillat-dev avatar Sep 03 '25 14:09 Paillat-dev

This is not the case anymore, was something changed or did I test wrong ?

Invisible only applies to component interactions

Icebluewolf avatar Sep 03 '25 15:09 Icebluewolf