Im trying to create a command wherein the user will be able to kick a member while the bot will ask the user to confirm whether to kick or not. When I tested the code, I dont get any errors in the terminal although I do get one on Discord saying "Interaction Failed." How may I fix this issue?Is there also a way for me to add a function wherein if the cancelled button is pressed? Saying "Cancelled kick." Im also quite new to dpy
#bot.command()
#commands.has_permissions(kick_members=True)
async def kick(ctx, member: discord.Member, *, reason=None):
username_1 = ctx.message.author.name
avatar_1 = ctx.message.author.avatar_url
embed = discord.Embed(description=f"**Kick {member}?**", color= 0x303136)
await ctx.send(embed = embed, components = [
[Button(label="Confirm", style="3", emoji = "✅", custom_id="button1"), Button(label="Cancel", style="4", emoji = "❌", custom_id="button2")]
])
username_1 = ctx.message.author.name
avatar_1 = ctx.message.author.avatar_url
conf=discord.Embed(title=f'{member} has been kick', color= 0x303136)
conf.set_author(name=f"kicked by {username_1}", icon_url=avatar_1)
interaction = await bot.wait_for("button_click", check = lambda i: i.custom_id == "button1")
await member.kick(reason=reason)
await interaction.send(content = conf, ephemeral=True)
You need to respond to the interaction for the discord to confirm that everything went well.
Try:
await interaction.response.send_message(content = conf, ephemeral=True)
This way you will be responding to an interaction by sending a message.
About your second question, please specify which fork of discord.py you are using.
Related
I'm trying to add buttons to my bot and I want another, already existing command to be executed when the button is clicked. How can this be done? For example, when you press the "1" button, "Hi" will be executed
#client.command()
async def Hi(ctx):
await ctx.send('Hi')
#client.command(pass_context = True)
async def test(ctx):
await ctx.send(
embed=discord.Embed(title="text"),
components=[
Button(style=ButtonStyle.green, label="1")
]
)
response = await client.wait_for("button_click")
if response.channel == ctx.channel:
I hope this is what you were looking for (I assume you're using discord.py). I looked over the issue and noticed three issues which were:
components=[ Button(style=ButtonStyle.green, label="1") ] ) Unless you're using another library I noticed that couldn't work.
As well as fixed the use if await client.wait_for("button_click") and changed it to await bot.wait_for("reaction_add") which is the correct usage.
Lastly, the if statement was not working, so I replaced it with the check function which returns a value if the user has responded with the correct 1️⃣ emoji.
#client.command(pass_context = True)
async def test(ctx):
message = await ctx.send(embed=discord.Embed(title="Text"))
emoji = '1️⃣' # The emoji you want the bot to react with
await message.add_reaction(emoji) # Bot reacts with that emoji you assigned
def check(response, user):
return str(response.emoji) in emoji # Checks that the user has responded with the correct emoji
response, user = await client.wait_for("reaction_add") # Waits for the user to react with the emoji
await ctx.send("Hi!")
Hopefully this works and resolves your issue. Good luck with your project!
You can invoke the command from another command. In this case though, the command is really small and you would be better off just putting it there.
See here in the docs, but be warned about using converters, checks, cooldowns, pre-invoke, or after-invoke hooks, as they aren't processed.
#client.command()
async def Hi(ctx):
await ctx.send('Hi')
# then do this in a command:
# ...
# no arguments as it is right now
await ctx.invoke(Hi)
# or for other commands if you need arguments
# sample_command(ctx, number: int, string: str)
await ctx.invoke(sample_command, 20, 'stack')
I'm trying to make my discord bot DM a person when I kick them. I have tried some stuff but nothing ended up working. This is the current kick code:
#bot.command(name="kick", aliases=["k"], help= "Kicks specified user from the server.")
async def kick(ctx, member: discord.Member, *, reason=None):
await member.kick(reason=reason)
await ctx.send(f'User {member} has been kicked.')
embed=discord.Embed(
title= f"{bot.user} kicked {member}",
color=bot.embed_color,
timestamp = datetime.datetime.now(datetime.timezone.utc)
)
embed.set_author(
name = ctx.author.name,
icon_url = ctx.author.avatar_url
)
embed.set_footer(
text = bot.footer,
icon_url = bot.footerimg
)
await bot.debug_channel.send(embed = embed)
print("Sent and embed")
await ctx.message.add_reaction('✅')
print("Added a reaction to a message")
Does anyone know how to make the bot send a DM?
You have to send a message to the kicked user.
Since you already have the member object, you can just do await member.send("What you want to send")
Also the message should be before await member.kick(), as the bot will not be able to message people that they don't have mutual servers with.
Another thing you should do is check if the user is kickable before sending a message to the member.
Some cases in which you can not kick the user are:
They have a higher role than the discord bot. (Can be solved by comparing the member.top_role and the bots top role)
They do not have permissions to kick. (Can be solved by checking for bots guild permissions)
Another thing is that you should also create a try except to catch any errors that can occur when trying to message the user. Some users have DM's off, so you would get an error when trying to message the member.
When I run my kick/ban command, I want it to send an embed to the channel the command is executed in to announce who has been banned. I have it in the code, but it doesn't post when the user is kicked. How would I fix this?
#commands.has_permissions(kick_members=True)
async def kick(context, member : discord.Member, *, reason=None):
# Conditions
if reason == None:
await context.channel.send("**``Please provide a reason for why this member should be kicked!``**", delete_after=3)
else:
# Await Kick
await member.kick(reason=reason)
# Send Embed in Server
myEmbed = discord.Embed(title="CRYPTIC Moderation", color=0x000000)
myEmbed.add_field(description=f'{member.mention} has been successfully kicked for: **``{reason}``**!')
myEmbed.set_footer(icon_url=context.author.avatar_url, text=f'Invoked by {context.message.author}')
await context.message.channel.send(embed=myEmbed)
# DM Kicked User
if member.dm_channel == None:
await member.create_dm()
await member.dm_channel.send(
content=f"You have been kicked from **``{context.guild}``** by {context.message.author} for **``{reason}``**!"
) ```
The DM part works in both commands, but the embed doesn't work in either. Thank you.
The problem is, that instead of just adding a description to the embed, you add a field, but fields have name and value, and not description. So instead, set the description where you set the embed title:
##bot.command or something similar is missing here. Copy and paste error?
#commands.has_permissions(kick_members=True)
async def kick(context, member : discord.Member, *, reason=None):
# Conditions
if reason == None:
await context.channel.send("**``Please provide a reason for why this member should be kicked!``**", delete_after=3)
else:
# Await Kick
await member.kick(reason=reason)
# Send Embed in Server
myEmbed = discord.Embed(title="CRYPTIC Moderation", color=0x000000, description=f'{member.mention} has been successfully kicked for: **``{reason}``**!') #add the description where you add the title
myEmbed.set_footer(icon_url=context.author.avatar_url, text=f'Invoked by {context.message.author}')
await context.message.channel.send(embed=myEmbed)
# DM Kicked User
if member.dm_channel == None:
await member.create_dm()
await member.dm_channel.send(
content=f"You have been kicked from **``{context.guild}``** by {context.message.author} for **``{reason}``**!"
) ```
I'm trying to create a verification function for Discord Bot using buttons. I have tried creating it, but not sure if it works (testing purpose) .
I need it to give a role to verify a user like a role called Verified, would also like a suggestion on how I can make it not a command and just make it a embed in a single channel where new members can just simply click on it and get the role to be verified.
I'm not getting any errors in the console of development, it's just saying when I click the button in the UI (Discord App) I get an message saying "Interaction failed".
#client.command()
async def verify(ctx):
member = ctx.message.author
role = get(member.guild.roles, name="Sexy EGirl")
await ctx.send(
embed = discord.Embed(description="Click below to verify", color=getcolor(client.user.avatar_url)),
components = [
Button(style=ButtonStyle.blue, label = 'Verify')
]
)
interaction = await client.wait_for("button_click", check=lambda i: i.component.label.startswith("Verify"))
await interaction.respond(member.add_roles(role))
You get "Interaction failed", if you don't send a respond message.
#client.event
async def on_button_click(interaction):
message = interaction.message
button_id = interaction.component.id
if button_id == "verify_button":
member = message.guild.get_member(interaction.user.id)
role = message.guild.get_role(859852728260231198) # replace role_id with your roleID
await member.add_roles(role)
response = await interaction.respond(embed=discord.Embed(title="Verified"))
#client.command()
#commands.has_permissions(administrator=True) # you need to import command from discord.ext if you want to use this -> from discord.ext import commands
async def verify(ctx):
await ctx.send(
embed=discord.Embed(title="Embed - Title", description="Click below to verify"),
components=[
Button(style=ButtonStyle.blue, label='Verify', custom_id="verify_button")
])
With this code you are able to send an embed with a verify button in a channel. (if you have administrator permissions) Then the user can press on the button and the on_button_click event will be triggered.
To handle the Interaction failed, you are sending a respond message.
I have tried different options, and this one was the one that I desired the most, but I cannot seem to get it working. Could I get some help? (Sorry I am very new to coding)
This is my code:
import discord
from discord.ext import commands
client = discord.Client()
bot = commands.Bot(command_prefix='-')
#bot.command()
async def speak(ctx, *, text):
if ctx.message.author.id == ID here:
message = ctx.message
await message.delete()
await ctx.send(f"{text}")
else:
await ctx.send('I need text!')
Thanks
Your else statement makes little sense here. It is best to set up the condition differently, that you want text once and if that does not happen, then there is an else argument.
I don't know if this is relevant either, but apparently it looks like you want only one person to be able to execute this command. For the owner there would be:
#commands.is_owner()
But if you want to make it refer to another person use:
#bot.command()
#commands.is_owner() # If you want to set this condition
async def say(ctx, *, text: str = None):
if ctx.message.author is not ID_You_Want:
await ctx.send("You are not allowed to use the command.")
return # Do not proceed
if text is None: # If just say is passed with no text
await ctx.send("Please insert a text.")
else:
await ctx.send(text) # Send the text
Optional: You can also delete the command that was send with ctx.message.delete()
Your command is not executing because you defined client and bot.
Simply remove client = discord.Client() and you will be fine.