简体   繁体   中英

What is the correct way to make a ban command in discord.py?

I am making a discord bot called Excelsior. One of it's commands is a ban command, which, true to it's name, bans a user from the server.

Here is the code that is specific to my error:

elif message.content.startswith("e? ban"):
    li = list(message.content)
    if len(li) == 2:
      await message.channel.send("Who do I ban?")
    else:
      await ban(message, li[2])

The way it's supposed to work is by splitting the command into a list. Then it takes the 2nd item in the list, which has to be the username of the user, and it plugs that into the ban command which is in my full code (see below).

Whenever I run the e? ban [user] e? ban [user] command however, the program gives me an error that the string of the username does not have an attribute ban . I believe this is because I am passing a literal string into the function.

My question is how do I input the username (or id) into the bot such that the ban function can actually find out the username? How do I get this to work?

Here is the code for the bot: 1

import discord
import os
import random
from keep_alive import keep_alive
from discord_components import DiscordComponents, Button, ButtonStyle, InteractionEventType
from discord.ext.commands import Bot
from discord.ext import commands

client = discord.Client()
bot = Bot("!")

@client.event
async def on_ready():
  print("Ready! {0.user}".format(client))

@bot.command()
@commands.has_permissions(administrator = True)
async def ban(ctx, member: discord.Member, reasons = "No reason"):
  await member.ban(reason = reasons)
@client.event
async def on_message(message, member= discord.Member):
  if message.author == client.user:
    pass
  
  elif message.content.startswith("e? help"): 
    embed = discord.Embed(title = "Commands", description = "Excelsior is a powerful bot you can use to gamify and manage your server. ", color = 0x66ccff)
    embed.add_field(name = "Commands:", value = "`e? help` \n `e? roll` \n `e? copy` \n `e? work`")
    await message.channel.send(embed = embed)
  
  elif message.content.startswith("e? roll"):
    embed = discord.Embed(title = "Roll a die :game_die:", description = "This command rolls a die and gives you a random number between 1 and 6.", color = 0xff000)
    embed.add_field(name = "Your number:", value = random.randint(1, 6))
    await message.channel.send(embed = embed)
  
  elif message.content.startswith("e? copy"):
    list_of_words = message.content.split(" ")
    if len(list_of_words) == 2:
      embed = discord.Embed(title = "Invalid Syntax!", description = "The format for the `e? copy` is this: ", color = 0xff0000)
      embed.add_field(name = "`e? copy (what you want me to say)`", value = "I need something to copy!")
      await message.channel.send(embed = embed)
    else: 
      string = ""
      for item in list_of_words[2:len(list_of_words)]:
        string += item
        string += " "
      message_sent = "\""+string+"\""
      await message.channel.send(message_sent)
  
  elif message.content.startswith("e? work"):
    num1 = random.randint(1, 10)
    op = ["*", "/", "+", "-"]
    num2 = random.randint(1, 10)
    equation = str(num1) + random.choice(op) + str(num2)
    corr = random.randint(1, 4)
    button = []
    for i in range(4):
      if corr == i:
        button.append(Button(label = int(eval(equation))))
      else:
        button.append(Button(label = random.randint(1, int(eval(equation) - 1))))
    mess = str(equation) + "\n" + "Click one of the buttons below. _Choose the wrong answer and you lose money!_ :sob:"
    embed = discord.Embed(title = "What is the correct answer to the problem below?", description = mess, color = 0x0000ff)
    await message.channel.send(embed = embed, components = button)
    """@client.event
    async def on_button_click(interaction):
      if interaction.component.label.startswith("ha"):
        await interaction.respond(type = InteractionEventType.ChannelMessageWithSource, content = 'clicked')
      else:
        await interaction.respond(type = InteractionEventType.ChannelMessageWithSource, content = "clicked2")"""
  elif message.content.startswith("e? ban"):
    li = list(message.content)
    if len(li) == 2:
      await message.channel.send("Who do I ban?")
    else:
      print(message.author)
      await ban(message, li[2])
keep_alive()
client.run(os.getenv("TOKEN"))

I have already looked at the following questions below:

  • Discord.py ban command . This doesn't answer my question because while it provides the actual ban function, it doesn't address that I want to run the command after I run the ban command. Also in that question, the user id is directly inputted into the function but I don't have that kind of luxury.

If any more information is needed I am happy to provide it.


After a conversation in the comments, I have written an MCVE that is supposed to work according to the comments, however it doesn't.

Here is the code of the MCVE (it is much shorter):

import discord
import os
import random
from keep_alive import keep_alive
from discord_components import DiscordComponents, Button, ButtonStyle, InteractionEventType
from discord.ext.commands import Bot
from discord.ext import commands
 
client2 = commands.Bot(command_prefix = "e? ")
client = discord.Client()
bot = Bot("e? ")
 
@client.event
async def on_ready():
  print("Ready! {0.user}".format(client))
 
@client2.command(name = "ban")
@commands.has_permissions(administrator = True)
async def ban(ctx, member: discord.Member, reasons = "No reason"):
  await member.ban(reason = reasons)
 
keep_alive()
client.run(os.getenv("TOKEN"))

However, the above code does not even acknowledge the e? ban e? ban command. I was told in the comments that I can do it the way I am doing it right now.

How should this be approached?

First of all : on_message event takes as argument just message

Second : your code is a whole mess, you use both client and bot for your commands and what's supposed to mean client2 ? i can see you probably don't have much experience with dpy or maybe python in general, though, before asking a question i recommend you do at least a minimum of effort and read the documentation of the library, you have clear examples in there.

if you decide to use client then go for:

client = commands.Bot(command_prefix=" ") # your prefix between " "

Third: Ban command

@client.command()
@commands.has_permissions(administrator=True) # though imo i would put just ban_members perm for this.
async def ban(ctx, member: discord.Member = None, *, reason=None)
    if member == ctx.author:
       await ctx.send("You can't ban yourself")
       return
    await member.ban(reason=reason)
    await ctx.send("User banned")

There you have it, a pretty basic command, and stop using the prefix on on_message event if you have this piece of code already client = commands.Bot(command_prefix=" ")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM