discord.py icon indicating copy to clipboard operation
discord.py copied to clipboard

Analogues to `command_*` events for application commands

Open MajorTanya opened this issue 2 years ago • 4 comments

Summary

Add events such as application_command_error and application_command_completion to mimic the command_error and command_completion events of text commands.

What is the feature request for?

The core library

The Problem

I personally liked to use the command_completion event as a way to build some statistics for how often a command gets used (only counting successful uses). The normal event listener from discord.ext.commands works perfectly for this.

However, a similar event for application commands doesn't exist, nor does the command_error analogue, which is useful in the error handling process.

The Ideal Solution

Having events dispatched that are equivalent in purpose would be the ideal solution, especially if their listeners were as simple to use as the on_command_completionand on_command_error ones, i.e., on_application_command_completion and on_application_command_error.

They could possibly be added for other Interaction types, or maybe as one generic event overall (interaction_completion?).

The Current Solution

None.

Additional Context

I don't know if there is a structural reason for these events to not exist or if there is some usable solution (I didn't find any when searching through issues, discussions, or the Discord server).

MajorTanya avatar Jun 08 '22 17:06 MajorTanya

@MajorTanya There exists a similar listener on_interaction

rtk-rnjn avatar Jun 08 '22 17:06 rtk-rnjn

@MajorTanya There exists a similar listener on_interaction

Thanks! You're right, but that fires on all invocations of an interaction, right? I was wondering specifically about one that “guarantees” an error / successful completion, like on_command_completion.

MajorTanya avatar Jun 08 '22 18:06 MajorTanya

This feature request is common and is something I was aware about even before I published any of the changes. The problems are mainly design and future proofing. The problems I need to resolve are as follows:

  1. The command framework cheats a bit by adding extra events that have nothing to do with Discord for the sake of usability. In contrast, every event that discord.Client dispatches corresponds to at least one gateway event from Discord or from the protocol. There are no library specific events being dispatched by this mechanism. The library specific events are instead done as "hooks" such as setup_hook and before_identify_hook.
  2. Creating events related to application commands means that there will be possible conflict whenever Discord decides to add events for application commands, some of these have already existed but were removed. Right now there is one Discord dispatch event for application commands for permissions being updated.
  3. There already exists on_interaction for on_app_command and CommandTree.on_error for on_app_command_error. You're right that there's a glaring omission for on_app_command_completion.
  4. The interaction with hybrid commands would need to be thought out. For example, if you invoke a hybrid command's application command counterpart right now the on_command_completion/on_command_error/on_command events are dispatched. Should the equivalent on_app_command ones be called as well?

Rapptz avatar Jun 08 '22 23:06 Rapptz

Thank you for the in-depth response, I didn't know about all those factors before.

  1. Creating events related to application commands means that there will be possible conflict whenever Discord decides to add events for application commands, some of these have already existed but were removed. [...]

An “easy” solution would be to prepend the events with a dpy or something and make the events look like DPY_APP_CMD_COMPLETED / handlers like on_dpy_app_command_completed. It would make them immune from immediately breaking Discord changes, though I'm aware that this approach is too icky and breaks with library consistency 😅.

  1. The interaction with hybrid commands would need to be thought out. For example, if you invoke a hybrid command's application command counterpart right now the on_command_completion/on_command_error/on_command events are dispatched. Should the equivalent on_app_command ones be called as well?

It would probably be necessary to call both to avoid unexpected behaviour, but could another option be to only call the handler of the variant invoked? So if the Hybrid gets called as a Slash Command, it could trigger on_app_command_completion but if it gets used as a classic Command, it could trigger on_command_completion.

This way, a command completion doesn't get handled in duplicate, and the triggered one is always type-appropriate. It would also make the library overall more consistent (from my viewpoint at least), considering that Hybrids currently only call the classic handlers.

I'm not sure how this approach could cause problems (other than the new behaviour that would require getting used to by developers?), but I'm sure there are many possibilities.

If they are used as clean-up hooks or similar, developers would maybe need to duplicate code / create methods for them?

My ideas might be too simplistic though, just trying to figure it out

MajorTanya avatar Jun 13 '22 19:06 MajorTanya