【问题标题】:Discord.py trouble with move_member()与 move_member() 的 Discord.py 问题
【发布时间】:2018-02-14 06:28:31
【问题描述】:

我在将move_member() 用于 python 机器人时遇到问题。该命令的目的是通过将用户移动到频道来“踢”用户,然后将其删除,以便他们断开语音呼叫,但不需要返回服务器的邀请。我知道仅移动用户即可实现此目的,但我希望用户断开连接。

import discord
import random
import time
import asyncio
from discord.ext import commands
from discord.ext.commands import Bot

bot = commands.Bot(command_prefix="!")

@bot.event
async def on_ready():
    await bot.change_presence(game=discord.Game(name='with fire'))
    print("Logged in as " + bot.user.name)
    print(discord.Server.name)


@bot.command(pass_context=True)
async def kick(ctx,victim):
    await bot.create_channel(message.server, "kick", type=discord.ChannelType.voice)
    await bot.move_member(victim,"kick")
    await bot.delete_channel("bad boi")

bot.run('TOKEN_ID')

该行给出了错误:

提供的频道必须是语音频道

await bot.move_member(victim,"kick")

这一行给出了这个错误:

'str' 对象没有属性 'id'

await bot.delete_channel("kick")

我很确定您必须获取频道 ID 而不是“踢”,但我不知道该怎么做,因为下面的代码不起作用,即使我替换 ChannelType.voicediscord.ChannelType.voice

discord.utils.get(server.channels, name='kick', type=ChannelType.voice)

【问题讨论】:

  • 只是为了在同一页面上,如果用户还没有语音,您不能将成员移动到语音聊天聊天。 Discord 只是不支持。
  • 看起来 OP 想要进行语音聊天,而不是真正的踢。如果是这样,下一个明显的事情就是 OP 不会踢不在语音聊天中的人。

标签: python discord


【解决方案1】:

delete_channel('kick') 将不起作用,因为您需要传入 channel 对象而不是字符串。

你不需要使用 discord.utils 来获取你想要的频道。 create_channel 返回一个通道对象,所以你应该可以使用它。

但是,您确实需要获取您要踢的Member 对象。您还犯了引用message.server 而不是ctx.message.server 的错误

@bot.command(pass_context=True)
async def kick(ctx, victim):
    victim_member = discord.utils.get(ctx.message.server.members, name=victim)
    kick_channel = await bot.create_channel(ctx.message.server, "kick", type=discord.ChannelType.voice)
    await bot.move_member(victim_member, kick_channel)
    await bot.delete_channel(kick_channel)

现在,如果您使用重写库,则必须执行以下操作

@bot.command()
async def kick(ctx, victim):
    victim_member = discord.utils.get(ctx.guild.members, name=victim)
    kick_channel = await ctx.guild.create_voice_channel("kick")
    await victim_member.move_to(kick_channel, reason="bad boi lul")
    await kick_channel.delete()

正如 cmets 中提到的 abccd,这被评估为一个字符串,这并不能保证你会踢到正确的人。 discord.utils.get 将获取第一个结果,如果多个用户具有相同的名称,则不一定是正确的用户。

更好的方法是使用@user 或使用用户ID。这是旧库中的一个示例

@bot.command(pass_context=True)
async def kick(ctx):
    victim = ctx.message.mentions[0]
    kick_channel = await bot.create_channel(ctx.message.server, "kick", type=discord.ChannelType.voice)
    await bot.move_member(victim,kick_channel)
    await bot.delete_channel(kick_channel)

我强烈建议您开始使用 rewrite 库,因为它更像 Pythonic 并且无论如何它将成为未来的新库。

【讨论】:

  • 您几乎完整的答案的唯一问题是discord.utils.get 返回具有给定名称的第一个成员,频道中可能有多个成员具有相同的名称(在一个人口众多的频道)。受害者可能不是 OP 真正想要踢的实际成员
  • 是的,你是对的。更好的方法是通过 @ 引用成员或提供用户 ID。我将编辑我的答案以使用 @ 作为示例,但由 OP 决定他希望如何实施(或同时实施)
  • 它工作正常,而且它适用于我自己的服务器,大多数时候只有
  • Here 是 Rewrite 库的文档。我同意有时文档可能难以阅读。你只需要磨砺它。您还可以尝试查找其他开源机器人,例如我的:here,并阅读它们的源代码。还有一个用于所有 API 的不和谐服务器,您可以在其中获得易于访问的帮助,邀请链接是 here
  • 谢谢,我之前已经使用过 Discord 服务器,但它们表现得好像您应该事先了解 API 和 Discord 的来龙去脉,但提供的帮助不如他们在 Stack 上提供的那么多溢出。
【解决方案2】:

根据Discord documentation,对delete_channel 的调用需要Channel 类型的参数。

有关Channel 类的更多信息,请参阅the Channel documentation

如果我了解您正在尝试做什么,为了让您的代码按预期运行,您将需要维护对您用作临时频道的频道的引用,然后更改您的违规行:

await bot.delete_channel(tmp_channel)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 2021-01-21
    • 2020-08-31
    相关资源
    最近更新 更多