Discordpy Mod Logs Command - discord

I'm trying to make a mod logs, I'm not really good at this, I scripted myself and kinda worked but it didn't worked. So basically my plan is when someone types .modlogs #channel, bot is gonna get the channel id and type it to json file with guild id, i made that it works very well I'm stuck on getting key info from json file, im printing the values and they are same.
#commands.command(aliases=['purge'])
#commands.guild_only()
#commands.has_permissions(manage_messages=True)
async def clear(self,ctx, arg: int = None):
if arg is None:
await ctx.send(':x: You need to state a value!')
else:
with open('./logs.json', 'r') as f:
logsf = json.load(f)
if ctx.guild.id in logsf:
embedv = discord.Embed(color = discord.Colour.random())
embedv.add_field(name='Event Type:', value="Clear")
embedv.add_field(name='Channel:', value= ctx.channel)
embedv.add_field(name='Moderator:', value=ctx.message.author)
embedv.footer(text='Epifiz Logging')
schannel = commands.get_channel(logsf[ctx.guild.id])
await ctx.channel.purge(limit=arg)
await discord.schannel.send(embed=embedv)
await ctx.send('Done')
elif ctx.guild.id not in logsf:
await ctx.channel.purge(limit=arg)
await ctx.send(':white_check_mark: Successfully cleared {} messages.'.format(arg))
also my json file:
{
"838355243817369620": 853297044922564608
}
Also guild id is on json file, its not wrong.
Output

You made multiple mistakes in your code. The reason why you are getting the error is because this line here if ctx.guild.id in logsf: returns False even if the guild's id is in your JSON file. Here is why:
logsf = json.load(f) returns a dictionary. You'll get {"838355243817369620": 853297044922564608} it's unclear whether 838355243817369620 or 853297044922564608 is your guild id but think of it this way:
s = {1:2}
2 in s return False
and the second mistake is inserting "838355243817369620" as a str rather than an int like this 838355243817369620.
The solution is to use list() as follow if ctx.guild.id in list(logsf): and to insert "838355243817369620" as an int in your JSON file so it looks like this:
{
838355243817369620: 853297044922564608
}
#rather than this
{
"838355243817369620": 853297044922564608
}
value in embeds accepts str not discord objects. Use f"{input}" rather than the object as an input.
embedv.add_field(name='Channel:', value= f"{ctx.channel}")
embedv.add_field(name='Moderator:', value=f"{ctx.message.author}")
await schannel.send(embed=embedv) rather than await discord.schannel.send(embed=embedv)
From this line schannel = commands.get_channel(logsf[ctx.guild.id]) I can assume that 838355243817369620 is your server's id. So, I think that you can use:
if ctx.guild.id in logsf.keys(): instead of if ctx.guild.id in list(logsf):
and make sure to convert its keys values into int rather than str to make it work.

Related

Trying to sort a leaderboard command from highest value to lowest

I have a leaderboard that I'm trying to sort from the member with the highest count to the lowest count but I cannot seem to do it.
Leaderboard Code:
#bot.command()
#commands.cooldown(1, 20, commands.BucketType.user)
async def leaderboard(ctx):
embed = discord.Embed(
title="Leadboard",
description="Your Servers Count",
color=0xFF000
)
with open('messages.json') as file:
data = json.load(file)
for key, value in data[f"{ctx.guild.name}"].items():
try:
embed.add_field(name = key, value = value)
embed.set_footer(text="If you feel your message's are not being counted, please get the server owner to send me a dm!")
except: return
await ctx.respond(embed=embed)
Output: Gyazo.com
And here is a example of what I'm trying to accomplish.
Gyazo.com
final answer :
#your imports [...]
from discord.utils import get
from operator import itemgetter
from tabulate import tabulate
#your declarations [...]
#bot.command()
#commands.cooldown(1, 20, commands.BucketType.user)
listValues = []
sortedList = []
embed = discord.Embed(
title="Leadboard",
description="Your Servers Count",
color=0xFF000
)
with open('dat.json') as file:
data = json.load(file)
listValues = new_list = list(map(list, data[f"{ctx.guild.name}"].items()))
sortedList = sorted(listValues, key=itemgetter(1), reverse=True)
strToPrint = ""
for item in sortedList :
strToPrint = strToPrint +"\n"+ item[0] +" : "+str(item[1])
embed.add_field(name="Scores", value=strToPrint )
embed.set_footer(text="If you feel your message's are not being counted, please get the server owner to send me a dm!")
await ctx.send(embed=embed)
After a few tries on my side, easiest was to make a list of json dictionary, map the list to get keys and values, and turn it into a new list.
Then I convert the list into a string, adding "\n" as delimiter, and converting the score, after it has been sorted, into a string. Finally, I pass the resulting string as value for your embed, and.. voilà :)

Discord server channel lister not working

I'm trying to make something that can list all the channels in a server of your choice, but it won't work.
import discord
client = discord.Client()
token = ('TOKEN')
#client.event
async def on_connect():
print("What server do you want to list?")
find_guild = input("")
for guild in client.guilds:
try:
if guild.id == find_guild:
print(guild)
for channel in guild.channels:
try:
print(f' {channel}')
except:
print("Failed")
except:
print("Failed")
client.run(token)
(I removed my token for reasons)
I think that the issue is that the "if guild.id == find_guild:"
won't work.
Your find_guild = input("") is returning a str, the guild.id is an int, so comparing the two will always return False
Convert the input to an int using find_guild = int(input("")) and your code should work as intended.

