How to fix JSONDecoder error in discord.py - python

So I am trying to create a code that bans a member for banning a member without being whitelisted, here is the code.
#client.event
async def on_member_ban(guild, user):
with open('whitelisted.json') as f:
whitelisted = json.load(f)
async for banner in guild.audit_logs(limit=1, action=discord.AuditLogAction.ban):
if str(banner.user.id) in whitelisted[str(guild.id)]:
return
await guild.ban(banner.user, reason="Banning too many members")
return
The error occurs on this line
whitelisted = json.load(f)
The code worked perfectly fine without the json part but I need it since if someone is whitelisted then I don't want them to get banned.
Here is the exact error message "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)"

The json file was empty so all I had to do was put the "{}" in the file.

Related

'NoneType' object has no attribute 'send' even though it should work

For some reason, I keep getting this error message, I can't understand it because everything I've seen online seems like my code should be working:
import discord #imports packages
import random
client = discord.Client(intents=discord.Intents.default())
def get_quote():
x = 0
f = open(r"C:\Users\natem\OneDrive\Documents\phil_quotes.txt", "r")
content = f.readlines()
for line in f:
x += 1
quote = (content[random.randint(0,x)])
f.close
return quote
#client.event
async def on_ready():
jeneral_channel = client.get_channel(Channel ID)
gospel = get_quote()
await jeneral_channel.send(message)
client.run("TOKEN")
What's happening is jeneral_channel = client.get_channel(...) is resulting in jeneral_channel being a None object because client.get_channel is returning nothing - aka a None object.
Which means this is a problem with your attempt to get the channel not being properly functioning, meaning you're either doing it wrong or your access for your client doesn't have access to the channel ID/channel/information.
I would re-consult the API for the Discord library you are using, make sure you set up your user authentication and application authentication (bot auth!) properly, the bot/client in question is joined to your Discord server and channel properly, and that you've actually provided proper credentials and a proper ChannelID value for the system that your client has access to in your code.
(this was previously a comment but I've made it an answer now)

How can I send a message to a user out of a JSON file?

Probably a very easy question to answer, but I want to send a message to a user after a certain time. For this I read his ID from a JSON. Problem with this? You cannot append a send to a str or this error is then spit out.
I have already tried to convert the whole thing, but without success. Can someone give me a hint here?
The code:
#commands.Cog.listener()
async def on_ready(self):
period = 10 # 86400.0
while 3:
with open('work_data/statues.json') as j:
u_data = json.load(j)
for user in list(u_data.keys()): # read user, ID comes out if you do print(user)
if dt.datetime.now().timestamp() - u_data[user][0]['last_seen'] >= period:
await user.send(f"{user}, you haven't shown up at work for 24 hours and have been fired.") # part that doesn't work
await asyncio.sleep(2)
u_data.pop(user)
write_json(u_data)
await asyncio.sleep(0.1)
The JSON:
{
"30288509151923XXXX": [ # Last 4 numbers removed because privacy.
{
# rest not relevant
}
]
}
The error message:
Ignoring exception in on_ready
Traceback (most recent call last):
File "C:\Users\Mike\PycharmProjects\MikeBot\venv\lib\site-packages\disnake\client.py", line 505, in _run_event
await coro(*args, **kwargs)
File "C:\Users\Mike\PycharmProjects\MikeBot\cogs\work.py", line 308, in on_ready
await user.send(f"{user}, you haven't shown up at work for 24 hours and have been fired.")
AttributeError: 'str' object has no attribute 'send'
It looks like you are using disnake instead of discord.py.
You can have a look at their docs. Here we learn something about fetch_user, get_user or getch_user which will first check the cache and then fetch the user if needed.
In your example, you can use the following:
await self.bot.getch_user(user) # asynchronous, needs to be awaited
I think its because you can’t send a message to a number it needs to be sent to a user.
Instead of:
await user.send(f"{user}, you haven't shown up at work for 24 hours and have been fired.")
Try:
_user = await self.client.fetch_user(int(user))
await _user.send(f"{user}, you haven't shown up at work for 24 hours and have been fired.")
user_object = await bot.fetch_user(<id>)
await user_object.send(<message>)
should work in your case!

Member voice state return value problem in discordpy

For a simple example, I prepared the following code. Although there is no missing permission of the bot, when I query it using "fetch_member" it return None, I don't know how to fix this problem please help.
#client.command()
async def test(ctx):
a = await client.fetch_guild(ctx.guild.id)
b = await a.fetch_member(ctx.author.id)
print(b.voice) #return value is None
print(ctx.author.voice) #return value is VoiceStateObject
This is not discord.py specific issue as the data is just not provided by the Discord API. To avoid this just use ctx.author.voice or use get_guild instead of fetch_guild
Here's a screenshot of the docs for Guild.fetch_guild:

discord.py retrieving data from json file not responding

Sorry for the unclear question title. I don't know any other way to put it.
I made a command that says p!channel [channel_id] which basically makes a channel where my bot will respond with "e". I want the command to store the channel_id and guild_id into a json file called channel.json, and when a user sends a message, it will check if the message is in the channel_id channel, and if it is in the channel, will send "e". However, it's not responding and no error codes are showing up. Can someone help? Code is below:
def get_channel(client,message):
with open("channel.json", "r") as f:
e = json.load(f)
return e[str(message.guild.id)]
#client.command()
#commands.has_permissions()
async def channel(ctx, *, channelid):
with open("channel.json", "r") as f:
e = json.load(f)
e[str(ctx.guild.id)] = channelid
with open("channel.json", "w") as f:
json.dump(e,f)
await ctx.send(f"Successfully setup <#{channelid}>")
#client.event
async def on_message(message):
if message.channel.id == get_channel:
await message.channel.send('e')
There are several immediate problems that are keeping this from functioning.
You're only referencing get_channel, not calling it. The channel's ID isn't equal to the function itself, so the message is never sent. You want get_channel(client, message).
Your on_message event ensures that your command never gets called.
You attempt to use ctx.send() instead of ctx.channel.send().
Channel IDs are integers, but command arguments are always read in as strings. Without converting the argument to an integer, comparing it against a channel's ID will always return False.
In addition, there are several things you could improve:
The get_channel function doesn't ever use client, so you could alter your function definition to simply get_channel(message).
Furthermore, channel IDs are globally unique, so you don't need to save the guild ID in order to unambiguously identify a channel.
It would be more efficient not to read the whole file every time you need to check for an ID.
The has_permissions check doesn't check anything if you supply it no arguments, so in your code it does nothing.
You probably don't want your bot to respond to its own messages.
Here's an improved version that reads a saved file on startup, if one exists. It then keeps the IDs as a set in memory, and only opens the file when it needs to add a new ID.
from discord.ext import commands
import json
client = commands.Bot(command_prefix='p!')
try:
with open('channels.json') as f:
client.ids = set(json.load(f))
print("Loaded channels file")
except FileNotFoundError:
client.ids = set()
print("No channels file found")
#client.command()
async def channel(ctx, channel_id):
try:
channel_id = int(channel_id)
except ValueError:
await ctx.channel.send("Channel must be all digits")
return
if channel_id in client.ids:
await ctx.channel.send(f"Channel <#{channel_id}> is already set up.")
return
client.ids.add(channel_id)
with open('channels.json', 'w') as f:
json.dump(list(client.ids), f)
await ctx.channel.send(f"Successfully set up <#{channel_id}>")
#client.event
async def on_message(message):
if message.channel.id in client.ids and message.author != client.user:
await message.channel.send('e')
# Pass processing on to the bot's command(s)
await client.process_commands(message)
client.run(TOKEN)

can any one tell me what is missing in my code please, i cant use the discord user name

I want the user to start with 40 points, but if he already started just send how many points he has.
The error that im currently geting is: message is a required argument that is missing.
But i dont know what is missing.
async def money(self, ctx, message):
user = message.author
read = open(user, 'a').close()
if os.stat(user).st_size == 0:
moneyfile=open(user, 'w')
moneyfile.write('40')
moneyfile.close()
else:
readfile = open(user, 'r').read()
points=readfile
int(points)
await ctx.send(points)
The error reads itself, you are doing the command but not entering a message param. To fix this, delete the message param and set user in the 2nd line to ctx.author.

Categories

Resources