【问题标题】:massban / massunban commands only work for users within the server. How can I make it so it also bans/unbans users not in the server?massban / massunban 命令仅适用于服务器内的用户。我怎样才能使它也禁止/取消禁止不在服务器中的用户?
【发布时间】:2021-03-26 13:13:44
【问题描述】:

所以我一直在尝试创建两个命令——一个禁止多个用户,另一个取消多个用户的禁令;massban 和 massunban。

这两个命令对服务器中的用户有效,但需要注意的是它不适用于不在服务器中的 ID。

这里的想法是做 !massban ID ID ID ID (...) 和 !massunban ID ID ID ID ID (...)

    @commands.command(name="massban")
    @commands.has_any_role("Admin", "Moderator", "Bot")
    async def massban(self, context, *user_ids: int):
        for u in user_ids:
            user_object = self.client.get_user(u)
            await context.guild.ban(user_object)

    @commands.command(name="massunban")
    @commands.has_any_role("Admin", "Moderator", "Bot")
    async def massunban(self, context, *user_ids: int):
        for u in user_ids:
            user_object = self.client.get_user(u)
            await context.guild.unban(user_object)

问题是这会返回如下错误

上述异常是以下异常的直接原因:

Traceback (most recent call last):
  File "C:\Users\Dazz\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\ext\commands\bot.py", line 903, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\Dazz\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\ext\commands\core.py", line 859, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\Dazz\AppData\Local\Programs\Python\Python38\lib\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: AttributeError: 'NoneType' object has no attribute 'id'

我一直在查看文档,到处寻找解决此问题的方法;我在一些 Discord 服务器上寻求帮助,但无济于事。

任何帮助将不胜感激。

【问题讨论】:

  • 您是否启用了意图?
  • 已启用! intents = discord.Intents.default() intents.members = True client = discord.Client(intents=intents) client = commands.Bot(command_prefix="!", intents=intents)

标签: python discord discord.py


【解决方案1】:

问题是,用户不会自动加载到缓存中。所以 Discord.py 无法从缓存中获取用户。这里的解决方案是使用.fetch_user()。这是一个您不应该使用但在这种情况下必须使用的 API 调用。

所以修改后的代码如下:

@commands.command(name="massban")
@commands.has_any_role("Admin", "Moderator", "Bot")
async def massban(self, context, *user_ids: int):
    for u in user_ids:
        user_object = await self.client.fetch_user(u)
        await context.guild.ban(user_object)

@commands.command(name="massunban")
@commands.has_any_role("Admin", "Moderator", "Bot")
async def massunban(self, context, *user_ids: int):
    for u in user_ids:
        user_object = await self.client.fetch_user(u)
        await context.guild.unban(user_object)

【讨论】:

  • 非常感谢!我还在self.client.fetch_user(u) 旁边添加了等待,因此它可以修复enable tracemalloc to get the object allocation traceback 错误!它看起来像这样user_object = await self.client.fetch_user(u)
  • 哦,对了,总是忘记等待 xD,不客气
【解决方案2】:

添加到 FlexGames 答案中。在 1.6 版本中,如果您提供了 ID,discord.py UserConverter 已经获取了给出的用户并检查该 ID 是否有效。答案可以缩短。 UserConverter 还接受名称/提及/ID,这是一个奖励。这里说明UserConverter

这是精简版

@commands.command(name="massban")
@commands.has_any_role("Admin", "Moderator", "Bot")
async def massban(self, ctx, *users: discord.User):
    # map calls ctx.guild.ban for each users
    # asyncio.gather awaits each coroutine concurrently
    await asyncio.gather(*map(ctx.guild.ban, users))

@commands.command(name="massunban")
@commands.has_any_role("Admin", "Moderator", "Bot")
async def massunban(self, ctx, *users: discord.User):
    await asyncio.gather(*map(ctx.guild.unban, users))

【讨论】:

  • 也非常感谢分享这个方法!赞成。
猜你喜欢
  • 2021-09-09
  • 2019-09-03
  • 2021-03-30
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 2019-10-11
  • 2021-09-15
  • 2015-12-09
相关资源
最近更新 更多