I wanted to write a mute command for a bot in the discord - discord

I wanted to write a mute command for a bot in the discord. The command does not work. Here's the code and the error
#bot.tree.command(name="mute", description="Мьют участника")
#app_commands.checks.has_permissions( administrator = True )
async def mute( interaction: discord.Interaction, member: discord.Member,reason: str = None ):
await interaction.response.defer( thinking = True )
await interaction.channel.purge( limit = 1 )
mute_role = discord.utils.get ( interaction.guild.roles, id = '1061014280922746887', name = 'muted' )
await member.add_roles( mute_role )
await interaction.channel.send( embed = discord.Embed(
title="Участник успешно замьючен",
description= ( f"{member.mention} **был замьючен модератором** {interaction.user.mention}! "),
color=discord.Color.from_str("#C3F")
))
error
I was trying to recreate the role of mute. Change interaction.guild.roles to interaction.message.guild.roles

ID's are ints, not strings. You're passing a string to utils.get, so nothing is found and mute_role is None, as your error message is telling you.
discord.utils.get(interaction.guild.roles,id='1061014280922746887',name='muted')
# ^^^^^^^^^^^^^^^^^^^^^ string
Pass the ID as an int instead.
Docs for Role.id: https://discordpy.readthedocs.io/en/stable/api.html#discord.Role.id
Type:
int

Related

Discord.py, member.status showing allways offline [duplicate]

#bot.tree.command(name="user", description="Shows some informations about the mentioned user.")
async def user(interaction: discord.Interaction, member:discord.Member=None):
if member == None:
member = interaction.user
roles = [role for role in member.roles if role.name != "#everyone"]
embed = discord.Embed(title=f"Details about the user, {member.name}",color=0xdaddd8, timestamp = datetime.datetime.utcnow())
embed.set_thumbnail(url=member.avatar) # Avatar Thumbnail
embed.add_field(name="👤 Name", value = f"{member.name}#{member.discriminator}") # Embeds
embed.add_field(name="🏷️ Nickname", value = member.display_name)
embed.add_field(name="🆔 User ID", value = member.id)
embed.add_field(name="📆 Created at", value = member.created_at.strftime("%D \n%I:%M %p"))
embed.add_field(name="👋🏻 Joined at", value = member.joined_at.strftime("%D \n%I:%M %p"))
embed.add_field(name="🟢 Status", value = member.status) #this line is'nt working as it should
embed.add_field(name="❤️‍🔥 Top role", value = member.top_role.mention)
bot_status = "Yes, it is" if member.bot else "No, They'snt"
embed.add_field(name="🤖 Bot?", value = bot_status)
embed.set_footer(text = interaction.user.name,icon_url = interaction.user.avatar)
await interaction.response.send_message(embed=embed)
I made a User information command and this command shows every person offline even itself how can i fix it?
This is likely due to lack of intents.
Add in your code, under the intents you define:
intents.members = True
intents.presences = True
Use member.raw_status instead of member.status. It will return a string value such as 'online', 'offline' or 'idle'.

Discord.py snipe command is sniping messages from other channels

I recently made a snipe command for my discord bot but I have one problem. Snipe command snipes a message from other channels when I for example want to snipe a message in general. Here is my code:
#bot.event
async def on_message_delete(message):
if message.attachments:
bob = message.attachments[0]
bot.sniped_messages[message.guild.id] = (bob.proxy_url, message.content, message.author, message.channel.name, message.created_at)
else:
bot.sniped_messages[message.guild.id] = (message.content,message.author, message.channel.name, message.created_at)
#bot.command(aliases=['s'])
async def snipe(ctx):
try:
bob_proxy_url, contents,author, channel_name, time = bot.sniped_messages[ctx.guild.id]
except:
contents,author, channel_name, time = bot.sniped_messages[ctx.guild.id]
try:
embed = discord.Embed(description=contents , color=discord.Color.purple(), timestamp=time)
embed.set_image(url=bob_proxy_url)
embed.set_author(name=f"{author.name}#{author.discriminator}", icon_url=author.avatar_url)
embed.set_footer(text=f"Deleted in : #{channel_name}")
await ctx.channel.send(embed=embed)
except:
embed = discord.Embed(description=contents , color=discord.Color.purple(), timestamp=time)
embed.set_author(name=f"{author.name}#{author.discriminator}", icon_url=author.avatar_url)
embed.set_footer(text=f"Deleted in : #{channel_name}")
await ctx.channel.send(embed=embed)
snipe_message_author = {}
snipe_message_content = {}
#client.event
async def on_message_delete(message):
snipe_message_author[message.channel.id] = message.author
snipe_message_content[message.channel.id] = message.content
#client.command(name = 'snipe')
async def snipe(ctx):
channel = ctx.channel
try:
em = discord.Embed(description = f"`{snipe_message_content[channel.id]}`\nMessage sent by {snipe_message_author[channel.id]}!", color = 0x00c230)
em.set_author(name = f"Last deleted message in #{channel.name}")
em.set_thumbnail(url="https://cdn.discordapp.com/avatars/352793093105254402/8a2018de21ad29973696bfbf92fc31cd.png?size=4096")
em.set_footer(text = f"Snipe requested by {ctx.message.author}")
await ctx.send(embed = em)
except:
embed = discord.Embed(colour = 0x00c230)
embed.set_author(name=f"There are no deleted messages in #{ctx.channel}!")
embed.set_thumbnail(url="https://cdn.discordapp.com/avatars/352793093105254402/8a2018de21ad29973696bfbf92fc31cd.png?size=4096")
embed.set_footer(text=f"Snipe requested by {ctx.message.author}")
await ctx.channel.send(embed=embed)
Thats what I use and it works properly.
Since I added [message.channel.id] to the variables it only checks for snipes in that channel. This is how it looks like in Discord

