0

I'm trying to write a Discord bot with Lua and the Discordia library. I've been trying to implement a way for it to check whether the person running the command has a role to do so. The id for that role is the adminid variable. The bot was working until I implemented the permissions check and now it crashes with

Uncaught Error: .../Documents/Lua Projects/DiscordBot/deps/coro-channel.lua:62: ...rojects/DiscordBot/deps/discordia/libs/utils/Emitter.lua:105: ...cts/DiscordBot/deps/discordia/libs/containers/Member.lua:312: attempt to index local 'self' (a number value) stack traceback: [C]: in function 'assert' .../Documents/Lua Projects/DiscordBot/deps/coro-channel.lua:62: in function 'onPlain' ...s/Lua Projects/DiscordBot/deps/secure-socket/biowrap.lua:76: in function <...s/Lua Projects/DiscordBot/deps/secure-socket/biowrap.lua:61> [C]: in function 'run' [string "bundle:/init.lua"]:52: in function <[string "bundle:/init.lua"]:47> [C]: in function 'xpcall' [string "bundle:/init.lua"]:47: in function 'fn' [string "bundle:deps/require.lua"]:310: in function <[string "bundle:deps/require.lua"]:266> whenever you run the command. I have no idea what the problem is so I'm asking you guys. Here's my full code if anyone can help me out.

local discordia = require("discordia")
local coro = require("coro-http")
local json = require("json")
local client = discordia.Client()

adminid = 726406258730598451

local commands = {
    {Command = "-ping", Description = "Replies with pong!"};
    {Command = "-norris", Description = "Replies with a Chuck Norris fact!"};
    {Command = "-cool [mentionedUser]", Description = "Says how cool the mentioned use is! If no one is mentioned it replies with how cool you are!"};
}

function chuckNorris(message)
    coroutine.wrap(function()
        local link = "https://api.chucknorris.io/jokes/random"
        local result, body = coro.request("GET", link)
        body = json.parse(body)
        message:reply("<@!"..message.member.id.."> "..body["value"])
        
    end)()
    
end

client:on("messageCreate", function(message)
    local content = message.content
    local member = message.member
    local memberid = message.member.id
    if content:lower() == "-ping" then
        message:reply("pong")
        
    end
    if content:lower() == "-norris" then
        chuckNorris(message)
        
    end 
    if content:lower():sub(1,#"-cool") == "-cool" then
        local mentioned = message.mentionedUsers
        if #mentioned == 1 then
            message:reply("<@!"..mentioned[1][1].."> is "..math.random(1,100).."% cool.")
            
            elseif #mentioned == 0 then
            message:reply("<@!"..memberid.."> is "..math.random(1,100).."% cool.")
            
        end
        
    end
    if content:lower() == "-help" then
        local list = ""
        for i,v in pairs(commands) do
            list = list..v.Command..": "..v.Description.."\n"
            
        end
        message:reply(list)
        
    end
    if content:lower():sub(1,#"-ban") == "-ban" then
        local mentioned = message.mentionedUsers
        if #mentioned == 1 then
            message:reply("<@!"..mentioned[1][1].."> has been banned.")
            member.guild:banUser(mentioned[1][1],_,_)
            
            elseif #mentioned == 0 then
            message:reply("Error: Incorrect Syntax = -ban [user]")
            
            elseif #mentioned >= 1 then
            message:reply("Sorry that operation isn't supported yet.")
            
        end
        
    end
    if content:lower():sub(1,#"-unban") == "-unban" then
        local mentioned = message.mentionedUsers
        if #mentioned <= 1 then
            message:reply("<@!"..mentioned[1][1].."> has been unbanned.")
            member.guild:unbanUser(mentioned[1][1],_)
            
            elseif #mentioned >= 1 then
            message:reply("Sorry that operation isn't supported yet.")
            
        end
        
    end
    if content:lower():sub(1,#"-kick") == "-kick" then
        local mentioned = message.mentionedUsers
        if member.hasRole(adminid) == true then
            if #mentioned <= 2 then
                message:reply("<@!"..mentioned[1][1].."> has been kicked for ")
                member.guild:kickUser(mentioned[1][1],_)
                
                elseif #mentioned == 0 then
                message:reply("Error: Incorrect Syntax = -kick [user]")
                
                
                elseif #mentioned >= 2 then
                message:reply("Sorry that operation isn't supported yet.")
                
            end
        else
            message:reply("You do not have permission to run that command.")
        end
    end
        
end)

client:run("Bot "..io.open("./login.txt"):read())
  • 1
    you have a function call with `.` where you're supposed to use `:` and your first parameter is a number value. in that function this makes self a number value where it is supposed to be a table. anything else can be obtained from the call stack. happy debugging – Piglet Jun 27 '20 at 12:46

2 Answers2

2

You are calling a function using the . operator, instead of the : operator, this causes the first parameter of the called function (known as self) to be invalid. This is because when you call thing:function(parameter), lua actually calls thing.function(thing, parameter). The error message states that self (which is the variable name commonly used for this first parameter), was indexed (like self[2] or self.b), but self was a number value (adminid).

To fix this simply change

if member.hasRole(adminid) == true then

to

if member:hasRole(adminid) == true then

Additionally, testing == true is not necessary because it will only return true if the right side it true, which does nothing (unless your testing for specifically the boolean type, but this is usually not the case).

BEN1JEN
  • 71
  • 1
  • 7
0

If you continue needing the answer.
Change message.member to message.author
this will return the user, to get the member do (for a guild) message.guild:getMember(author or author.id)