Home > Software engineering >  Discord.py - User ID from message reaction dump to json file
Discord.py - User ID from message reaction dump to json file

Time:08-06

I'm looking for a way to store all the user reactions from a message in a json file. I want the users who react with the "✅" to be stored in one json file and the users who react with "❌" to be stored in a separate json file.

This is the portion of the code I'm having trouble with:

for reactions in message.reactions:
  if str(reactions) == "✅":
    user_list = [user async for user in message.reactions.users() if user != client.user]
    for user in user_list:
      users = user.id   "\n"
      
      with open ("reaction_tick.json", "w") as f:
        json.dump(users,f)
        return True
for reactions in message.reactions:
  if str(reactions) == "❌":
    user_list = [user async for user in message.reactions.users() if user != client.user]
    for user in user_list:
      users = user.id   "\n"
            
      with open ("reaction_cross.json", "w") as f:
        json.dump(users,f)
        return True

How do I gather all the users' ids and put them into a string then dump that into a json file?

So far, when I run all the code nothing happens and there are no error messages.

Any help would be greatly appreciated.

CodePudding user response:

You made a silly mistake in the line used to create user_list. It's reaction.users(), not <message>.reactions.users(). You are trying to call a function users() of a list object which does not exist (a list obviously doesn't have a .users() function). In other words, you are trying to use users() on the wrong object. message.reactions is a list (it returns a List[Reaction]). You are trying to run list.users(), which is invalid. I've corrected the code:

for reaction in message.reactions:
  if str(reaction) == "✅":
    user_list = [user async for user in reaction.users() if user != client.user]
    #it should be reaction.users() and not <message>.reactions.users()
    for user in user_list:
      users = users   str(user.id)   "\n" #converting ID to str and adding instead of overwriting
      
      with open ("reaction_tick.json", "w") as f:
        json.dump(users,f)
        return True
for reaction in message.reactions:
  if str(reaction) == "❌":
    user_list = [user async for user in reaction.users() if user != client.user]
    for user in user_list:
      users = users   str(user.id)   "\n"
            
      with open ("reaction_cross.json", "w") as f:
        json.dump(users,f)
        return True

Note that I've replaced reactions with reaction in the for loops (so that I don't make mistakes). You can correct them back if you want; just make sure you correct them in other places too.

Here is an example of how to use this code:

from discord.ext import commands
import discord.utils
import json

intent = discord.Intents(messages=True, message_content=True, guilds=True)

bot = commands.Bot(command_prefix="", description="", intents=intent)

@bot.event
async def on_ready(): #When the bot comes online
    print("It's online.")

@bot.command(name="gr")
async def gr(message, msg):
    if msg == "message":
        
        rmsg = None #the message with reactions
        
        async for msg in message.channel.history(limit=200):
            if msg.content == "message":
                rmsg = msg
        
        for reaction in rmsg.reactions:
            users = "" #the string to dump
            if str(reaction) == "✅":
                user_list = [user async for user in reaction.users() if user != bot.user]
                #it should be reaction.users() and not <message>.reactions.users()
                for user in user_list:
                    users = users   str(user.id)   "\n" #converting ID to str and adding instead of overwriting
                    
                    with open("reaction_tick.json", "w") as f:
                        json.dump(users, f)
                        return True
        for reaction in rmsg.reactions:
            if str(reaction) == "❌":
                user_list = [user async for user in reaction.users() if user != bot.user]
                for user in user_list:
                    users = users   str(user.id)   "\n"
                    
                    with open("reaction_cross.json", "w") as f:
                        json.dump(users, f)
                        return True

bot.run(<token>)

You can send a message on Discord (manually) and react to it with the emojis (for testing). Replace "message"s with the content of the message which you sent manually. rmsg is the message (to which you also reacted manually). users is the string that's going to be dumped as a JSON. Also, I've replaced users = user.id "\n" with users = users str(user.id) "\n". Your code overwrites users every time in the for loop. Also, you can't concatenate a string (users in my case) with an integer (user.id).

Do you not get any errors or exceptions? Because I got many.

  • Related