Cannot add/append element to JSON File - python

So, I was making a discord bot for an RP server with 4k members in emergency.
My goal was to store the lawyers database in a json file that would be hosted on one of my computers for testing. Here is my code:
import discord
import datetime
from typing_extensions import IntVar
from discord import member
from discord.embeds import Embed
import json
from discord.ext import commands
from discord.colour import Color
import asyncio
#Vars
lawyersdict = {}
prefix = "<"
client = commands.Bot(command_prefix=prefix)
#Misc Stuff
client.remove_command("help")
#Embeds-
#RegEmbed
regembed = discord.Embed (
colour = discord.colour.Color.from_rgb(64, 255, 0),
title = 'Success',
description = 'Successfully registered you in the database as a lawyer!'
)
regembed.set_author(name='GVRP. Co',
icon_url='https://cdn.discordapp.com/avatars/921176863156609094/51441aaab15838c9a76c0488fd4ee281.webp?size=80')
regembed.timestamp = datetime.datetime.utcnow()
#Invalid
factembed = discord.Embed (
colour = discord.colour.Color.from_rgb(255, 64, 0),
title = 'Uh oh',
description = 'Seems like an error occured! Please try again.'
)
factembed.set_author(name='UselessFacts',
icon_url='https://cdn.discordapp.com/avatars/921176863156609094/51441aaab15838c9a76c0488fd4ee281.webp?size=80')
factembed.timestamp = datetime.datetime.utcnow()
#CMDS-
#Register Command
#client.command(aliases=['reg'])
async def register(ctx):
if ctx.author == client.user:
return
else:
if isinstance(ctx.channel, discord.channel.DMChannel):
await ctx.send("Sorry, you cannot use this command in a DM for security reasons.")
else:
channel = await ctx.author.create_dm()
def check(m):
return m.content is not None and m.channel == channel
await channel.send(f"Hello {ctx.author.mention}! Please tell a little bit about yourself! You have 5 minutes. (To cancel the command, type 'cancel')")
await asyncio.sleep(0.3)
descmsg = await client.wait_for('message', check=check, timeout=300)
if descmsg.content == "cancel":
await channel.send(f"Cancelled command!")
else:
await channel.send(f"Almost there! You just need to enter the hiring price! You have 2 minutes. (between 450$ & 50,000$)")
await asyncio.sleep(0.3)
pricemsg = await client.wait_for('message', check=check, timeout=180)
if any(c.isalpha() for c in pricemsg.content):
if any(c.isalpha() for c in pricemsg.content):
await channel.send("Oops, you didnt typed a number! Make sure you didnt typed it without a coma! Please re-send the command.")
else:
def PrcCheck(num: int):
if num <= 50000 and num >= 450:
return True
else:
return False
if PrcCheck(int(pricemsg.content)):
desc = {
f"{str(ctx.author.id)}" : {
"Description" : f"{descmsg.content}",
"Price" : int(pricemsg.content),
"IsActive" : "true"
}
}
jsonobj = json.dumps(desc, indent=4, sort_keys= True)
with open('lawyers.json', mode='w') as outfile:
obj = json.load(json.dump(lawyersdict, outfile))
obj.append(desc)
obj.write(jsonobj, outfile)
await channel.send(embed=regembed)
else:
await channel.send(f"The price you entered is too low or too high! Price entered: ``{pricemsg.content}``. Please re-send the command.")
#client.event
async def on_ready():
print(f"Ready! Logged in as {client.user}")
client.run("Bot Token")
Here is the Compiler Error (Python 3.9):
Ignoring exception in command register:
Traceback (most recent call last):
File "C:\Users\theli\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "c:\Users\theli\OneDrive\Bureau\Discord Bots\GVRP. Co UtilBot\launcher.py", line 82, in register
obj = json.load(json.dump(lawyersdict, outfile))
File "C:\Users\theli\AppData\Local\Programs\Python\Python39\lib\json\__init__.py", line 293, in load
return loads(fp.read(),
AttributeError: 'NoneType' object has no attribute 'read'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\theli\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\theli\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\theli\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'read'
I tried to look at other posts to see if there was a solution. But it was a post from 2015 which didn't solve my problem.
My goal here was to append details about the Discord User who entered the info and has entered my command to register.
Thank you for reading this post

obj = json.load(json.dump(lawyersdict, outfile))
You're using the result of json.dump() as the argument to json.load().
But json.dump() doesn't return anything. So you're effectively calling json.load(None).

As John Gordon said above dump return None therefore you cant load it .
To continue your comment, then yes json.load(outfile) is what you need to do but only later.
the file is open for w (write) and its currently an open file, so you can do it right away but after the with statement, by creating another io open call using the with context or with just an open.

Related

Discord bot cannot fetch channel

I am trying to code a bot that will simultaneously print new messages in a server to console and for the user to be able to send messages to the server at the same time.
import discord
from asyncio import run
from threading import Thread
intents = discord.Intents.all()
intents.members = True
client = discord.Client(intents=intents)
async def p():
ap = await client.fetch_channel(1234567890)
return ap
main_guild = run(p())
def log_msg(msge,date):
with open('log.txt','a') as f:
f.write(msge + '\n' + date)
f.close()
async def send_a_message():
while True:
await main_guild.send(input('Send message: '))
#client.event
async def on_message(message):
base_msg = str(message.author)+': '+str(message.channel.name)+': '+str(message.content)
date = str(message.created_at)
if len(message.attachments) == 0:
print(base_msg)
log_msg(base_msg,date)
return
for i in range(len(message.attachments)):
base_msg += '\n'+(message.attachments[i]).url
log_msg(base_msg,date)
t = Thread(target=lambda:run(send_a_message()))
t.start()
try:
client.run('#######################')
except discord.errors.HTTPException:
from os import system
system('kill 1')
However, I get a strange error:
Traceback (most recent call last):
File "main.py", line 13, in <module>
main_guild = run(p())
File "/nix/store/hd4cc9rh83j291r5539hkf6qd8lgiikb-python3-3.10.8/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/nix/store/hd4cc9rh83j291r5539hkf6qd8lgiikb-python3-3.10.8/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
return future.result()
File "main.py", line 10, in p
ap = await client.fetch_channel(999141783709679668)
File "/home/runner/RandomRepl/venv/lib/python3.10/site-packages/discord/client.py", line 1824, in fetch_channel
data = await self.http.get_channel(channel_id)
File "/home/runner/RandomRepl/venv/lib/python3.10/site-packages/discord/http.py", line 604, in request
if not self._global_over.is_set():
AttributeError: '_MissingSentinel' object has no attribute 'is_set'
What is causing this and how do I fix this?
Thank you.
To get the channel you are using the client. But you are trying to get the channel before actually running the client, so you can't get the channel.
You have to first run the client and then get the channel. A possibility would be to use the on_ready event (called after client.run('...')) to get the channel.
Here is an example code you can start working with:
import discord
client = discord.Client(intents=discord.Intents.all())
main_guild = None
#client.event
async def on_ready():
global main_guild
await client.wait_until_ready()
main_guild = client.get_channel(1234567890)
print('Connected')
#client.event
async def on_message(message):
if message.author.id == client.user.id: return
if message.channel.type == discord.ChannelType.private: channel = 'DM'
else: channel = message.channel.name
base_msg = f'{message.author}: {channel}: {message.content}'
await main_guild.send(base_msg)
client.run('#######################')

Getting user input with Discord bot outside of a command or event

I am trying to get input from a discord server to create a list of numbers. Since I will be getting a list of numbers as input for multiple different commands, I wanted to see if it was possible to make a helper function and get input through that.
However, I ran into some problems:
-When solely passing the Context object as argument to the function, then calling the bot's wait_for() method, the following warning is outputted:
Ignoring exception in command a_q_d:
Traceback (most recent call last):
File "C:\Users\name\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "c:\Users\name\OneDrive\Documents\Programming\Python Projects\Databot\quantitative_commands.py", line 11, in a_q_d
q3, q1 = np.percentile(lst, [75,25])
File "<__array_function__ internals>", line 6, in percentile
File "C:\Users\name\anaconda3\lib\site-packages\numpy\lib\function_base.py", line 3706, in percentile
a, q, axis, out, overwrite_input, interpolation, keepdims)
File "C:\Users\name\anaconda3\lib\site-packages\numpy\lib\function_base.py", line 3826, in _quantile_unchecked
interpolation=interpolation)
File "C:\Users\name\anaconda3\lib\site-packages\numpy\lib\function_base.py", line 3403, in _ureduce
r = func(a, **kwargs)
File "C:\Users\name\anaconda3\lib\site-packages\numpy\lib\function_base.py", line 3941, in _quantile_ureduce_func
x1 = take(ap, indices_below, axis=axis) * weights_below
TypeError: unsupported operand type(s) for *: 'coroutine' and 'float'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\name\anaconda3\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\name\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\name\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: unsupported operand type(s) for *: 'coroutine' and 'float'C:\Users\name\anaconda3\lib\asyncio\events.py:88: RuntimeWarning: coroutine 'data_list_quantitative' was never awaited
self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
-I also tried passing in the Bot object as argument, however, the same error as above was returned.
Here is the code from my main file:
from discord.ext import commands
import builtins
bot = commands.Bot("/", case_insensitive = True)
builtins.bot = bot
#Command Imports
import quantitative_commands
import combinatorics_commands
import generic_commands
#Events
#bot.event
async def on_ready():
print("Logged in as {}.".format(bot))
bot.run("Token")
And here is the code from the functions I am testing:
#bot.command(pass_context = True)
async def a_q_d(ctx):
lst = data_list_quantitative(ctx)
q3, q1 = np.percentile(lst, [75,25])
iqr = q3-q1
await ctx.send("Minimum value: "+str(min(lst)))
await ctx.send("Maximum value: "+str(max(lst)))
await ctx.send("Range: "+str(max(lst)-min(lst)))
await ctx.send("Mean: "+str(statistics.mean(lst)))
await ctx.send("Median: "+str(statistics.median(lst)))
await ctx.send("Variance (sample): "+str(statistics.variance(lst)))
await ctx.send("Variance (population): "+str(statistics.pvariance(lst)))
await ctx.send("Standard deviation (sample): "+str(statistics.stdev(lst)))
await ctx.send("Standard deviation (population): "+str(statistics.pstdev(lst)))
await ctx.send("Interquartile range (IQR): "+str(iqr))
async def data_list_quantitative(ctx) -> list:
"""Creates a 1-dimensional list of quantitative data
to be used for analysis.
"""
lst = []
await ctx.send("Enter values (type 'done' when finished): ")
while True:
try:
item = await bot.wait_for("message", check = lambda m : m.author == ctx.author, timeout=30)
if item.content == "done": return lst
try:
lst.append(float(item.content))
except ValueError:
print("Invalid input! Must be a number.")
continue
except asyncio.TimeoutError:
await ctx.send("Sorry, you took too long to give an input!")
Thanks in advance for any help!
You need to await it. Otherwise, you'll get the coroutine object, rather than what you wanted, the return value of the function:
#bot.command(pass_context = True)
async def a_q_d(ctx):
lst = await data_list_quantitative(ctx)
q3, q1 = np.percentile(lst, [75,25])
However, be aware that from the code you gave, that will return None. You need some kind of return lst at the end.
You can do it with add parameters in your function. For example:
#bot.command(pass_context = True)
async def a_q_d(ctx,num1:int, string1:str):
"""
your code here
"""
so your command will be seem like this:
/a_q_d 1 hello
or you can try to catch messages with "on_message" event
A part from these, maybe there is no way to do this.

