Ignoring exception in command buy - discord.py

An error pops up when I do the buy command. This code comes from The coding academy discord server but they didn't seem to know how to help. This is for a currency bot. Here is my code followed by the error:
`mainshop = [{"name":"Knife","price":65,"description":"Mug people! Unlocks `mug`"},
{"name":"Laptop","price":5000,"description":"Post some sweet memes on reddit! Unlocks `postmemes`"},
{"name":"Gun","price":10000,"description":"Rob people and businesses! Unlocks `rob` and `mug`"}]
#client.command()
async def shop(ctx):
em = discord.Embed(title = "Shop")
for item in mainshop:
name = item["name"]
price = item["price"]
desc = item["description"]
em.add_field(name = name, value = f"${price} | {desc}")
await ctx.send(embed = em)
#client.command()
async def buy(ctx,item,amount = 1):
await open_account(ctx.author)
res = await buy_this(ctx.author,item,amount)
if not res[0]:
if res[1]==1:
await ctx.send("That Object isn't there!")
return
if res[1]==2:
await ctx.send(f"You don't have enough money in your wallet to buy {amount} {item}")
return
await ctx.send(f"You just bought {amount} {item}")
#client.command()
async def inventory(ctx):
await open_account(ctx.author)
user = ctx.author
users = await get_bank_data()
try:
bag = users[str(user.id)]["bag"]
except:
bag = []
em = discord.Embed(title = "Inventory")
for item in bag:
name = item["item"]
amount = item["amount"]
em.add_field(name = name, value = amount)
await ctx.send(embed = em)
async def buy_this(user,item_name,amount):
item_name = item_name.lower()
name_ = None
for item in mainshop:
name = item["name"].lower()
if name == item_name:
name_ = name
price = item["price"]
break
if name_ == None:
return [False,1]
cost = price*amount
users = await get_bank_data()
bal = await update_bank(user)
if bal[0]<cost:
return [False,2]
try:
index = 0
t = None
for thing in users[str(user.id)]["bag"]:
n = thing["item"]
if n == item_name:
old_amt = thing["amount"]
new_amt = old_amt + amount
users[str(user.id)]["bag"][index]["amount"] = new_amt
t = 1
break
index+=1
if t == None:
obj = {"item":item_name , "amount" : amount}
users[str(user.id)]["bag"].append(obj)
except:
obj = {"item":item_name , "amount" : amount}
users[str(user.id)]["bag"] = [obj]
with open("mainbank.json","w") as f:
json.dump(users,f)
await update_bank(user,cost*-1,"wallet")
return [True,"Worked"]
Error:
Ignoring exception in command buy: Traceback (most recent call last): File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs) File "main.py", line 50, in buy
res = await buy_this(ctx.author,item,amount) File "main.py", line 104, in buy_this
if bal[0]<cost: TypeError: 'bool' object is not subscriptable
The above exception was the direct cause of the following exception:
Traceback (most recent call last): File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 902, in invoke
await ctx.command.invoke(ctx) File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 864, in invoke
await injected(*ctx.args, **ctx.kwargs) File "/opt/virtualenvs/python3/lib/python3.8/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: 'bool' object is not subscriptable

As much as I see your value of the variable bal is somehow a bool value due to which if you try to take out values from it as a list, it gives you the following error.
You should try checking the definition of the update_bank() command and check it's return type.
Check this website for more info on the error : https://www.tutorialexample.com/fix-typeerror-bool-object-is-not-subscriptable-in-python-python-tutorial/

Related

discord.py file append rewrite the file instead of appending

When I want to append something to a file (with the append mode), it just erases everything before writing what I would like to append.
I have an on_voice_state_update event, when triggered, it checks if the user joined a specific channel. If yes: it creates a voice channel with some permissions for the user who created the voice channel. It is also supposed to append to a file called member_channel.txt this: {member.id}:{the_member's_voice_channel.id} but instead of adding this at the end of the file, it first erases everything and then add what I want to add.
Here are the codes:
#bot.event
async def on_voice_state_update(member, before, after):
if after.channel is not None and after.channel.id == 1059553884286230608:
guild = bot.get_guild(966749409314504774)
everyone_role = discord.utils.get(guild.roles, id = 966749409314504774)
community_role = discord.utils.get(guild.roles, id = 1006304076331483256)
muted_role = discord.utils.get(guild.roles, id = 1059109986258653244)
global member_channel
member_channel = await guild.create_voice_channel(name = f"Vocal de {member.name}")
await member_channel.edit(category = discord.utils.get(get_guild().channels, id = 1057730051321372692))
await member_channel.set_permissions(member, connect = True, manage_channels = True, manage_permissions = True, priority_speaker = True, move_members = True)
await member_channel.set_permissions(everyone_role, view_channel = False)
await member_channel.set_permissions(community_role, view_channel = True)
await member_channel.set_permissions(muted_role, speak = False)
await member.move_to(member_channel)
with open("member_channel.txt", "a") as file: # THIS IS WHAT
file.write(str(member.id) + ":" + str(member_channel.id) + "\n") # IS'NT WORKING
print(f"[{await get_hour()}] {member.name} created a temporary voice channel.")
#then we want to delete the channel if it is empty and equal to a member's channel, and also delete the line in member_channel.txt corresponding to this member and channel
elif before.channel is not None and len(before.channel.members) == 0:
new_file_value = ""
try:
with open("member_channel.txt", "r") as file:
lines = file.readlines()
splited_lines = []
for line in lines:
splited_lines.append((line.split(":")))
for lines in splited_lines:
for line in lines:
line.replace("\n", "")
if str(before.channel.id) in line:
await before.channel.delete()
del splited_lines[line.index(str(before.channel.id))]
for line in splited_lines:
print(new_file_value)
new_file_value += line
for ele in line:
print(new_file_value)
new_file_value += line + ":"
with open("member_channel.txt", "w+") as file:
file.write(new_file_value)
print(f"[{await get_hour()}] I deleted the temporary voice channel {member_channel.name}.")
file.close()
file.close()
except NameError:
return

Manually picking users from reaction roles

I have a command which allows people to react to a message to enter into a "battle". Then with another command, 2 people are chosen. This is my code:
#client.command(aliases=['start', 'g'])
async def startbattle(ctx):
msg = await ctx.send("React to enter battle")
await msg.add_reaction("🎉")
await asyncio.sleep(10000000000000000)
message = await ctx.fetch_message(msg.id)
for reaction in message.reactions:
if str(reaction.emoji) == "🎉":
users = await reaction.users().flatten()
if len(users) == 1:
return await msg.edit(embed=discord.Embed(title="Nobody has won the giveaway."))
try:
user1 = random.choice(users)
user2 = random.choice(users)
except ValueError:
return await ctx.send("not enough participants")
await ctx.send(f'Battle will be against {user1} and {user2}')
#client.command()
async def pick(ctx):
async for message in ctx.channel.history(limit=100, oldest_first=False):
if message.author.id == client.user.id and message.embeds:
reroll = await ctx.fetch_message(message.id)
users = await reroll.reactions[0].users().flatten()
users.pop(users.index(client.user))
winner1 = random.choice(users)
winner2 = random.choice(users)
await ctx.send(f"The battle will be against {winner1.mention} and {winner2.mention}")
break
else:
await ctx.send("No giveaways going on in this channel.")
This is the error which I get while using the "pick" command,
users = await reroll.reactions[0].users().flatten()
IndexError: list index out of range
the error is in the for loop as it gets the msg and the msg doesnt have any reaction so it there is no list so list is out of range to fix this u have to add try and except there so it skips the msg with no reactions.
code :
#client.command()
async def pick(ctx):
async for message in ctx.channel.history(limit=100, oldest_first=False):
if message.author.id == client.user.id and message.embeds:
reroll = await ctx.fetch_message(message.id)
try:
users = await reroll.reactions[0].users().flatten()
except:
break
users.pop(users.index(client.user))
winner1 = random.choice(users)
winner2 = random.choice(users)
await ctx.send(f"The battle will be against {winner1.mention} and {winner2.mention}")
return # <--- was the break
else:
await ctx.send("No giveaways going on in this channel.")
and a suggestion dont add break in the if statement as it will continuously check for msg if already it got one

Discord.py How to make a if this fail function

Hi I have following code
#commands.command(name="playing", aliases=["np"])
async def playing_command(self, ctx, name: t.Optional[str]):
player = self.get_player(ctx)
name = name or player.queue.current_track.title
async with ctx.typing():
async with aiohttp.request("GET", LYRICS_URL + name, headers={}) as r:
#if not 200 <= r.status <= 299:
#raise NoLyricsFound
data = await r.json()
if not player.is_playing:
raise PlayerIsAlreadyPaused
embed = discord.Embed(
title="Wird gespielt",
colour=ctx.author.colour,
timestamp=dt.datetime.utcnow(),
)
embed.set_thumbnail(url=data["thumbnail"]["genius"])
embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.avatar_url)
embed.add_field(name="Track title", value=player.queue.current_track.title, inline=False)
embed.add_field(name="Artist", value=player.queue.current_track.author, inline=False)
position = divmod(player.position, 60000)
length = divmod(player.queue.current_track.length, 60000)
embed.add_field(
name="Position",
value=f"{int(position[0])}:{round(position[1]/1000):02}/{int(length[0])}:{round(length[1]/1000):02}",
inline=False
)
await ctx.send(embed=embed)
But when I run this and the bot cant find a Thumbnail I get the key Error 'thumbnail'
So I tried this
#playing_command.error
async def playing_command(self, ctx, name: t.Optional[str]):
player = self.get_player(ctx)
name = name or player.queue.current_track.title
async with ctx.typing():
async with aiohttp.request("GET", LYRICS_URL + name, headers={}) as r:
#if not 200 <= r.status <= 299:
#raise NoLyricsFound
data = await r.json()
if not player.is_playing:
raise PlayerIsAlreadyPaused
embed = discord.Embed(
title="Wird gespielt",
colour=ctx.author.colour,
timestamp=dt.datetime.utcnow(),
)
embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.avatar_url)
embed.add_field(name="Track title", value=player.queue.current_track.title, inline=False)
embed.add_field(name="Artist", value=player.queue.current_track.author, inline=False)
position = divmod(player.position, 60000)
length = divmod(player.queue.current_track.length, 60000)
embed.add_field(
name="Position",
value=f"{int(position[0])}:{round(position[1]/1000):02}/{int(length[0])}:{round(length[1]/1000):02}",
inline=False
)
await ctx.send(embed=embed)
But with this I get errors like
_ClientEventTask exception was never retrieved
future: <ClientEventTask state=finished event=on_message coro=<bound method MusicBot.on_message of <bot.bot.MusicBot object at 0x0000022FEF05E6A0>> exception=CommandInvokeError('Command raised an exception: TypeError: can only concatenate str (not "CommandInvokeError") to str')>
Traceback (most recent call last):
File "C:\Users\user\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\user\Desktop\Neuer Ordner\MusicBot\bot\cogs\music.py", line 637, in playing_command
embed.set_thumbnail(url=data["thumbnail"]["genius"])
KeyError: 'thumbnail'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\user\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\user\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\user\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: KeyError: 'thumbnail'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 71, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\user\Desktop\Neuer Ordner\MusicBot\bot\cogs\music.py", line 658, in error_command
async with aiohttp.request("GET", LYRICS_URL + name, headers={}) as r:
TypeError: can only concatenate str (not "CommandInvokeError") to str
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 348, in _run_event
await self.on_error(event_name, *args, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:\Users\user\Desktop\Neuer Ordner\MusicBot\bot\bot.py", line 68, in on_message
await self.process_commands(msg)
File "C:\Users\user\Desktop\Neuer Ordner\MusicBot\bot\bot.py", line 64, in process_commands
await self.invoke(ctx)
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 943, in invoke
await ctx.command.dispatch_error(ctx, exc)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 422, in dispatch_error
await injected(cog, ctx, error)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 77, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: can only concatenate str (not "CommandInvokeError") to str
How to fix this
I just want when the thumbnail function fails that the bot send a embed without thumbnail
To check if a key exists in a dict you can use the in operator.
>>> "key" in {"key": "value"}
True
So just put an if around the set_thumbnail line.
if "thumbnail" in data and "genius" in data["thumbnail"]:
embed.set_thumbnail(url=data["thumbnail"]["genius"])
If the if's condition is False it won't run set_thumbnail so it won't add one, like you wanted.

Word limit in an embed description

I want to make that when the description of the embed exceeds the word limit it continues in another separate embed but that the previous embed ends with 3 dots (...) eliminating a small part of the message and following it in the other embed, at the moment this is the code I have:
#commands.command(aliases=["pj"])
async def personaje(self, ctx, personaje=None, member: discord.Member=None):
if personaje is None:
await ctx.send(":x: Debes proporcionar la id del personaje que quieres visualizar")
else:
if member is None:
member = ctx.author
if os.path.exists("json/Roleplay/Personajes/{member}/{idpersonaje}.json".format(member=member.id, idpersonaje=personaje)):
with open("json/Roleplay/Personajes/{member}/{idpersonaje}.json".format(member=member.id, idpersonaje=personaje), 'r') as f:
data = json.load(f)
Nombre = data["Nombre"]
Historia = data["Historia"]
color = data["Color"]
personalizado = data["Personalizado"]
text = ""
text = "".join(f"\n**{key}:** {value}" for key, value in personalizado.items())
color = int(color, 16)
timestamp = datetime.datetime.now()
prueba = f"**{Nombre} {text}\n\n**Historia:**\n {Historia}"
if len(prueba) < 2000:
embed=discord.Embed(description=prueba, color=color)
embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
embed.timestamp = timestamp
await ctx.send(embed=embed)
else:
embed=discord.Embed(description=prueba[:-3] + "...", color=color)
embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
embed.timestamp = timestamp
await ctx.send(embed=embed)
else:
await ctx.send(":x: Este personaje no existe")
return
Example of what I want to do (obviously with a longer text that exceeds 2000 words):
https://imgur.com/zytqLKm
Best method is making a function to split the data every n char.
Making fields with name of empty line might be better then using new embed.
Keep in mind don't split at 2000 exactly because you have ...
def split_length(data: str, n: int):
'''Splits the data given at each given n'''
out_data = []
for i in range(0, len(data), n):
out_data.append(data[i:i+n])
return out_data
#bot.command()
async def longtext(ctx):
embed = discord.Embed(title='Example of long text split')
long_text = 'qwerty'
field_values = split_length(data=long_text, n=2)
for value in field_values:
# "\u200b" is just an empty line
embed.add_field(name="\u200b", value=f"{value} ...", inline=True)
await ctx.send(embed=embed)

I am trying to make a rank card using PIL and discord.py UPDATED

i have a leveling system, using discord.py, i am trying to make a rank card, like mee6 and arcane. i wanna get the image to display the users rank and xp
heres the command that works, but i want to make it into a image.
#bot.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']
embed = discord.Embed(title = 'Level {}'.format(lvl), description = f"{exp} 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']
embed = discord.Embed(title = 'Level {}'.format(lvl), description = f"{exp} XP" ,color = discord.Color.green())
embed.set_author(name = member, icon_url = member.avatar_url)
await ctx.send(embed = embed)
and heres my crappy atempt.
#bot.command()
async def text(ctx):
text = [f"level {lvl}, exp {exp}"]
user = ctx.message.author
img = Image.open("rank.jpg")
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']
text = ['Level {}'.format(lvl)]
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("font.ttf", 150)
draw.text((480,445), text, (0, 0, 0,), font=font)
img.save("rankcard.jpg")
await ctx.send(file = discord.File("rankcard.jpg"))
and heres the console error, i doubt theres only one error with my code
Ignoring exception in command text:
Traceback (most recent call last):
File "C:\Users\Jack\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\Jack\Desktop\just some code\bot.py", line 33, in text
text = [f"level {lvl}, exp {exp}"]
UnboundLocalError: local variable 'lvl' referenced before assignment
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Jack\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 902, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Jack\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 864, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Jack\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: UnboundLocalError: local variable 'lvl' referenced before assignment
if you could fix up the code for me. i would be ever so greatful.
-thanks
UPDATE: i have now sorted those issues out but still trying to figure this out, my code:
#bot.command()
async def test(ctx,member: discord.Member = None):
global lvl, exp
if not member:
user = ctx.message.author
with open('level.json','r') as f:
users = json.load(f)
img = Image.open("rank.jpg")
lvl = users[str(ctx.guild.id)][str(user.id)]['level']
exp = users[str(ctx.guild.id)][str(user.id)]['experience']
text = [f"level {lvl}, exp {exp}"]
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("font.ttf", 150)
draw.text((480,445), text, (0, 0, 0,), font=font)
img.save("rankcard.jpg")
await ctx.send(file = discord.File("rankcard.jpg"))
and my error:
Traceback (most recent call last):
File "C:\Users\Jack\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 902, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Jack\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 864, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Jack\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: TypeError: expected string
You have to firstly define lvl and exp in the text function or global it as this is not found.
#bot.command()
async def text(ctx):
lvl = ...
exp = ...
text = [f"level {lvl}, exp {exp}"]
user = ctx.message.author
OR
#bot.command(aliases = ['rank','lvl'])
async def level(ctx,member: discord.Member = None):
global lvl, exp
if not member:
user = ctx.message.author
with open('level.json','r') as f:

Resources