Discord.py Команда с таймером
Хотелось бы попросить помощи.
Хочу сделать бота, который будет после команды создавать сообщение и создавать реакцию под своим сообщением, а после определенного промежутка времени (которое я укажу в команде) он будет выбирать рандомно тех людей, которые прожали реакцию бота и пингом, выбирать их.
Облазил много вариантов, но так и не нашел ни инфы, ни примера команды. Либо я глупый, либо не умею искать. Буду благодарен даже за информацию по моему вопросу!
Заранее благодарю.
Ответы (1 шт):
Не ищите готовый код, а постарайтесь придумать реализацию самостоятельно. Искать в этом деле нужно только отдельные, непонятные вам этапы создания команды.
На самом деле здесь главное начать)
*Cразу извините за длинный ответ, просто хочется, чтобы вы разобрались, а не просто скопировали код)
Создайте команду, которая принимает необходимые для полной работы параметры и создает сообщение - на вряд ли здесь возникнут трудности:
@bot.command()
async def random_pick(ctx, wait_seconds: int):
msg = await ctx.send('Нажмите ? внизу, чтобы участвовать')
Команда принимает время для ожидания и создает сообщение, но реакции под ним пока нет.
Что делать, если не знаете как работать с реакциями? Гуглить или читать документацию, где все подробно расписано. Советую почитать краткое руководство.
Вбиваем в поиск ключевое слово reaction и в списке видим что-то похожее на то, что мы ищем:
Выходит, теперь известно, как поставить реакцию под сообщением - добавляем это и подключим в функцию ожидание в течение wait_seconds:
@bot.command()
async def random_pick(ctx, wait_seconds: int):
msg = await ctx.send('Нажмите ? внизу, чтобы участвовать')
await msg.add_reaction('?')
await asyncio.sleep(wait_seconds)
Теперь нужно узнать список пользователей, которые поставили реакцию.
На изображении выше видим, что класс discord.Message имеет свойство reactions. Если открыть страницу, то можно узнать, что свойство хранит в себе список объектов типа discord.Reaction:
А у объекта discord.Reaction есть метод users() - переходим к нему:
И, что достаточно забавно, здесь даже есть пример выбора случайного пользователя, прям в документации)
Можете посмотреть самостоятельно
Также здесь надо отметить, что сообщение msg на данный момент не имеет реакций, так как в переменной хранится его состояние на момент отправки, а реакцию мы добавили позже. Поэтому нужно получить объект сообщения заново:
msg = await ctx.channel.fetch_message(msg.id)
И вот теперь уже можно получить список пользователей. Нашу реакцию поставил бот, поэтому она в списке первая, то есть индекс - 0:
users = await msg.reactions[0].users().flatten()
Вбиваем в гугл "python получить случайный элемент списка" и находим функцию choice() из стандартного модуля random.
Выбираем случайного пользователя, исключая самого бота (он-то тоже поставил реакцию) и отправляем сообщение, вызывая у выбранного юзера свойство mention, чтобы упомянуть:
del users[0] # бот первым ставит реакцию, поэтому его индекс - 0
await ctx.send(f'Победитель: {random.choice(users).mention}!')
Почитать про свойства других объектов, по типу mention у объекта пользователя можно все в той же документации, это вообще очень полезная штука)
Полный код:
import discord, asyncio
from random import choice
from discord.ext import commands
bot = commands.Bot(command_prefix='!', intents = discord.Intents.all())
@bot.command()
async def random_pick(ctx, wait_seconds: int):
msg = await ctx.send('Нажмите ? внизу, чтобы участвовать')
await msg.add_reaction('?')
await asyncio.sleep(wait_seconds)
msg = await ctx.channel.fetch_message(msg.id)
users = await msg.reactions[0].users().flatten()
del users[0]
await ctx.send(f'Победитель: {choice(users).mention}!')
bot.run('TOKEN')


