Home > Software design >  How to add cooldown mapping to users who reacted first?
How to add cooldown mapping to users who reacted first?

Time:03-02

Im currently working on a cart manager where users has a chance of a giveaway prize (First come first serve). Basically I will automatically post some embeds and the person who reacts first will get the prize and a message written in DM's from the bot. The user who got the prize first will get a cooldown for 5 minutes (the reason of this is that the same user should not be able to get a second prize within 5 minutes)

I have written something like this:

# -*- coding: utf-8 -*-
import asyncio
from datetime import datetime

from discord import Client, Embed, Object

client = Client()

lock = asyncio.Lock()

PRIVATE_CHANNEL_ID = xxxxxxxxxxxxxx
PUBLIC_CHANNEL_ID = xxxxxxxxxxxxx
EMOJI_ID = "\N{SHOPPING TROLLEY}"

# ----------------------------------------------------- #

@client.event
async def on_ready():
    print(f'{client.user.name} Logged In!')

@client.event
async def on_raw_reaction_add(payload):
    if payload.channel_id == PUBLIC_CHANNEL_ID and '\U0001f6d2' == str(payload.emoji) and payload.user_id != client.user.id:
        async with lock:
            # Check if person is rate limited

I have read abit regarding cooldown mapping and found an example of:

class SomeCog(commands.Cog):
    def __init__(self):
        self._cd = commands.CooldownMapping.from_cooldown(1.0, 60.0, commands.BucketType.user)

    async def cog_check(self, ctx):
        bucket = self._cd.get_bucket(ctx.message)
        retry_after = bucket.update_rate_limit()
        if retry_after:
            # you're rate limited
            # helpful message here
            pass
        # you're not rate limited

however my problem is that I do not know how to apply cooldown for a user who reacted first on given reaction and I wonder how can I do that? How can I apply a cooldown to the user to not be ablet o react for next 5 minutes using the CooldownMapping?

CodePudding user response:

The code you have shows how to have a common ratelimit between commands in a cog, to have a cooldown on the on_raw_reaction_add event you need a different approach.

raw_reaction_add_cooldown = commands.CooldownMapping.from_cooldown(
    1, 60.0, commands.BucketType.user  # change rate and per accordingly
)


async def get_raw_reaction_add_ratelimit(payload: discord.RawReactionActionEvent) -> Optional[float]:
    guild = client.get_guild(payload.guild_id)
    channel = client.get_channel(payload.channel_id)
    if guild is None or channel is None:
       return None

    author = guild.get_member(payload.user_id)
    message = await channel.fetch_message(payload.message_id)
    if author is None or message is None:
        return None

    # overwriting attribute since otherwise it will check the ratelimit 
    # of the user who SENT the message, not the one that reacted
    message.author = author
    bucket = raw_reaction_add_cooldown.get_bucket(message)
    return bucket.update_rate_limit()

To use it it's pretty simple, call the function and check for None

@client.event
async def on_raw_reaction_add(payload):
    ratelimit = await get_raw_reaction_add_ratelimit(payload)
    if ratelimit is None:
        print("NO RATELIMIT")
    else:
        print("RATELIMIT")

Pozdrawiam :)

  • Related