Trying to ask user confirmation for discord.py bot command, but doing so neglects the "if and elif block" entirely

I have imported everything needed for the command.
So, the issue here is, in the condition for executing the command (checking if the user said yes/no or something weird which terminates the command)
#commands.command()
#commands.has_permissions(manage_channels=True)
async def nuke(self, ctx,*, channel = None, reason = None):
if reason is None:
reason = "No reason was specified!"
if channel is None:
channel = ctx.channel
p = time.strftime(f'Today at %H:%M %p')
embei = discord.Embed(color=0xa3a3ff, title = ":warning: ALERT ALERT ALERT :warning: ", description=f"{ctx.author.mention} Are you sure you want to delete {ctx.channel.mention}? y/n")
await ctx.send(embed=embei)
msg = await self.client.wait_for('message', check=lambda message:message.author == ctx.author and message.channel.id == ctx.channel.id)
if msg.content.lower in ("y", "yes"):
embedis = discord.Embed(color=0xa3a3ff, title=f"Channel ({ctx.channel.name}) has been nuked :boom:", description=f"Nuked by: {ctx.author.name}#{ctx.author.discriminator} \n **Reason:** {reason}")
embedis.set_image(url = "https://66.media.tumblr.com/23dad7011515a9c21647fefb07e1c0e0/dd0cbd9bb94e2a45-1e/s640x960/a02fc34abff6953c59adafc190de6e5276969175.gif")
embedis.set_footer(text=f"Rylie - Thanks for using this bot! - {p} - {self.client.version}", icon_url = str(self.client.user.avatar_url))
await ctx.channel.delete(reason=reason)
channel = await ctx.channel.clone()
await channel.send(embed=embedis)
elif msg.content.lower in ("n", "no"):
embegs = discord.Embed(color=0xa3a3ff, title = ":red_circle: NOTICE :red_circle:", description = f"{ctx.channel.mention} was not nuked!")
embegs.set_footer(text=f"Rylie - Thanks for using this bot! - {p} - {self.client.version}", icon_url = str(self.client.user.avatar_url))
await ctx.send(embed=embegs)
else:
embers = discord.Embed(color=0xa3a3ff, title = ":red_circle: NOTICE :red_circle:", description = "No proper response was given, action was terminated")
embers.set_footer(text=f"Rylie - Thanks for using this bot! - {p} - {self.client.version}", icon_url = str(self.client.user.avatar_url))
await ctx.send(embed=embers)
The part with the issue
msg = await self.client.wait_for('message', check=lambda message:message.author == ctx.author and message.channel.id == ctx.channel.id)
if msg.content.lower in ("y", "yes"):
embedis = discord.Embed(color=0xa3a3ff, title=f"Channel ({ctx.channel.name}) has been nuked :boom:", description=f"Nuked by: {ctx.author.name}#{ctx.author.discriminator} \n **Reason:** {reason}")
embedis.set_image(url = "https://66.media.tumblr.com/23dad7011515a9c21647fefb07e1c0e0/dd0cbd9bb94e2a45-1e/s640x960/a02fc34abff6953c59adafc190de6e5276969175.gif")
embedis.set_footer(text=f"Rylie - Thanks for using this bot! - {p} - {self.client.version}", icon_url = str(self.client.user.avatar_url))
await ctx.channel.delete(reason=reason)
channel = await ctx.channel.clone()
await channel.send(embed=embedis)
elif msg.content.lower in ("n", "no"):
embegs = discord.Embed(color=0xa3a3ff, title = ":red_circle: NOTICE :red_circle:", description = f"{ctx.channel.mention} was not nuked!")
embegs.set_footer(text=f"Rylie - Thanks for using this bot! - {p} - {self.client.version}", icon_url = str(self.client.user.avatar_url))
await ctx.send(embed=embegs)
else:
embers = discord.Embed(color=0xa3a3ff, title = ":red_circle: NOTICE :red_circle:", description = "No proper response was given, action was terminated")
embers.set_footer(text=f"Rylie - Thanks for using this bot! - {p} - {self.client.version}", icon_url = str(self.client.user.avatar_url))
await ctx.send(embed=embers)
when I execute the command, it does ask me for the confirmation as expected, however, the reply here doesn't matter as it always executes the else statement. I thought the issue was with indentation and so I tried fixing that but that too didn't work. Does anyone know about the issue here I might be facing?
Extra: Before Adding user confirmation, the code was working absolutely fine! (It created a clone of the channel, sent the embed there saying it nuked the original channel, and deleted the original channel)
For this question of mine, the string.lower() is a method which I need to call, which was mentioned to me by Lukasz. I was using the string.lower() in the wrong way.
To Fix the problem I had, I declared two lists a and b
a=["y", "yes"]
b = ["n", "no"]
and changed
if msg.content.lower in ("y", "yes"):
elif msg.content.lower in ("n", "no"):
to
if msg.content in a:
elif msg.content in b:
and the issue was fixed.

