Программирование бота Discord на Python — Не могу понять, как настроить роли реакции (часть 2)

#python #discord.py

#python #discord.py

Вопрос:

Ранее я задавал вопрос о ролях реакции, эта проблема была решена, но теперь у меня другая проблема. Вот мой код:

 @client.event
async def on_raw_reaction_add(payload):
  message_id = payload.message_id
  if message_id == 800172672860291132:
    guild_id = payload.guild_id
    guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds)
    
    role = None
    if payload.emoji.name == '🔴':
      role = discord.utils.get(guild.roles, name='Red')
    elif payload.emoji.name == '🟠':
      role = discord.utils.get(guild.roles, name='Orange')
    elif payload.emoji.name == '🟡':
      role = discord.utils.get(guild.roles, name='Yellow')
      
    if role is not None:
      member = payload.member
      if member is not None:
        await member.add_roles(role)
        print("done")
      else:
        print("Member not found")
    
    else:
      print("Role not found")


@client.event
async def on_raw_reaction_remove(payload):
  message_id = payload.message_id
  if message_id == 800172672860291132:
    guild_id = payload.guild_id
    guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds)
    
    role = None
    if payload.emoji.name == '🔴':
      role = discord.utils.get(guild.roles, name='Red')
    elif payload.emoji.name == '🟠':
      role = discord.utils.get(guild.roles, name='Orange')
    elif payload.emoji.name == '🟡':
      role = discord.utils.get(guild.roles, name='Yellow')
    
    if role is not None:
      member = payload.member
      if member is not None:
        await member.remove_roles(role)
        print("done")
      else:
        print("Member not found")
    
    else:
      print("Role not found")
 

Бот раздает роли просто отлично, но когда реакция удаляется, она не удаляет роль и говорит «Участник не найден». Если вы посмотрите на мой код, вы увидите, что это означает, что участник по-прежнему отсутствует. И, как я уже сказал, часть, которая предоставляет роли, работает нормально. Не уверен, что делать, какие-нибудь советы?

Ответ №1:

Я советую вам прочитать документы о полезной нагрузке события реакции, там говорится, что значение члена доступно только в том случае, если event_type имеет значение REACTION_ADD .

Что касается того, как решить вашу проблему, вы можете использовать on_reaction_remove(реакция, пользователь), который имеет user в качестве значения.

В качестве резервной копии для проблем с кэшем вы можете сохранить список участников, у которых есть роль, и проверить реакции на отсутствующего участника при получении события on_raw_reaction_remove (полезная нагрузка)

Комментарии:

1. Хорошо, итак, в тех частях, где у меня есть, если payload.emoji.name бы я просто заменил полезную нагрузку на реакцию ?

2. @CarterMichaelis reaction.name

Ответ №2:

on_raw_reaction_remove не дает вам объект-член таким же образом on_raw_reaction_add . Однако у них обоих есть одна общая черта, user_id . Найдите своего участника через payload.user_id

Код, используемый в моем тестовом боте:

 @client.vent
async def on_raw_reaction_remove(payload):
    message_id = payload.message_id
    if message_id == 800172672860291132:
        guild_id = payload.guild_id
        guild = client.get_guild(guild_id)
        
        role = None
        if payload.emoji.name == '🔴':
            role = discord.utils.get(guild.roles, name='Red')
        elif payload.emoji.name == '🟠':
            role = discord.utils.get(guild.roles, name='Orange')
        elif payload.emoji.name == '🟡':
            role = discord.utils.get(guild.roles, name='Yellow')
        
        if role is not None:
            member = discord.utils.find(lambda m: m.id == payload.user_id, guild.members)
            if member is not None:
                await member.remove_roles(role)
                print("done")
            else:
                print("Member not found") 
        else:
            print("Role not found")
 

Комментарии:

1. Хм, это все еще дает мне «Участник не найден»

2. @CarterMichaelis Я добавил код, который использовал в своем тестовом боте. Попробуйте скопировать его прямо оттуда. Он отлично работает на моем боте

3. Да, я не знаю, я скопировал вставил код, все еще не работает

4. @CarterMichaelis Просто ради попытки, ты можешь сделать member = guild.get_member(payload.user_id) ? это поможет вам найти участника?

5. @CarterMichaelis Давайте разберем это на что-то более простое. Удалите или закомментируйте все, что у вас есть on_raw_reaction_remove . Затем выполните только payload.guild_id , payload.user_id , client.get_guild(guild_id) , guild.get_member(user_id) и распечатайте все эти элементы, чтобы увидеть, что написано в терминале. Если вы уверены, что on_raw_reaction_add это работает и дает роли, то я не думаю, что это может быть намерением