Raise MissingRequiredArgument(param) discord.ext.commands.errors.MissingRequiredArgument: cooldown is a required argument that is missing

I keep getting this error:
Ignoring exception in on_command_error
Traceback (most recent call last):
File "/usr/local/lib/python3.8/dist-packages/discord/client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "bot.py", line 191, in on_command_error
raise error
File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 855, in invoke
await self.prepare(ctx)
File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 789, in prepare
await self._parse_arguments(ctx)
File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 697, in _parse_arguments
transformed = await self.transform(ctx, param)
File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 542, in transform
raise MissingRequiredArgument(param)
discord.ext.commands.errors.MissingRequiredArgument: cooldown is a required argument that is missing.
Please help me its saying that here is my code
import discord
import json
import requests
import time
from discord.ext import commands
from discord.ext.commands import cooldown
from datetime import datetime, timedelta
on_cooldown = {}
client = commands.Bot(command_prefix = "!")
client.remove_command("help")
async def get_user_data():
with open("account.json","r") as f:
users = json.load(f)
return users
#client.event
async def on_ready():
print("Bot is ready")
print('Connected to bot: {}'.format(client.user.name))
print('Bot ID: {}'.format(client.user.id))
await client.change_presence(activity=discord.Game(name="Dwayne is protecting" + str(len(client.guilds)) + "Eggplants ", type=0))
#help command
#client.command(pass_context=True, aliases=['Help'])
async def help(ctx):
embed=discord.Embed(title="Help", description='Bot prefix = ?', color=0x7a0000)
embed.add_field(name="Spammers", value="!post <number> <message> <quantity>\n!plan", inline=True)
embed.add_field(name="Admin", value="!createa <User ID> <ExpDate> <cooldown> (Y-M-D)\n!bana <User ID> <Reason+Reason>\n?purge <amount>\n!ban <user> <reason>\n!unban <user>", inline=False)
embed.set_footer(text="Dwayne Bot")
await ctx.send(embed=embed)
#client.command()
async def post(ctx, To, message, amount):
users = await get_user_data()
if str(ctx.author.id) in users:
if users[str(ctx.author.id)]['Banned'] == 'N':
timeleft = datetime.strptime(users[str(ctx.author.id)]['expDate'],'%Y-%m-%d') - datetime.now()
if timeleft.days <= 0:
em = discord.Embed(color=0x7a0000, description="Sorry your plan on this tool has expired")
await ctx.send(embed=em)
else:
move_cooldown = users[str(ctx.author.id)]["cooldown"]
try:
last_move = datetime.now() - on_cooldown[ctx.author.id]
except KeyError:
last_move = None
on_cooldown[ctx.author.id] = datetime.now()
if last_move is None or last_move.seconds > move_cooldown:
on_cooldown[ctx.author.id] = datetime.now()
message = message.replace('+',' ')
requests.get(f'http://45.61.54.145/api.php?key=CRzQHsKuHpF3x2M9GFrR&to={To}&message={message}&amount={amount}')
await ctx.send('Check Messages')
await ctx.message.delete()
author = ctx.message.author
test_e = discord.Embed(colour = discord.Colour.from_rgb(166, 245, 255))
test_e.set_author(name="Hello thank you for using our spammer!")
test_e.add_field(name="Request", value="Your request to spam this number has been successful!", inline=False)
test_e.add_field(name="Refresh", value="You may use this command again in 5 minutes this is to keep our spammer less laggy!")
await author.send(embed=test_e)
else:
embed = discord.Embed(color=0x7a0000, description="You're Cooldown Is Still Active!")
await ctx.send(embed=embed)
else:
embed=discord.Embed(title=f"{ctx.author.name}", color=0x7a0000)
embed.add_field(name="User Banned", value=f"Banned: Yes\nBannedOn: {users[str(ctx.author.id)]['BannedOn']}\nBannedBy: {users[str(ctx.author.id)]['BannedBy']}\nBannedReason: {users[str(ctx.author.id)]['BannedReason']}")
embed.set_footer(text="madeby: toxic")
await ctx.send(embed=embed)
else:
embed = discord.Embed(color=0x7a0000, description=f"Sorry you don't have a plan on this tool")
await ctx.send(embed=embed)
In discord.py rewrite (above version v1.0+) pass_context has been removed from commands.
https://discordpy.readthedocs.io/en/stable/migrating.html#context-changes
Try removing that from the help command.