Discord Python Rewrite - help command error (custom)

So, I've made a help that works, but I want it to say something if the category that the user entered is invalid. I got a working code without the error if the category is invalid. The code:
#client.command()
async def help(ctx, *, category = None):
if category is not None:
if category == 'mod' or 'moderation' or 'Mod' or 'Moderation':
modhelpembed = discord.Embed(
title="Moderation Help",
timestamp=datetime.datetime.now(),
colour=discord.Color.green()
)
modhelpembed.add_field(name='kick', value="Kicks a member from the server", inline=False)
modhelpembed.add_field(name='ban', value='bans a member from the server', inline=False)
modhelpembed.add_field(name='unban', value='unbans a member from the server', inline=False)
modhelpembed.add_field(name="nuke", value="Nukes a channel :>", inline=False)
modhelpembed.add_field(name='mute', value="Mute a member", inline=False)
modhelpembed.add_field(name="purge", value='purges (deletes) a certain number of messages', inline=False)
await ctx.send(f'{ctx.author.mention}')
await ctx.send(embed=modhelpembed)
elif category == 'fun' or 'Fun':
funembed = discord.Embed(
title="Fun Help",
timestamp=datetime.datetime.now(),
colour=discord.Color.green()
)
funembed.add_field(name='meme', value='shows a meme from r/memes', inline=False)
funembed.add_field(name='waifu', value='shows a waifu (pic or link) from r/waifu', inline=False)
funembed.add_field(name='anime', value='shows a anime (image or link) from r/anime', inline=False)
funembed.add_field(name='spotify', value='Tells you the targeted user listening on', inline=False)
funembed.add_field(name="song", value="Tells you the whats the targeted user listening in Spotify", inline=False)
funembed.add_field(name="album", value="Tells you whats the targeted user album", inline=False)
funembed.add_field(name="timer", value="Sets a Timer for you.", inline=False)
await ctx.send(f'{ctx.author.mention}')
await ctx.send(embed=funembed)
else:
nonembed = discord.Embed(
title="Help list",
timestamp=datetime.datetime.now(),
colour=discord.Color.green(),
description='Category:\nmod\nfun'
)
await ctx.send(f'{ctx.author.mention}')
await ctx.send(embed=nonembed)
It works, but when i tried inputing a invalid category it sends Moderation.
You erros comes from your second if statement. You just have to replace it with either:
if category == ('mod' or 'moderation' or 'Mod' or 'Moderation'):
if category in ['mod', 'moderation', 'Mod', 'Moderation']:
Here's why your statement is triggered when you input an invalid category:
An empty string returns False (eg. "") and a string returns True (eg. "TEST").
If you don't put brackets, it will separate each or as a condition (if category == 'mod' / if 'mod' / if 'moderation' / if 'Mod' / if 'Moderation').
Since a non empty string returns True, when you input an invalid category, your second if statement gets triggered and it gives you the Moderation help message.
You can also use commands.Command attributes to make some refactoring:
#client.command(description='Say hi to the bot')
async def hello(ctx):
await ctx.send(f'Hi {ctx.author.mention}')
#client.command(description='Test command')
async def test(ctx):
await ctx.send('TEST')
#client.command()
async def help(ctx, *, category = None):
categories = {
'fun': ['hello',],
'testing': ['test',],
}
if category is None:
desc = '\n'.join(categories.keys())
embed = discord.Embed(
title="Help list",
timestamp=datetime.datetime.now(),
colour=discord.Color.green(),
description=f'Categories:\n{desc}'
)
else:
category = category.lower()
if not category in categories.keys():
await ctx.send('Category name is invalid!')
return
embed = discord.Embed(
title=f"{category.capitalize()} Help",
timestamp=datetime.datetime.now(),
colour=discord.Color.green()
)
for cmd in categories[category]:
cmd = client.get_command(cmd)
embed.add_field(name=cmd.name, value=cmd.description)
await ctx.send(ctx.author.mention, embed=embed)

Poll question which adds the correct amount of reactions. (d.py)

I am trying to make a poll command which adds the correct amount of reactions such as A B C D E etc.
I have already tried this but it was a simple yes or no poll command.
elif message.content.startswith('m/qpoll'):
question = message[8:]
await message.delete()
message = await message.channel.send(f"**New poll:** {question}")
await message.add_reaction('❌')
await message.add_reaction('✔️')
What i am trying to achieve is a command which adds A B C reactions if there is three possible answers and A B C D E if there is five possible answers etc.
The command the user has to use is preferred to be in this format:
m/poll "question" "answer 1" "answer 2" "answer 3"
The command needs to be under a on_message statement as the command package does not work as well for my bot.
A simple way to do it, without using discord.ext.commands :
elif message.content.startswith('m/qpoll'):
content = message.content[8:]
items = content.split(" ")
question = items[0]
answers = '\n'.join(items[1:])
await message.delete()
message = await message.channel.send(f"**New poll:** {question}\n{answers}")
reactions = ['A', 'B', 'C', 'D', 'E'] #replace the letters with your reactions
for i in range(len(items[1:]))
await message.add_reaction(reactions[i])
Here's the poll command I made for my bot
#commands.command()
async def poll(self, ctx):
"""
Conduct a poll (interactive)
?poll
"""
member = ctx.author
member: Member
maker = []
await ctx.send("```What is the Question ❓```")
em = ["🧪", "🧬", "🚀", "🖌️", "🧨"]
def mcheck(m):
return m.author == member
try:
msg = await self.bot.wait_for('message', timeout=20.0, check=mcheck)
maker.append(msg.content)
except TimeoutError:
return await ctx.send("```Poll timed out ⏳```")
await ctx.send("```How many options do you want?```")
try:
msg = await self.bot.wait_for('message', timeout=20.0, check=mcheck)
except TimeoutError:
return await ctx.send("```Poll timed out ⏳```")
i = int(msg.content)
if i > 5:
return await ctx.send("```A maximum of 5 options for polls```")
await ctx.send("```Enter your options ✔```")
for i in range(i):
try:
await ctx.send(f"```{i + 1}) ```")
msg = await self.bot.wait_for('message', timeout=20.0, check=mcheck)
maker.append(msg.content)
await msg.add_reaction("✅")
except TimeoutError:
return await ctx.send("```Poll timed out ⏳```")
poller = Embed(color=0x5EE34)
poller.title = maker[0]
des = ''
for j in range(1, len(maker)):
des += f"```{em[j - 1]} {maker[j]}```\n"
poller.description = des
pr = await ctx.send(embed=poller)
for j in range(i + 1):
await pr.add_reaction(em[j])
def reac_check(r, u):
return pr.id == r.message.id and r.emoji in em
eopt = {e: 0 for e in em}
while True:
try:
reaction, user = await self.bot.wait_for('reaction_add', timeout=20.0, check=reac_check)
e = str(reaction.emoji)
except TimeoutError:
await ctx.send("```Poll Finished ✅```")
break
if e in eopt.keys() and user != self.bot.user:
eopt[e] += 1
eopt = {k: v for k, v in sorted(eopt.items(), key=lambda item: item[1], reverse=True)}
most = next(iter(eopt))
loc = em.index(most)
poller.title = "Results 🏆"
poller.description = f"```Folks chose 📜\n{maker[loc + 1]}```"
return await ctx.send(embed=poller)
As a rule of thumb avoid using on_message to create commands. You can read about commands.Bot() in the docs.
That said you should be able adapt the above example to suit your needs.

Resources