【问题标题】:What is the correct way to make a ban command in discord.py?在 discord.py 中发出禁令命令的正确方法是什么?
【发布时间】:2022-01-13 00:34:34
【问题描述】:

我正在制作一个名为 Excelsior 的不和谐机器人。它的命令之一是禁止命令,顾名思义,就是禁止用户访问服务器。

这是针对我的错误的代码:

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])

它的工作方式是将命令拆分为一个列表。然后它获取列表中的第二项,它必须是用户的用户名,并将其插入到我的完整代码中的禁令命令中(见下文)。

然而,每当我运行e? ban [user] 命令时,程序都会给我一个错误,即用户名的字符串没有ban 属性。我相信这是因为我将文字字符串传递给函数。

我的问题是如何将用户名(或 id)输入到机器人中,以便禁令功能实际上可以找到用户名?我如何让它发挥作用?

这是机器人的代码: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"))

我已经看过以下问题:

  • Discord.py ban command。这不能回答我的问题,因为虽然它提供了实际的 ban 函数,但它没有解决我想在运行 ban 命令后运行该命令。同样在那个问题中,用户ID是直接输入到函数中的,但我没有那种奢侈。

如果需要更多信息,我很乐意提供。


在 cmets 中进行对话后,我编写了一个 MCVE,它应该根据 cmets 工作,但它没有。

这是 MCVE 的代码(要短得多):

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"))

然而,上面的代码甚至不承认e? ban 命令。在 cmets 中有人告诉我,我可以按照我现在的方式来做。

应该如何处理?

【问题讨论】:

  • 如果您要在on_message 事件处理程序中重新发明整个命令前缀系统,为什么还要从Bot 继承而不是Client?或者更重要的是,为什么不将你的命令前缀设置为'e? ' 并为自己省去很多麻烦?
  • @CrazyChucky 我不知道我重新发明了前缀系统。如果我使用内置前缀系统,它可以解决我的问题吗?
  • 简短的回答是,是的。可以按照您设置的方式进行操作,但将这些命令(helpban 等)中的每一个设置为实际的@bot.command 会更简单。这就是它的目的。
  • @CrazyChucky 感谢您的帮助,非常感谢!您介意写一个答案,以便我能完全理解您的意思吗?
  • 你的意思是把bot = Bot("!")改成bot = Bot("e? ")吗?我不确定如何准确地实现它。

标签: python discord.py


【解决方案1】:

首先 on_message 事件仅作为参数 message

第二您的代码一团糟,您同时使用clientbot 作为您的命令,client2 应该是什么意思?我可以看到您可能对 dpy 或 python 一般没有太多经验,但是,在提出问题之前,我建议您至少做最少的努力并阅读该库的文档,那里有明确的示例。

如果您决定使用client,请选择:

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

第三:禁止命令

@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")

你有它,一个非常基本的命令,如果你已经有这段代码client = commands.Bot(command_prefix=" "),请停止在on_message事件上使用前缀

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-10
    • 2021-07-27
    • 2014-12-09
    • 2018-11-07
    • 2017-02-13
    • 2015-04-18
    • 2012-10-27
    • 1970-01-01
    相关资源
    最近更新 更多