How to solve floodwait error await result

[12:36:26] Joining #acharaexchange...
ERROR:telethon.client.updates:Unhandled exception on join_start
Traceback (most recent call last):
File "/storage/emulated/0/yul/msg2/telethon/client/updates.py", line 284, in _dispatch_update
await callback(event)
File "join.py", line 83, in join_start
await client(JoinChannelRequest(channel_name))
File "/storage/emulated/0/yul/msg2/telethon/client/users.py", line 48, in __call__
result = await future
telethon.errors.rpcerrorlist.FloodWaitError: A wait of 205 seconds is required
Anyone can help me how to solve it i want to make this if that case appeared , how to make it being restart or make time sleep and continue automatically
My script like this
Join the channel
#client.on(events.NewMessage(chats=dogeclick_channel, incoming=True))
async def join_start(event):
message = event.raw_text
if 'You must join' in message:
channel_name = re.search(r'You must join #(.*?) to earn', message).group(1)
print_msg_time(f'Joining #{channel_name}...')
# joining
await client(JoinChannelRequest(channel_name))
print_msg_time(f'Verifying...')
try this
async def join_start(event):
if True :
try:
message = event.raw_text
if 'You must join' in message:
channel_name = re.search(r'You must join #(.*?) to earn', message).group(1)
print_msg_time(f'Joining #{channel_name}...')
hidden = random. randrange(20, 45)
print_msg_time('Sending /join command')
time.sleep(hidden)
await client(JoinChannelRequest(channel_name))
# Join the channel
print_msg_time(f'Verifying...')
# Clicks the joined
await client(GetBotCallbackAnswerRequest(
peer=url_channel,
msg_id=event.message.id,
data=event.message.reply_markup.rows[0].buttons[1].data
))
except errors.FloodWaitError as e:
print('Flood wait for ', e.seconds)
exit

