How to display the title of the song in the embed? - python

Here's my code (The bot answers are in Spanish)
I was trying to put the self.info['title'] in the embed description but it was an error that said 'music_cog' object has no attribute 'info':
def search_yt(self, item):
with YoutubeDL(self.YDL_OPTIONS) as ydl:
try:
self.info = ydl.extract_info("ytsearch:%s" % item, download=False)['entries'][0]
except Exception:
return False
return {
'source': self.info['formats'][0]['url'],
'title': self.info['title'],
'channel': self.info['channel']
}
#client.command()
async def p(self, ctx, *args):
embed = discord.Embed(
title = 'Reproduciendo 🎵',
description = 'song_title'
)
query = " ".join(args)
voice_channel = ctx.author.voice.channel
if voice_channel is None:
await ctx.send("Antes debes meterte a un canal de voz")
else:
song = self.search_yt(query)
if type(song) == type(True):
await ctx.send("Hubo un error al intentar reproducir la canción >-<")
else:
await ctx.send(embed=embed)
await ctx.send("**Canción agregada con exito**")
self.music_queue.append([song, voice_channel])
if self.is_playing == True:
await ctx.send('La canción se agrego a la lista de reproducción')
else:
await self.play_music()
await ctx.send("**Reproduciendo**")

Write song = self.search_yt(query) before the embed initialization and create the embed like this:
embed = discord.Embed(
title = "Reproduciendo 🎵",
description = song['title']
)

Related

Discord.py Button responses interaction failed after 3 min

The button doesn't respond if no one has clicked it in 3 minutes.
I saw that it was something with timeout but I don't know where to place it.
My code:
#Tickets
class Menu(discord.ui.View):
def __init__(self):
super().__init__()
self.value = None
#discord.ui.button(label="📥 Ticket", style=discord.ButtonStyle.grey)
async def menu1(self, interaction: discord.Interaction, button: discord.ui.Button):
with open("open_channels_user_id.json", "r") as f:
data = json.load(f)
user_id = data["user_id"]
if user_id != interaction.user.id:
admin_role = discord.utils.get(interaction.guild.roles, name="hulpje")
category = discord.utils.get(interaction.guild.categories, name='Ticket')
overwrites = {interaction.guild.default_role: discord.PermissionOverwrite(read_messages=False),
interaction.guild.me: discord.PermissionOverwrite(read_messages=True),
interaction.user: discord.PermissionOverwrite(read_messages=True),
admin_role: discord.PermissionOverwrite(read_messages=True)}
new_ticket = await interaction.guild.create_text_channel(f'Ticket- {interaction.user.name}', category=category, overwrites=overwrites)
channel = client.get_channel(new_ticket.id)
embed = discord.Embed(title=f'Ticket- {interaction.user.name}', description="Goed dat je een ticket opent. \n Stuur alvast wat informatie zodat het makkelijker is voor het staff team.", color=0x004BFF)
await channel.send(embed=embed)
await interaction.response.send_message(f"Ticket is geopen met de naam: Ticket- {interaction.user.name}")
data['user_id'] = interaction.user.id
with open("open_channels_user_id.json", "w") as f:
json.dump(data, f)
time.sleep(3)
await interaction.channel.purge(limit=1)
else:
await interaction.channel.send("Je hebt al een ticket openstaan.")
time.sleep(5)
await interaction.channel.purge(limit=1)
async def menu(ctx):
view = Menu()
embed = discord.Embed(title="Ticket", description="Vragen, klachten of iets anders maak hier je Ticket aan en wordt zo snel mogelijk geholpen!", color=0x004BFF)
await ctx.send(embed=embed, view=view)
I don't know what to do. Pls help!
You can set the timeout value like this:
class Menu(discord.ui.View):
def __init__(self):
super().__init__(timeout=180) # Timeout value in seconds
self.value = None
If you set it to None, it will never time out, until you restart your bot.
If you want the view to persist between bot restarts, see this example here: https://github.com/Rapptz/discord.py/blob/master/examples/views/persistent.py

How to stop after function from executing twice after song ends

The after function in ctx.guild.voice_client.play(stream, after=lambda e: self.queueCheck(ctx, id, vc)) ie, queueCheck is running two times when it should run just once. It basically pops off a track off the queue and plays it on vc. But because the function itself is running two times in a row, it leads to one song getting skipped out of nowhere.
Here is the relevant code:
queues = {}
class music(commands.Cog):
def __init__(self, client):
self.client = client
self.tracks = {}
self.isPaused = False
self.skipping = False
self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 -nostdin', 'options': '-vn'}
self.YDL_OPTIONS = {'format': 'bestaudio/best',
'outtmpl': 'downloads/%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'noplaylist': True,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0', # ipv6 addresses cause issues sometimes
'force-ipv4': True,
'cachedir': False}
def queueCheck(self, ctx, id, vc):
text = ""
if queues[id] != []: # if server player queue not empty
stream = queues[id].pop(0)
if self.skipping == True:
print('skipping')
self.tracks[id].pop(0)
if len(self.tracks[id]) != 0:
text = "Now playing **" + self.tracks[ctx.message.guild.id][0] + "**"
self.skipping = False
else:
print('end naturally')
self.tracks[id].pop(0)
text = "Now playing **" + self.tracks[ctx.message.guild.id][0] + "**"
try:
vc.play(stream, after=lambda e: self.queueCheck(ctx, id, vc))
except Exception as e:
text = 'An error occurred while processing this request: ```py\n{}: {}\n```'.format(type(e).__name__, e)
else:
text = "Queue has finished playing!"
self.tracks[id].clear()
queues[id].clear()
print('should show up once')
coro = ctx.send(text)
fut = asyncio.run_coroutine_threadsafe(coro, self.client.loop)
try:
fut.result()
except:
# an error happened while sending the message
pass
async def playSong(self, ctx, url):
with youtube_dl.YoutubeDL(self.YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
if 'entries' in info: # if no url is input
url2 = info['entries'][0]['formats'][0]['url']
if ctx.message.guild.id not in self.tracks.keys():
self.tracks[ctx.message.guild.id] = [info['entries'][0]['title']]
else:
self.tracks[ctx.message.guild.id].append(info['entries'][0]['title'])
elif 'formats' in info: # if url is passed
url2 = info['formats'][0]['url']
if ctx.message.guild.id not in self.tracks.keys():
self.tracks[ctx.message.guild.id] = [info['title']]
else:
self.tracks[ctx.message.guild.id].append(info['title'])
#print(*(x for x in self.tracks[ctx.message.guild.id]), sep='\n')
stream = await discord.FFmpegOpusAudio.from_probe(url2, **self.FFMPEG_OPTIONS)
return stream
#commands.command(name='play', help="Plays any song", aliases=['pl'])
async def play(self, ctx, *, url):
if ctx.author.voice is None:
return await ctx.send('You are not in a voice channel!')
if ctx.voice_client is None:
await ctx.author.voice.channel.connect()
vc = ctx.guild.voice_client
guild = ctx.message.guild
if not vc.is_playing() and not self.isPaused:
stream = await self.playSong(ctx, url)
queues[guild.id] = [stream]
vc.play(stream, after=lambda e: self.queueCheck(ctx, guild.id, vc))
await ctx.send('Playing ' + '**' + str(self.tracks[ctx.message.guild.id][0]) + '**')
else:
await self.queue(ctx, url)
async def queue(self, ctx, url):
stream = await self.playSong(ctx, url)
guild = ctx.message.guild
if guild.id in queues:
queues[guild.id].append(stream)
await ctx.send('Added track ' + '**' + str(self.tracks[guild.id][len(self.tracks[guild.id]) - 1]) + '**')
#commands.command(name='queue', help="Shows the current queue", aliases=['q','Q'])
async def showQueue(self, ctx):
if ctx.voice_client is None:
return await ctx.send('I am not connected to a voice channel!')
if len(self.tracks[ctx.message.guild.id]) == 1:
queueEmbed = discord.Embed(title="Queue", description = "Your queue seems to be a tad bit empty :(", color=discord.Colour.random())
queueEmbed.add_field(name=':drum: Currently playing \n' + self.tracks[ctx.message.guild.id][0], value='\u200b', inline=False)
queueEmbed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.avatar.url)
await ctx.send(embed=queueEmbed)
elif len(self.tracks[ctx.message.guild.id]) > 0:
queueEmbed = discord.Embed(title="Queue", color=discord.Colour.random())
queuee = ""
if len(self.tracks[ctx.message.guild.id]) != 0:
for i in range(1, len(self.tracks[ctx.message.guild.id])):
queuee += ":white_small_square:" + str(i) + ". " + self.tracks[ctx.message.guild.id][i] + "\n"
else:
queuee = "No songs here"
queueEmbed.add_field(name='Coming up next', value='**' + queuee + '**', inline=False)
queueEmbed.add_field(name=':drum: Currently playing \n' + self.tracks[ctx.message.guild.id][0], value='\u200b', inline=False)
queueEmbed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.avatar.url)
await ctx.send(embed=queueEmbed)
else:
await ctx.send('No music in queue')

