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