luawebhooksrobloxhttpservice

Error attempt to concatenate Instance with string after passing in strings


So I am trying to make a game where in StarterCharacterScripts in a local script upon touching a part called WinPad for it to fire an event, which send a message in chat, and send a PostAsync() to a Discord webhook. However, upon firing the event it gives the error attempt to concatenate Instance with string even though all passed in arguments are strings. Here is the event firer in LocalScript:

        local name = tP:FindFirstChild("TowerName")
        local diff = tP:FindFirstChild("Difficulty")
        local diffid = tP:FindFirstChild("DifficultyId")
        local diffcolor = tP:FindFirstChild("DiffColor3")
        game.ReplicatedStorage.WinEvent:FireServer(game.Players.LocalPlayer.Name, name.Value, diff.Value, diffid.Value, diffcolor.Value)

Here is the OnServerEvent:Connect() script:

game.ReplicatedStorage.WinEvent.OnServerEvent:Connect(function(plr, towername, towerdiff, towerdiffid, color)
    local HookData = {
            ['content'] = "**"..plr.."** has beaten **"..tostring(towername).." [<:"..tostring(towerdiff)..":"..tostring(towerdiffid)..">]**."
    }
    HookData = http:JSONEncode(HookData)
    http:PostAsync(url, HookData)
    plr.Parent:MoveTo(Vector3.new(-764, 12.5, -54.5))
    createSystemMessage:FireAllClients((plr.." has beaten "..towername.."."), color, Enum.Font.SourceSansBold, Enum.FontSize.Size14)
end)

Also, tP is the part that is touched by the LocalPlayer.Character.Humanoid


Solution

  • When you use a RemoteEvents' OnServerEvent signal, the first parameter is always the Player that used the FireServer function, and that is provided automatically by the engine. Your function signature should look like this :

    function(player, plrname, towername, towerdiff, towerdiffid, color)
    

    But, there's no need to provide the player name, because you could get that from player.Name. So to fix your problem and clean up your code, I would recommend this in your LocalScript :

    local winevent = game.ReplicatedStorage.WinEvent
    
    local name = tP.TowerName.Value
    local diff = tP.Difficulty.Value
    local diffid = tP.DifficultyId.Value
    local diffcolor = tP.DiffColor3.Value
    
    winevent:FireServer(name, diff, diffid, diffcolor)
    

    And this in your server Script :

    local winEvent = game.ReplicatedStorage.WinEvent
    winEvent.OnServerEvent:Connect(function(player, towername, towerdiff, towerdiffid, color)
        -- format some messages
        local message = "%s has beaten %s."
        local hookMessage = string.format(message,
            "**" .. player.Name .. "**",
            string.format("**%s [<:%s:%s>]**", towername, towerdiff, towerdiffid))
        local playerMessage = string.format(message, player.Name, towername)
    
        -- fire some data to some server
        local HookData = {
                ['content'] = hookMessage,
        }
        HookData = http:JSONEncode(HookData)
        http:PostAsync(url, HookData)
    
        -- move the player's character somewhere
        player.Character:MoveTo(Vector3.new(-764, 12.5, -54.5))
    
        -- alert everyone that stuff has happened
        createSystemMessage:FireAllClients(playerMessage, color, Enum.Font.SourceSansBold, Enum.FontSize.Size14)
    end)