how i add a img that a user sent in a discord.py embed

I'm making a suggestion discord bot, and I'd like to know if there's how I can add an image that the user posted on embed
something like
embed.set_image(url=image_url)
the image_url would be the image the user added to the message.
suggestion_channel_id = 925568558241550393
color = 0x3498db
#bot.event
async def on_message(message):
suggestionData = '{}'.format(message.content).replace('?sugestão','')
if message.author == client.user:
return
if message.content.startswith('?sugestão'):
embed=discord.Embed(title ='Nova sugestão!')
embed.add_field(name='Vote Abaixo!', value=suggestionData, inline=True)
channel=bot.get_channel(suggestion_channel_id)
embed.color=color
embed.set_footer(text='Sugestão por ' + message.author.name, icon_url=message.author.avatar_url)
up_emoji = '\N{THUMBS UP SIGN}'
down_emoji = '\N{THUMBS DOWN SIGN}'
msg = await channel.send(embed=embed)
await msg.add_reaction(up_emoji)
await msg.add_reaction(down_emoji)
await message.channel.send('Sua sugestão foi enviada!' + '** ' + message.author.name + ' 😎' + ' **')
token = config("token")
bot.run(token)
You can use message.attachments to get a list of message attachments:
#bot.command()
async def send_image(ctx):
embed = discord.Embed(title="Your attached image")
if len(message.attachments):
embed.set_image(url=ctx.message.attachments[0].url)
await ctx.send(embed=embed)

Command raised an exception: TypeError: unhashable type: 'list' when updating my database

My entire code:
from discord.ext.commands import Bot, CheckFailure, has_role
import discord
import os
import random
from replit import db
from keep_alive import keep_alive
from statistics import mode
from operators import embeds
from datetime import date
#embed preset
'''
embed = discord.Embed(title="title", description="desc", color=PURPLE)
embed.set_author(name="Jäger Bot", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="name", value="value", inline=True)
embed.set_footer(text="requested by " + authormention + "| " + send_date)
await ctx.send(embed=embed)
'''
bot = Bot(command_prefix="j!", help_command=None)
# bot ready and activity
#bot.event
async def on_ready():
print("Bot started")
game = discord.Game("with Jäger")
await bot.change_presence(status=discord.Status.online, activity=game)
# --------------------
PURPLE = 0x800080
STAFF_ROLE_ID = 817476654297383002
SOTW_ROLE_ID = 817458661982994463
FORMER_SOTW_ROLE_ID = 817030310663028736
JAGER_ROLE_ID = 818950349016137739
today = date.today()
global is_voting
is_voting = False
global send_date
send_date = today.strftime("%d-%m-%Y")
#update db
#bot.event
async def update_db(key, value):
if key in db.keys():
old_value = db[key]
old_value.append(value)
db[key] = old_value
else:
db[key] = [value]
#keys:
#nominating_perons ppl who have nominated
#nominated_persons ppl who have been nominated
#voting_perons ppl who have voted
#voted_persons ppl who have been voted for
#----commands----
#help
#bot.command()
async def help(ctx ,category=None):
print("command: help")
staff_category = "staff"
sotw_category = "sotw"
misc_category = "misc"
if category is None:
print("no category")
embed = discord.Embed(title="Select a category with `j!help \"category\"`", description="Prefix = j!", color=PURPLE)
embed.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="Categories:", value="`staff` `sotw` `misc`", inline=True)
embed.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=embed)
else:
if category == staff_category:
print("staffhelp")
staff = discord.Embed(title="Staff commands", description="prefix = j!", color=PURPLE)
staff.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
staff.add_field(name="startvote", value="Starts the voting process", inline=False)
staff.add_field(name="finishvote", value="Finishes the voting process", inline=False)
staff.add_field(name="list <key> | debug only", value="Shows all the items in a specific list", inline=False)
staff.add_field(name="clear <key> | debug only", value="Clears all the items in a specific list", inline=False)
staff.add_field(name="ph <key> | debug only", value="Adds a `place_holder` to a specific list", inline=False)
staff.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=staff)
else:
if category == sotw_category:
print("sotwhelp")
sotw = discord.Embed(title="Sotw commands", description="prefix = j!", color=PURPLE)
sotw.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
sotw.add_field(name="nominate <member>", value="Nominate a member", inline=False)
sotw.add_field(name="vote <member>", value="Vote for a member", inline=False)
sotw.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=sotw)
else:
if category == misc_category:
print("mischelp")
misc = discord.Embed(title="Misc commands", description="prefix = j!", color=PURPLE)
misc.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
misc.add_field(name="quote", value="A random siege operator quote", inline=False)
misc.add_field(name="profile <operator>", value="Shows the profile of the specified siege operator", inline=True)
misc.add_field(name="shoot <member>", value="Shoot someone", inline=False)
misc.add_field(name="sexy <member>", value="Shows how sexy someone is", inline=False)
misc.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=misc)
else:
print("wrong category")
embed = discord.Embed(title="Select a category with `j!help \"category\"`", description="Prefix = j!", color=PURPLE)
embed.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="Categories:", value="`staff` `sotw` `miscellaneous`", inline=True)
embed.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=embed)
#help end
#SOTW
#nominate
#bot.command()
async def nominate(ctx, nominatedperson: discord.Member):
print("command: nominate")
print(nominatedperson)
nominated_person = nominatedperson.mention
nominating_person = ctx.author.mention
former_sotw_role = discord.utils.get(ctx.guild.roles, id=FORMER_SOTW_ROLE_ID)
if not is_voting:
print("is_voting was false")
nominated_persons = db["nominated_persons"]
nominating_persons = db["nominating_persons"]
if nominating_person not in nominating_persons:
print("nominating person wasnt in nominating persons")
if nominated_person in nominated_persons:
print("nominated_person was in nominated_persons")
await ctx.send("That member has already been nominated!")
else:
print("nominated_person wasnt in nominated_persons")
former_sotw_role = discord.utils.get(ctx.guild.roles, id=FORMER_SOTW_ROLE_ID)
if former_sotw_role in nominatedperson.roles:
print("nominated_person was former sotw")
await ctx.send("That member has already been SOTW this year!")
else:
print("nominated_person wasnt former sotw")
embed = discord.Embed(title="Member nominated:", description=nominated_person, color=PURPLE)
embed.set_author(name="Jäger Bot", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="By:", value=nominating_person, inline=True)
embed.set_footer(text=send_date)
print(nominated_persons)
await update_db(nominated_persons, nominated_person)
await update_db(nominating_persons, nominating_person)
await ctx.send(embed=embed)
else:
print("nominating_person was in nominating_persons")
await ctx.send("You already nominated someone")
else:
print("is_voting was true")
await ctx.send("You can't nominate while we are voting for the next SOTW!")
#nominate end
#SOTW end
#insert place_holder
#bot.command()
#has_role(STAFF_ROLE_ID)
async def ph(ctx, key):
print("command: ph")
await update_db(key, "place_holder")
await ctx.send("Placeholder has been added to " + key)
#ph.error
async def ph_error(ctx, error):
if isinstance(error, CheckFailure):
await ctx.send("Only staff members can use this command")
#insert place_holder end
#list
#bot.command()
#has_role(STAFF_ROLE_ID)
async def list(ctx, to_list):
print("command: list")
if to_list in db.keys():
requester = ctx.author
requestermention = str(requester)
items = db[to_list]
embed = discord.Embed(title="List", description=to_list, color=PURPLE)
embed.set_author(name="Jäger Bot", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="Items:", value=items, inline=True)
embed.set_footer(text="requested by " + requestermention + " | " + send_date)
await ctx.send(embed=embed)
else:
await ctx.send("That list doesn't exist")
#list.error
async def list_error(ctx, error):
if isinstance(error, CheckFailure):
await ctx.send("Only staff members can use this command")
#list end
#list keys
#bot.command()
async def keys(ctx):
allkeys = db.keys()
await ctx.send(allkeys)
#list keys end
#clear
#bot.command()
#has_role(STAFF_ROLE_ID)
async def clear(ctx, to_clear):
print("command: clear")
str_userid = ctx.author.id
str_zoutigewolfid = "298516275322290188"
userid = int(str_userid)
zoutigewolfid = int(str_zoutigewolfid)
if userid == zoutigewolfid:
if to_clear in db.keys():
del db[to_clear]
await ctx.send("List " + to_clear + " has been cleared")
else:
await ctx.send("That list doesn't exist")
else:
await ctx.send("Only my daddy Wolf can use this command!")
#clear.error
async def clear_error(ctx, error):
if isinstance(error, CheckFailure):
await ctx.send("Only staff members can use this command")
#clear end
#quote
# preset {"title": "", "description": ""},
quotes_list = [
{"title": "A really big fucking hole coming right up!", "description": "Jordan 'Thermite' Trace"},
{"title": "Pass those plates around!", "description":"Julien 'Rook' Nizan"},
{"title": "You can stop worrying about grenades now!", "description": "Marius 'Jäger' Streicher"},
{"title": "if it runs on batteries, I'll see it!", "description": "Monica 'IQ' Weiss"},
{"title": "Fookin' laser sights!", "description": "Mike 'Thatcher' Baker"},
{"title": "Toxic babes are in position!", "description": "James 'Smoke' Porter"},
{"title": "Jammah in position!", "description": "Mark 'Mute' R. Chandar"},
{"title": "EDD primed, let them come!", "description": "Maxim 'Kapkan' Basuda"},
{"title": "Mine flying out!", "description": "Elżbieta 'Ela' Bosak"},
{"title": "You're mine bloody asshole!", "description": "Taina 'Caveira' Pereira"},
{"title": "Malbodan haengdong-iji (말보단 행동이지)", "description": "Chul 'Vigil' Kyung Hwa"},
{"title": "Launching override!", "description": "Grace 'Dokkaebi' Nam"},
{"title": "Camera in position!", "description": "Meghan 'Valkyrie' J. Castellano"},
{"title": "As my friend would say: A really big fucking hole coming right up.", "description": "Yumiko 'Hibana' Imagawa"},
{"title": "Big brother coming in for overwatch!", "description": "Olivier 'Lion' Flament"},
{"title": "Time for a wakeup call", "description": "Grace 'Dokkaebi' Nam"},
{"title": "No runnin' in the halls!", "description": "Morowa 'Clash' Evans"},
{"title": "LMG mounted and loaded!", "description": "Alexsandr 'Tachanka' Senaviev, RIP old tachanka"},
{"title": "Rtila active!", "description": "Jalal 'Kaid' El Fassi"},
{"title": "Now you see me, now you don't!", "description": "Elena 'Mira' María Álvarez"},
{"title": "Why do it yourself when robots do it better?", "description": "Masaru 'Echo' Enatsu"},
{"title": "Bullseye, got us a drone", "description": "Max 'Mozzie' Goose"},
]
#bot.command()
async def quote(ctx):
requester = ctx.author
requestermention = str(requester)
random_index = random.randint(0,21)
quote = quotes_list[random_index]
embed = discord.Embed(**quote, color=PURPLE)
embed.set_footer(text="Requested by " + requestermention + " | " + send_date)
await ctx.send(embed=embed)
#quote end
#operator profile
#bot.command()
async def profile(ctx, operator_name):
await ctx.send(embed=embeds[operator_name])
#operator profile end
#sexy
#bot.command()
async def sexy(ctx, person: discord.Member):
jager_role = discord.utils.get(ctx.guild.roles, id=JAGER_ROLE_ID)
sexyperson = person.mention
if jager_role in person.roles:
print("person was jager")
embed = discord.Embed(title="Sexy meter", description="Lord Jäger is 69420% sexy", color=PURPLE)
await ctx.send(embed=embed)
else:
print("person wasnt jager")
outputint = random.randint(0,100)
output = str(outputint)
embed = discord.Embed(title="Sexy meter", description=sexyperson + " is " + output + "% sexy", color=PURPLE)
await ctx.send(embed=embed)
#sexy end
#gun list
guns_list = [
"MP5",
"M4",
"AK-47",
"MP7",
"SCAR-L",
"Desert Eagle",
"MP5K",
"AUG A2",
"M249",
"AR15"
]
#title list
title_list = [
"Elimination",
"Homicide",
"Assasination",
"Drive-by",
"Sniped",
"Popped",
"Capped",
"No-scoped",
]
#shoot
#bot.command()
async def shoot(ctx, person: discord.Member):
print("command: shoot")
shooter = ctx.author.mention
shotperson = person.mention
shooterid = ctx.author.id
shotpersonid = person.id
randomnumber = random.randint(0,9)
randomgun = guns_list[randomnumber]
randomtitlenumber = random.randint(0,7)
title = title_list[randomtitlenumber]
if shooterid != shotpersonid:
embed = discord.Embed(title=title, description=shooter + " shot " + shotperson + " with " + randomgun, color=PURPLE)
await ctx.send(embed=embed)
else:
await ctx.send("Shooting yourself is a very dumb idea")
#shoot end
#anti nword
racist_words = [
"nigga",
"niggas",
"nigger",
"niggers",
"/Vigga",
"/Viggas",
"/Vigger",
"/Viggers",
"niga",
"nega",
"negga",
"nibba",
"/vigga",
"/viggas",
"/vigger",
"/viggers",
]
# racist detector 9000
"""
#bot.event
async def on_message(msg):
if any(word in msg.content for word in racist_words):
print("someone said the n word")
await msg.channel.send(msg.author.mention + " did you just seriously say the n-word?")
await msg.channel.send("Not poggers bro, not poggers")
await msg.channel.send(f"<#&{STAFF_ROLE_ID}> come get this bitch")
await msg.delete()
await bot.process_commands(msg)
"""
#racist end
#commands end
keep_alive()
bot.run(os.getenv("TOKEN"))
when i do the command j!nominate #discord mention it gives the error "Command raised an exception: TypeError: unhashable type: 'list'" but dont remember hashing any list. can someone please tell me why this is happening? the database is formatted like this ["1", "2", "3"] if you need to know
error:
Ignoring exception in command nominate:
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 148, in nominate
await update_db(nominated_persons, nominated_person)
File "main.py", line 53, in update_db
db[key] = [value]
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 182, in __setitem__
r = self.sess.post(self.db_url, data={key: j})
TypeError: unhashable type: 'list'
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: unhashable type: 'list'
Untested but try the following
async def update_db(key, value):
if key in db.keys():
db[key].append(value)
else:
db[key] = [value]
Can you see why you were getting the TypeError by comparing my code with yours?
Ok, thanks for updating the question with the full code and traceback.
The offending line is db[key] = [value] that throws a TypeError:unhashable type list,
which means you passed a list type as key argument for the update_db function.
That cannot be done because, as the traceback clearly states, you cannot hash a list type (meaning you cannot access a dictionary value using a key that is a list type).
But the real source of the pain is right above that line:
if key in db.keys():
key = db[key]
key.append(value)
db[key] = key
That's a lot of key, isn't it? The problem here is that you used the variable name key referring to different things and you ended up with a bit of confusion, so I suggest you use different variables to indicate different things:
async def update_db(key, value):
if key in db.keys():
old_value = db[key]
old_value.append(value)
db[key] = old_value
else:
db[key] = [value]
In this way it is the value that is actually updated in the database and not the key, so the latter would never end up being a list.
This last one is just out of curiosity. Why are you defining a function to update the database, aren't there defined methods to do that? What db are you using?
I FOUND THE ANSWER!
the problem was with await update_db(nominated_persons, nominated_person)
as it is like that, it doesn't update the db because nominated_persons is undefined, so i defined it with nominated_persons = db["nominated_persons"]. but then i would get the hash error because that is a list and i cant use that, so i just did nominated_persons = "nominated_persons" so the nominated_persons is defined as the word "nominated_persons". so now it works
i feel so stupid
here is the updated code:
#bot.command()
async def nominate(ctx, nominatedperson: discord.Member):
print("command: nominate")
nominated_person = nominatedperson.mention
nominated_persons = "nominated_persons"
await update_db(nominated_persons, nominated_person)
await ctx.send("whatever")
(Side note: you can just put “nominated_persons” in the update_db command you don’t have to refer to it with a variable like i did.)

