Создание бота для ролей в Discord, заходит в онлайн без проблем, но не обновляет роли.

Вопрос или проблема

В данный момент я программирую ролевого бота для небольшого сообщества на Discord, чтобы изучить Python 3 и библиотеку Discord в целом. Я пробовал разные решения в интернете, но явно что-то упускаю. Надеялся на какую-нибудь подсказку или идею о том, что не так, так как ошибок не выводится.

@client.event
async def on_ready():
  channel = client.get_channel(<ChannelID>)  #установить канал на #rules
  если isinstance(channel, discord.TextChannel):
    text = "Пожалуйста, прочитайте #rules и отреагируйте для подтверждения."
    emoji = await channel.send(text)
    await emoji.add_reaction('✅')

#Когда реакция
    @client.event
    async def on_reaction_add(reaction, author):
      channel = client.get_channel(<ChannelId>)  #Обновление канала как резерв
      если reaction.message.channel is not None и channel:
          return
      если reaction.emoji == "✅":
        author = reaction.author
        роль = await reaction.author.guild.get_role(<RoleID>)
        await author.add_roles(роль)  #Проверяет на правильную реакцию и добавляет роль
        reaction.message.delete()

Я пытался импортировать дополнительные библиотеки, такие как typing, для дополнительных функций, пробовал async On_Reaction, On_Ready и даже On_Message. У меня есть библиотека эмодзи на случай, если это была проблема. Роль для бота выше, чем роль, которую он пытается назначить, бот имеет права модератора, права членов гильдии и все разрешения, которые могут быть полезны для этого в моем понимании, а именно:

Читать историю сообщений
Создавать выражения
Создавать реакции
Модерировать участников
Управлять ролями
Создавать сообщения

Я также пробовал user.guild.roles и author.guild.roles для назначения.

В вашем фрагменте есть несколько ошибок. Первое — это то, что событие on_reaction_add определено внутри события on_ready, что может не сработать, так как это не поддерживается. Второе, в документации у нас есть discord.on_reaction_add(reaction, user), который имеет параметры класса discord.Reaction и (Union[discord.Member, discord.User]). Вы пытаетесь получить это:

await reaction.author.guild.get_role(<RoleID>)

https://discordpy.readthedocs.io/en/stable/api.html#discord.Reaction, отсюда правильный способ сделать это:

await reaction.message.guild.get_role(<RoleID>)

Тогда у нас есть это:

author = reaction.author

вы уже имеете автора, поэтому не должно быть причин пытаться получить его по-другому. Событие возвращает реакцию и пользователя, где пользователь — это человек, который отреагировал.

Проверьте документацию здесь: https://discordpy.readthedocs.io/en/stable/api.html, найдите discord.on_reaction_add

Ответ или решение

Создание бота для ролей в Discord может показаться сложной задачей, особенно если учесть множество деталей, которые могут стать причиной проблем. Основываясь на предоставленной информации, давайте разберем основные аспекты, которые могут привести к тому, что бот успешно подключается, но не обновляет роли.

1. Определение события обработки реакций

Как вы указали, код для обработчика событий on_reaction_add был помещен внутрь on_ready. Это недостаток структуры, так как вышестоящие функции как on_ready могут вызывать нежелательное поведение у вложенных обработчиков. Необходимо вынести обработчик on_reaction_add на тот же уровень, что и обработчик on_ready, чтобы Discord мог правильно распознать его.

2. Параметры и использование объекта реакции

Согласно документации Discord.py, основной целью этого события является получение реакций. Вместо того чтобы использовать reaction.author, необходимо использовать второй параметр, который передается в on_reaction_add, чтобы получить пользователя, добавившего реакцию. Ваша запись должна выглядеть следующим образом:

@client.event
async def on_reaction_add(reaction, user):

3. Получение роли и добавление ее пользователю

Ваш код содержит ошибку в способе получения роли. Вместо использования reaction.author, вы должны использовать user, который передается в качестве второго аргумента. Также следует убедиться, что вы используете правильный метод получения роли:

role = reaction.message.guild.get_role(<RoleID>)

4. Доступ к нужным каналам и проверка разрешений пользователя

Обратите внимание, что у вашего бота должны быть необходимые разрешения для управления ролями, а также для чтения и отправки сообщений в том канале, где он работает.

Вот пример исправленного кода:

@client.event
async def on_ready():
    channel = client.get_channel(<ChannelID>)  # Установите свой ChannelID
    if isinstance(channel, discord.TextChannel):
        text = "Пожалуйста, прочитайте #правила и добавьте реакцию для подтверждения."
        await channel.send(text)
        after_message = await channel.send('✅')
        await after_message.add_reaction('✅')

@client.event
async def on_reaction_add(reaction, user):
    if user.bot:  # Игнорировать реакции от ботов
        return
    if reaction.emoji == "✅" and reaction.message.channel.id == <ChannelID>:  # Проверить, что реакция добавлена в нужный канал
        role = reaction.message.guild.get_role(<RoleID>)  # Получить роль по ID
        member = reaction.message.guild.get_member(user.id)  # Получить члена сервера
        if role is not None and member is not None:
            await member.add_roles(role)  # Добавить роль пользователю

5. Проверка отладочной информации

Если бот продолжает не добавлять роли, включите отладочную информацию, чтобы видеть, доходят ли запросы до обработчика. Например, вы можете добавить print()-выражения, чтобы проверить, выполняются ли функции.

print(f'{user.name} добавил реакцию.')

Заключение

Следуя этим советам, вы сможете устранить проблемы с вашим ботом и привести его в рабочее состояние. Не забудьте проверить разрешения, убедиться в том, что все идентификаторы правильные, и, что самое важное, избегайте вложенности функций события. Это основные моменты, которые помогут улучшить ваш код и обеспечить его корректную работу.

Оцените материал
Добавить комментарий

Капча загружается...