为什么这个 Discord 机器人告诉我 :kick 是一个未定义的值?

我是做 Discord 机器人的新手,我正在使用 discordia 库。目前,我正在制作一个踢人命令,但不知什么原因,当我尝试踢被提到的用户时,它会显示 "bot.lua:52: attempt to call method 'kick' (a nil value)"。但是,如果我尝试踢发送消息的人,它就可以正常工作。

client:on("messageCreate", function(msg)
local content = msg.content
local member = msg.member
local channel = msg.guild
local Author = msg.author

if content:sub(1,5) == prefix.."kick" then
    local isMod = false

    local function checkIfIsMod()
        for i, v in pairs(member.roles) do
            if v.name:lower() == "admin" then
                isMod = true
            end
        end
    end

    checkIfIsMod()

    if isMod then
        print("yes")
        if #msg.mentionedUsers > 1 then

        msg:reply("一次只能提及一个用户!")

        elseif #msg.mentionedUsers == 0 then

        msg:reply("请提及一个人!")

        elseif #msg.mentionedUsers == 1 then
        local mentioned = msg.mentionedUsers[1]

        mentioned:kick()
        msg:reply("已踢出该用户!")
        end
    else
        msg:reply("您不是管理员!")
    end
end

end)

点赞
用户12514997
用户12514997

我并不完全了解 Discordia,但我已经阅读了文档并进行了测试,并希望现在能澄清问题:

每个连接的人都有两个机器人了解的对象:UserMember。用户是 Discord 帐户,成员是服务器上的某个人。实际上:您作为用户登录到Discord。您是多个服务器成员

您无法踢出用户,因为用户未连接到服务器。成员是。 kick 是成员的方法。

msg.author 返回 Usermsg.member 返回 Member。您在帖子中说您可以踢写消息的人。您没有展示此代码,但我必须假设您正在调用 msg.member 上的 kick,因为它不会在 msg.author 上工作。

当您提及用户时,它们会作为 ID 列表返回(msg.mentionedUsers)。每个 ID 有一个用户,但用户可以是跨多个服务器的多个“成员”。您需要获得被提及的 User 和调用提及所在的公会(服务器)之间的成员关系。您可以使用 Guild:getMember(ID) 实现此目的。根据文档,您也可以使用 Guild.members:get(ID),但是这是缓存的。离线成员不一定会被缓存(已知于方法),因此我发现使用 Guild:getMember(ID) 更安全(它将发出 HTTP 请求)。您可以使用 msg.guild 获取公会(如在原始代码中所示)。

以下是可工作的代码,用于遍历所有被提到的用户并将其踢出。如果您愿意,可以重新组织此代码以踢出第一个人。您可以将其放在 if isMod then 语句中。

for id in msg.mentionedUsers:iter() do
    local u = msg.guild:getMember(id)
    print("kicking", u.name)
    u:kick()
end
2020-05-14 23:19:30