PCXCogs icon indicating copy to clipboard operation
PCXCogs copied to clipboard

[reactchannel] Option to have only one reaction per message.

Open viharm opened this issue 3 years ago • 3 comments

Hi, this is a really cool cog, and I love it for its simplicity. But I do feel that there are some improvements which could make it more versatile.

I am aware that you have noted in issue #48, that you will be rewriting this cog. When you do may I suggest the following please?

Currently, anyone can react to all options, this is ok for many usecases using the custom template. But for voting, it might be useful to prevent multiple reactions - people shouldn't be able to upvote and downvote at the same time.

(if this is already the case, then I'm sorry for raising it; as I couldn't find the option for this functionality).

Thanks again for making an awesome tool :-)

viharm avatar Jan 16 '22 11:01 viharm

Back in the day, it was the case that a user could only upvote or downvote on a message, and the bot would automatically remove the opposite reaction if present. Very slick, I liked seeing it in action. But, that can lead to a huge amount of API abuse if you have users that spam up and down votes over and over. So I decided to remove that.

The karma math still checks out though, if a user reacts with both they cancel each other out (since one adds 1 and then the other subtracts 1). Just that it looks like there's a lot more total votes than there actually are. Unfortunately, that's just how Discord is.

I will keep this open though, since I do want to see that feature remade, while respecting the API. Though if it turns out there's a bunch of race conditions or weird edge cases that make it difficult or impossible to reimplement safely, I might just give up on it. We shall see!


Notes for future PhasecoreX:

Maybe have a background task that checks on a queue every half second or so. Whenever an upvote/downvote happens, add it to this queue. When the background task sees something in the queue, pop it, check if the reaction still exists, do the reaction removal on the opposite, and then wait 10 seconds or something (if we did remove one). Then keep looking for the next reaction to process. That way, each reaction that needs to be removed will need to wait at least 10 seconds from the last removal.

Will have to check what happens when the user spams a bunch. Ultimately you want their last upvote to count. They could upvote and then downvote (upvote immediately removed), then upvote again (queue is waiting 10 seconds to process this upvote), then remove downvote and then re-add it. The queue will first check the upvote, see it's still there, and remove the downvote. Then the queue will process the downvote, but that doesn't exist anymore so it's skipped. The users last action of downvote isn't how this process ends. So yeah there's probably a lot of garbage edge cases like that.

Maybe that could be solved so that whenever a reaction is added to the queue, immediately remove the opposite reaction from the queue. There's probably a python data structure that can do that.

PhasecoreX avatar Jan 16 '22 15:01 PhasecoreX

Understood. Thanks for your response. I am also glad to see that you've put significant thought to enhancing the single reaction functionality. I'm not familiar with the Discord API, and certainly not knowledgeable enough, but as I was trying out various cogs, I noticed that reactpoll by Flapjack (https://github.com/flapjax/FlapJack-Cogs) uses the single input functionality (with an option to allow multiple reactions. I hope it helps.

viharm avatar Jan 16 '22 22:01 viharm

Yeah I looked over it, that code just deletes the old reaction, like I was doing before. But also that code was from 2 years ago, and Discord has been a bit more strict on API abuse since then. It would be nice if Discord had a "limit how many different reactions a user can have on a message" option per message, that would solve everything. But alas no such luck.

PhasecoreX avatar Jan 16 '22 22:01 PhasecoreX