How do I make a leaderboard command? Discord.py - python

This is my event that configures levels for each member and stores the information in a JSON file. I would like a leaderboard that lists the top 10 people with the highest level but I am unsure how to go about doing this. Thanks in advance.
class on_message(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_message(self, message):
channel = self.bot.get_channel(config.server_chat)
with open("users.json", "r") as f:
users = json.load(f)
await update_data(users, message.author)
await add_experience(users, message.author, 1)
await level_up(users, message.author, message, channel)
with open("users.json", "w") as f:
json.dump(users, f)
async def update_data(users, user):
if not str(user.id) in users:
users[str(user.id)] = {}
users[str(user.id)]["experience"] = 0
users[str(user.id)]["level"] = 1
users[str(user.id)]["messages"] = 0
async def add_experience(users, user, exp):
users[str(user.id)]["experience"] += exp
users[str(user.id)]["messages"] += exp
async def level_up(users, user, message, channel):
experience = users[str(user.id)]["experience"]
lvl_start = users[str(user.id)]["level"]
lvl_end = int(lvl_start * 5)
update = lvl_start + 1
if experience >= lvl_end:
users[str(user.id)]["experience"] = 0
users[str(user.id)]["level"] = lvl_start + 1
if not message.author.bot:
lvl = users[str(user.id)]["level"]
await channel.send(f"**{user.mention} reached level {update}**")
def setup(bot):
bot.add_cog(on_message(bot))

You can sort JSON data and get first 10 users:
#commands.command()
async def leaderboard(self, ctx):
with open("users.json", "w") as f:
data = json.load(f)
embed = discord.Embed(title="Leaderboard")
for user_id, user_data in sorted(data.items(), key=lambda x: x[1]['experience'], reverse=True)[:10]:
embed.add_field(name=self.bot.get_user(user_id), value=f"Experience: {user_data['experience']}\nLevel: {user_data['level']}", inline=False)
await ctx.send(embed=embed)

Related

I was wondering how to make a leaderboard cmd in discord.py rewrite

Hi I was wondering how I would make a leaderboard cmd in discord.py rewrite I have a fully working lvling system but I'm wondering how to show the top ten ppl that are the highest lvl. I tried this but nothing comes up when I type -leaderboard ok so I need to type more to upload this so just ignore what I'm typing now damn I need to write even more ok is this enough hopfully
async def leaderboard(ctx):
with open('users.json', 'r') as f:
data = json.load(f)
top_users = {k: v for k, v in sorted(data.items(), key=lambda item: item[1], reverse=True)}
names = ''
for postion, user in enumerate(top_users):
# add 1 to postion to make the index start from 1
names += f'{postion+1} - <#!{user}> with {top_users[user]}\n'
embed = discord.Embed(title="Leaderboard")
embed.add_field(name="Names", value=names, inline=False)
await ctx.send(embed=embed)
in my users.json folder its user id then xp then lvl.
here is the code for my mainfile
#client.event
async def on_member_join(member):
with open('users.json', 'r') as f:
users = json.load(f)
await update_data(users, member)
with open('users.json', 'w') as f:
json.dump(users, f)
#client.event
async def on_message(message):
if message.author.bot == False:
with open('users.json', 'r') as f:
users = json.load(f)
await update_data(users, message.author)
await add_experience(users, message.author, 5)
await level_up(users, message.author, message)
with open('users.json', 'w') as f:
json.dump(users, f)
await client.process_commands(message)
async def update_data(users, user):
if not f'{user.id}' in users:
users[f'{user.id}'] = {}
users[f'{user.id}']['experience'] = 0
users[f'{user.id}']['level'] = 1
async def add_experience(users, user, exp):
users[f'{user.id}']['experience'] += exp
async def level_up(users, user, message):
with open('levels.json', 'r') as g:
levels = json.load(g)
experience = users[f'{user.id}']['experience']
lvl_start = users[f'{user.id}']['level']
lvl_end = int(experience ** (1 / 4))
if lvl_start < lvl_end:
await message.channel.send(f'{user.mention} has leveled up to level {lvl_end}')
users[f'{user.id}']['level'] = lvl_end
#client.command()
async def level(ctx, member: discord.Member = None):
if not member:
id = ctx.message.author.id
with open('users.json', 'r') as f:
users = json.load(f)
lvl = users[str(id)]['level']
await ctx.send(f'You are at level {lvl}!')
else:
id = member.id
with open('users.json', 'r') as f:
users = json.load(f)
lvl = users[str(id)]['level']
await ctx.send(f'{member} is at level {lvl}!')
Remember that commands in discord.py should use the command decorator to specify that the function is meant to be processed as a command.
Therefore, in your main file, please add:
#client.command()
async def leaderboard(ctx):
with open('users.json', 'r') as f:
data = json.load(f)
top_users = {k: v for k, v in sorted(data.items(), key=lambda item: item[1], reverse=True)}
names = ''
for postion, user in enumerate(top_users):
# add 1 to postion to make the index start from 1
names += f'{postion+1} - <#!{user}> with {top_users[user]}\n'
embed = discord.Embed(title="Leaderboard")
embed.add_field(name="Names", value=names, inline=False)
await ctx.send(embed=embed)
The client.command() decorator has been added here.

discord.py Level System (Add Roles)

I want do add a Role which will gave to everyone who reach lvl 5. I already tried something but that didnt worked. Has somebody an idea how to start?
The stats got saved in a .json file like this:
{"719479402953572383": {"504641949068689430": {"experience": 8, "level": 1}}}
async def on_message(message):
if not message.author.bot:
print('function load')
with open('level.json','r') as f:
users = json.load(f)
print('file load')
await update_data(users, message.author,message.guild)
await add_experience(users, message.author, 4, message.guild)
await level_up(users, message.author,message.channel, message.guild)
with open('level.json','w') as f:
json.dump(users, f)
await bot.process_commands(message)
async def update_data(users, user,server):
if not str(server.id) in users:
users[str(server.id)] = {}
if not str(user.id) in users[str(server.id)]:
users[str(server.id)][str(user.id)] = {}
users[str(server.id)][str(user.id)]['experience'] = 0
users[str(server.id)][str(user.id)]['level'] = 1
elif not str(user.id) in users[str(server.id)]:
users[str(server.id)][str(user.id)] = {}
users[str(server.id)][str(user.id)]['experience'] = 0
users[str(server.id)][str(user.id)]['level'] = 1
async def add_experience(users, user, exp, server):
users[str(user.guild.id)][str(user.id)]['experience'] += exp
async def level_up(users, user, channel, server):
experience = users[str(user.guild.id)][str(user.id)]['experience']
lvl_start = users[str(user.guild.id)][str(user.id)]['level']
lvl_end = int(experience ** (1/4))
if str(user.guild.id) != '757383943116030074':
if lvl_start < lvl_end:
await channel.send('{} has leveled up to Level {}'.format(user.mention, lvl_end))
users[str(user.guild.id)][str(user.id)]['level'] = lvl_end```

Problems with my Discord Bot's Leveling system and role giver

So, I'm working on a Discord bot for my Discord server by following some tutorials, and I can't seem to figure out why both the reaction-role-giver and the leveling system isn't working.
For the reaction-role-giver, the point is to give the emoji the role to the person who reacts to that emoji as the descriptor implies. The error I'm getting for that is "Member not found." And the leveling system is supposed to store the user ID and the experience level in the users.json file (which it does). Still, it doesn't increase the level numbers like it's told to, and it duplicates the User ID in the users.json instead of adding the EXP points to the already-there User ID.
Here's the code:
import discord
from discord.ext import commands
import os
import json
client = commands.Bot(command_prefix="~")
#client.event
async def on_ready():
print("Bot is ready")
# Leveling System starts here!
# Needs to be fixed.
#client.event
async def on_member_join(member):
with open('users.json', 'r') as f:
users = json.load(f)
await update_data(users, member)
with open('users.json', 'w') as f:
json.dump(users, f)
#client.event
async def on_message(message):
with open('users.json', 'r') as f:
users = json.load(f)
await update_data(users, message.author)
await add_experience(users, message.author, 5)
await level_up(users, message.author, message.channel)
with open('users.json', 'w') as f:
json.dump(users, f)
async def update_data(users, user):
if not user.id in users:
users[user.id] = {}
users[user.id]['experience'] = 0
users[user.id]['level'] = 1
async def add_experience(users, user, exp):
users[user.id]['experience'] += exp
async def level_up(users, user, channel):
experience = users[user.id]['experience']
lvl_start = users[user.id]['level']
lvl_end = int(experience ** (1/4))
if lvl_start < lvl_end:
await client.send_message(channel, '{} has leveled up to level {}'.format(user.mention, lvl_end))
users[user.id]['level'] = lvl_end
# Reaction Code starts here
# Needs to be fixed...
#client.event
async def on_raw_reaction_add(payload):
message_id = payload.message_id
if message_id == ID_redacted: # ID Redacted but in the actual file it's there
guild_id = payload.guild_id
guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds)
if payload.emoji.name == 'Toons':
role = discord.utils.get(guild.roles, name='Toons')
elif payload.emoji.name == 'Heroes':
role = discord.utils.get(guild.roles, name='Heroes')
elif payload.emoji.name == 'NotificationsSquad':
role = discord.utils.get(guild.roles, name='Notifications Squad')
else:
role = discord.utils.get(guild.roles, name=payload.emoji.name)
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.add_roles(role)
print("done")
else:
print("Member not found.")
else:
print("Role not found.")
token = os.environ.get("Secrets")
client.run(token)
I've tried to get help from some friends but they're too busy. So, I have come here for help. I hope that this was enough information to go on! If not, ask me in the comments if I need more information.

How to make a leaderboard command discord.py?

I have looked all over the web, and couldn't find an answer. I also asked my friend but he didn't know how to do this command. How can I make this level code display in a leaderboard command?
Here is my code:
#client.event
async def on_message(message):
if not message.author.bot:
print('function load')
with open('level.json','r') as f:
users = json.load(f)
print('file load')
await update_data(users, message.author,message.guild)
await add_experience(users, message.author, 4, message.guild)
await level_up(users, message.author,message.channel, message.guild)
with open('level.json','w') as f:
json.dump(users, f)
await client.process_commands(message)
async def update_data(users, user,server):
if not str(server.id) in users:
users[str(server.id)] = {}
if not str(user.id) in users[str(server.id)]:
users[str(server.id)][str(user.id)] = {}
users[str(server.id)][str(user.id)]['experience'] = 0
users[str(server.id)][str(user.id)]['level'] = 1
elif not str(user.id) in users[str(server.id)]:
users[str(server.id)][str(user.id)] = {}
users[str(server.id)][str(user.id)]['experience'] = 0
users[str(server.id)][str(user.id)]['level'] = 1
async def add_experience(users, user, exp, server):
users[str(user.guild.id)][str(user.id)]['experience'] += exp
async def level_up(users, user, channel, server):
experience = users[str(user.guild.id)][str(user.id)]['experience']
lvl_start = users[str(user.guild.id)][str(user.id)]['level']
lvl_end = int(experience ** (1/4))
if str(user.guild.id) != '757383943116030074':
if lvl_start < lvl_end:
await channel.send('{} has leveled up to Level {}'.format(user.mention, lvl_end))
users[str(user.guild.id)][str(user.id)]['level'] = lvl_end
#client.command(aliases = ['rank','lvl'])
async def level(ctx,member: discord.Member = None):
if not member:
user = ctx.message.author
with open('level.json','r') as f:
users = json.load(f)
lvl = users[str(ctx.guild.id)][str(user.id)]['level']
exp = users[str(ctx.guild.id)][str(user.id)]['experience']
endXP = (lvl + 1) ** 4
embed = discord.Embed(title = 'Level {}'.format(lvl), description = f"{exp} XP / {endXP} XP" ,color = discord.Color.green())
embed.set_author(name = ctx.author, icon_url = ctx.author.avatar_url)
await ctx.send(embed = embed)
else:
with open('level.json','r') as f:
users = json.load(f)
lvl = users[str(ctx.guild.id)][str(member.id)]['level']
exp = users[str(ctx.guild.id)][str(member.id)]['experience']
endXP = (lvl + 1) ** 4
embed = discord.Embed(title = 'Level {}'.format(lvl), description = f"{exp} XP / {endXP} XP" ,color = discord.Color.green())
embed.set_author(name = member, icon_url = member.avatar_url)
await ctx.send(embed = embed)
Another thing. Most of the people that comment on my posts nowadays comment about a certain question that has nothing to do with what I'm asking. If you want to bombard me with those comments, go do it in the question, not on this post. Thank you :)
#client.command()
async def leaderboard(ctx, x=10):
with open('level.json', 'r') as f:
users = json.load(f)
leaderboard = {}
total=[]
for user in list(users[str(ctx.guild.id)]):
name = int(user)
total_amt = users[str(ctx.guild.id)][str(user)]['experience']
leaderboard[total_amt] = name
total.append(total_amt)
total = sorted(total,reverse=True)
em = discord.Embed(
title = f'Top {x} highest leveled members in {ctx.guild.name}',
description = 'The highest leveled people in this server'
)
index = 1
for amt in total:
id_ = leaderboard[amt]
member = client.get_user(id_)
em.add_field(name = f'{index}: {member}', value = f'{amt}', inline=False)
if index == x:
break
else:
index += 1
await ctx.send(embed = em)
here is some code that may help

I have this error: json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

I have looked over all of the internet but am not able to solve this error. I have no idea what it means as I'm new to json files and python. This is for my Discord.py leveling system. Please help me.
I don't Understand it at all. Its quite new to me. I am really confused. It doesn't make any sense to me.
Here is my code:
#client.event
async def on_member_join(member):
with open('users.json', 'r') as f:
users = json.load(f)
await update_data(users, member)
with open('users.json', 'w') as f:
json.dump(users, f)
#client.event
async def on_message(message):
if message.author.bot == False:
with open('users.json', 'r') as f:
users = json.load(f)
await update_data(users, message.author)
await add_experience(users, message.author, 5)
await level_up(users, message.author, message)
with open('users.json', 'w') as f:
json.dump(users, f)
await client.process_commands(message)
async def update_data(users, user):
if not f'{user.id}' in users:
users[f'{user.id}'] = {}
users[f'{user.id}']['experience'] = 0
users[f'{user.id}']['level'] = 1
async def add_experience(users, user, exp):
users[f'{user.id}']['experience'] += exp
async def level_up(users, user, message):
with open('levels.json', 'r') as g:
levels = json.load(g)
experience = users[f'{user.id}']['experience']
lvl_start = users[f'{user.id}']['level']
lvl_end = int(experience ** (1 / 4))
if lvl_start < lvl_end:
await message.channel.send(f'{user.mention} has leveled up to level {lvl_end}')
users[f'{user.id}']['level'] = lvl_end
#client.command()
async def level(ctx, member: discord.Member = None):
if not member:
id = ctx.message.author.id
with open('users.json', 'r') as f:
users = json.load(f)
lvl = users[str(id)]['level']
await ctx.send(f'You are at level {lvl}!')
else:
id = member.id
with open('users.json', 'r') as f:
users = json.load(f)
lvl = users[str(id)]['level']
await ctx.send(f'{member} is at level {lvl}!')
levels.json file:
{}
users.json file:
{}
Try putting {} or [] to your json file

Categories

Resources