Mention Author Python Bot

I need to make tag author in this line This is your random {} pick,
token = "xxxxxxxxxxxxxxxxxxxxxxxx"
prefix = "?"
import discord
from discord.ext import commands
from discord.ext.commands import Bot
import random
bot = commands.Bot(command_prefix=prefix)
bot.remove_command("help")
#bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('------')
answers = ["apple", "ball", "cat", "dog", "elephant", "frog", "gun"]
#bot.command()
async def choose(k : int):
"""Chooses between multiple choices."""
if 0 <= k <= 10:
await bot.say("This is your random {} pick, {}".format(k, ctx.message.author.mention))
embed = discord.Embed(description='\n'.join(random.choices(answers, k=k)))
await bot.say(embed=embed)
else:
await bot.say("Invalid number")
bot.run(token)
getting error like this while command used.
Ignoring exception in command choose
Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 50, in wrapped
ret = yield from coro(*args, **kwargs)
File "E:\Test.py", line 25, in choose
await bot.say("This is your random {} pick, {}".format(k, ctx.message.author.mention))
NameError: name 'ctx' is not defined
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 846, in process_commands
yield from command.invoke(ctx)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 374, in invoke
yield from injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 54, in wrapped
raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: NameError: name 'ctx' is not defined
Python identifiers can't begin with a number. What you can do is specify the name of the command to be something other than the name of the coroutine.
#bot.command(pass_context=True)
async def choose(ctx, k: int):
"""Chooses between multiple choices."""
if 0 <= k <= 10:
await bot.say("This is your random {} pick, {}".format(k, ctx.message.author.mention))
embed = discord.Embed(description='\n'.join(random.choices(answers, k=k)))
await bot.say(embed=embed)
else:
await bot.say("Invalid number")
Well this is easy!
async def (ctx,k : int):
Just add ctx and you're done!
Also
bot.say
Will give you error instead use
ctx.send

Categories

Resources