How to make Discord.py get how MANY users reacted with a specific emoji?

I'm trying to make a poll command in Discord.py but want at the end the bot to send a list of users that reacted with 1️⃣ and another list of people that reacted with 2️⃣.
This is my code so far:
async def poll(ctx, q1, q2, time : int):
await ctx.send(f"React with 1 to vote for **{q1}** and with 2 to vote for **{q2}**\n**Poll Lasts for {time} seconds**")
poll = discord.Embed(title = "Poll", color = discord.Color.blue())
poll.add_field(name = f"{q1} 1️⃣", value = "᲼᲼᲼᲼᲼᲼")
poll.add_field(name = f"{q2} 2️⃣", value = "᲼᲼᲼᲼᲼᲼")
msg = await ctx.send(embed = poll)
r1 = await msg.add_reaction("1️⃣")
r2 = await msg.add_reaction("2️⃣")
await asyncio.sleep(time)
await ctx.send("Times up! **Poll Closed**")
new_msg = discord.utils.get(client.cached_messages,id = msg.id)
users1 = await r1.reactions[0].users().flatten()
users1.pop(users1.index(client.user))
users2 = await r2.reactions[0].users().flatten()
users2.pop(users2.index(client.user))
em=discord.Embed(title=f'Votes for {q1}', description=" , ".join(user.name for user in users1),color = discord.Colour.blue())
await ctx.send(embed = em)
em=discord.Embed(title=f'Votes for {q2}', description=" , ".join(user.name for user in users2),color = discord.Colour.blue())
await ctx.send(embed = em)
And this is the error I am getting:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'reactions'
Message.add_reaction returns None, you can't use these two lines
r1 = await msg.add_reaction("1️⃣")
r2 = await msg.add_reaction("2️⃣")
Easiest approach would be to fetch the message again with the updated reactions
message = await ctx.send("Whatever")
await message.add_reaction("1️⃣")
await message.add_reaction("2️⃣")
await asyncio.sleep(10)
updated_message = await ctx.channel.fetch_message(message.id)
users1, users2 = [], []
for r in updated_message.reactions:
print(f"{str(r)} was added {r.count} times")
if str(r) == "1️⃣":
users = await r.users().flatten()
users1.extend(users)
elif str(r) == "2️⃣":
users = await r.users().flatten()
users2.extend(users)
# `users1` and `users2` are lists of users that reacted with `1️⃣` and `2️⃣` accordingly
Reference:
Messageable.fetch_message
Message.reactions
Reaction.count
Reaction.users

Categories

Resources