How to check if a user has permission to use a command? Discordpy

I am creating a custom help command and I have a problem. The default help command can somehow hide commands that are not available for a user that invoked the command. I was looking everywhere and I can't find any solution. I tried using hidden attribute of a command object but it is not working. The best solution would be a method like Member.can_use(command) that would return True or False but there is nothing like that in docs. Or at least I cannot find it.
Help would be appreciated.
Use the Command.can_run method, an example would be:
#bot.command()
async def can_it_run(ctx, command_name: str):
command = bot.get_command(command_name)
can_use = await command.can_run(ctx)
if can_use:
await ctx.send(f"You can use {command_name}")
else:
await ctx.send(f"You can't use {command_name}")
Sadly if a check raises an exception (like commands.guild_only) the exception(s) won't be suppressed, also if you want to check if someone else (not the invoker) can use the command you have to overwrite Context.author, a handy function would be:
async def can_run(ctx, command_name: str, member: discord.Member=None) -> bool:
command = bot.get_command(command_name)
if command is None: # Command doesn't exist / invalid command name
return False # Or raise an exception
if member is not None: # If a member is passed overwrite the attribute
ctx.author = member
try:
return await command.can_run(ctx)
except Exception:
return False
#bot.command()
async def can_it_run(ctx, command_name: str, member: discord.Member=None):
resp = await can_run(ctx, command_name, member)
await ctx.send(resp)
You could just check if the user countains a certain id by doing the following:
if (message.author.id == "WHoever ID1" || message.author.id == "Whoever ID2"):
#Do Something
If you want to put a bunch of ID's in then just do the following:
bool = false;
arr = ["ID1", "ID2", "ID3"]
for x in arr:
if(x == message.author.id):
bool = true;
if(bool):
#Do stuff
bool = false;
This is very vague code but it should be something similar to this

Why does my discord bot not send a variable?

I have a bot that needs to send a message with a set message, followed by an integer defined by a variable. When I run this, the bot reacts to the message correctly but then doesn't send any response whatsoever. Why? XD (and yes I'm kinda bad and new at coding but idc I am determined to get this to work!)
EDIT: Ok it's sending the text and variable now, but it always prints as 0. Anyone know why it's always zero?
else:
emoji = '\N{Cross Mark}'
await message.add_reaction(emoji)
await message.channel.send("You messed it up at:")
await message.channel.send(f'{bowl_count}')
bowl_count == int(0)
Are you using on_message?
Also are you checking if bowl_count is equal to 0?
You don't need to provide int() unless you have a variable called 0 that's value is a string (text in quote marks)
else:
emoji = '\N{Cross Mark}'
await message.add_reaction(emoji)
await message.channel.send("YOU MESSED IT UP AT: ", bowl_count)
bowl_count = 0
Other than that it looks fine.
If you are using commands, then do define an await ctx.send("TEXT") as a variable called message
else:
emoji = '\n{Cross Mark}'
await message.add_reaction(emoji)
await message.channel.send("YOU MESSED IT UP AT: " + bowl_count)
bowl_count == int(0)
first, the escaped \N doesn't work, try \n
second, just use + to concatenate the strings
As a starter, you can not add a reaction that way, I would recommend doing this;
await message.add_reaction('👍')
As for using a valuable, you can do it using a f string:
text = "Hello!"
await ctx.send(f'{text}')

EOL while scanning string literal, Unknown Emoji

Command raised an exception: HTTP Exception: 400 Bad Request (error code: 10014): Unknown Emoji and EOL while scanning string literal are the 2 errors I have having while trying to add a reaction to an embed msg with python (discord.py)
Here is the full code, the problem is around the exclamation mark
#client.command()
async def ask(ctx, *, question=None):
try:
page = urllib.request.urlopen(f'http://askdiscord.netlify.app/b/{ctx.message.author.id}.txt')
if page.read():
embed = discord.Embed(color=0xFF5555, title="Error", description="You are banned from using AskDiscord!")
await ctx.send(embed=embed, content=None)
return
except urllib.error.HTTPError:
pass
if question:
channel = client.get_channel(780111762418565121)
embed = discord.Embed(color=0x7289DA, title=question, description=f"""
Question asked by {ctx.message.author} ({ctx.message.author.id}). If you think this question violates our rules, click ❗️ below this message to report it
""")
embed.set_footer(text=f"{ctx.message.author.id}")
message = await channel.send(content=None, embed=embed)
for emoji in ('❗️'):
await message.add_reaction(emoji)
for emoji in ('🗑'):
await message.add_reaction(emoji)
embed = discord.Embed(color=0x55FF55, title="Question asked", description="Your question has been send! You can view in the answer channel in the [AskDiscord server](https://discord.gg/KwUmPHKmwq)")
await ctx.send(content=None, embed=embed)
else:
embed = discord.Embed(title="Error", description=f"Please make sure you ask a question...", color=0xFF5555)
await ctx.send(content=None, embed=embed)
Tuple need to have a , at the end if there is only one element in it else its considered as a string in your case change ('❗️') to ('❗️',)

Resources