Ban Command System

Hello! I’ve created the following ban script, designed to not only ban users but also send a webhook to a Discord server and create a card on Trello. Despite troubleshooting and trying various fixes, it still won’t work. Any assistance would be greatly appreciated!

local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")

local discordWebhookUrl = "https://webhook.lewisakura.moe/api/"
local trelloKey = ""
local trelloToken = ""
local trelloBoardId = ""
local trelloListId = ""
local groupId = 

local function generateCaseID()
    local randomDigits = math.random(1000, 9999)
    return "GB" .. randomDigits
end

local function getRobloxProfilePicture(userId)
    return "https://www.roblox.com/headshot-thumbnail/image?userId=" .. userId .. "&width=420&height=420&format=png"
end

local function formatDuration(duration)
    if not duration then
        return "Permanent", "Permanent"
    end

    local amount, unit = duration:match("(%d+)([mhdwmy])")
    local durationText, durationTimestamp
    if unit == "m" then
        durationText = amount .. " Minutes"
        durationTimestamp = os.time() + (tonumber(amount) * 60)
    elseif unit == "h" then
        durationText = amount .. " Hours"
        durationTimestamp = os.time() + (tonumber(amount) * 3600)
    elseif unit == "d" then
        durationText = amount .. " Days"
        durationTimestamp = os.time() + (tonumber(amount) * 86400)
    elseif unit == "w" then
        durationText = amount .. " Weeks"
        durationTimestamp = os.time() + (tonumber(amount) * 604800)
    elseif unit == "m" then
        durationText = amount .. " Months"
        durationTimestamp = os.time() + (tonumber(amount) * 2592000)
    elseif unit == "y" then
        durationText = amount .. " Years"
        durationTimestamp = os.time() + (tonumber(amount) * 31536000)
    else
        return "Permanent", "Permanent"
    end

    return durationText, "<t:" .. math.floor(durationTimestamp) .. ":F>"
end

local function getFormattedDateTime()
    local dateTime = os.date("*t")
    return string.format("%02d/%02d/%04d %02d:%02d:%02d %s EST", 
        dateTime.month, dateTime.day, dateTime.year, 
        (dateTime.hour % 12 == 0) and 12 or (dateTime.hour % 12), 
        dateTime.min, dateTime.sec, 
        dateTime.hour >= 12 and "PM" or "AM")
end

local function hasRequiredRole(player)
    local roleRank = player:GetRankInGroup(groupId)
    return roleRank >= 247 or (roleRank >= 241 and roleRank <= 242) or (roleRank >= 235 and roleRank <= 236)
end

game.ReplicatedStorage.BanUser.OnServerEvent:Connect(function(player, targetUsername, reason, duration)
    if not hasRequiredRole(player) then
        player:Kick("You do not have permission to use this command.")
        return
    end

    local targetPlayer = Players:FindFirstChild(targetUsername)
    if not targetPlayer then
        player:Kick("User not found.")
        return
    end

    local caseID = generateCaseID()
    local durationText, durationTimestamp = formatDuration(duration)
    targetPlayer:Kick("Banned: " .. reason .. " | Case ID: " .. caseID)

    local discordData = {
        ["embeds"] = {{
            ["title"] = "Ban Log",
            ["color"] = tonumber("2b2d31", 16),
            ["fields"] = {
                {["name"] = "Staff", ["value"] = "[`" .. player.Name .. "`](https://www.roblox.com/users/" .. player.UserId .. "/profile)", ["inline"] = true},
                {["name"] = "Rank", ["value"] = "[`" .. player:GetRoleInGroup(groupId) .. "`](https://www.roblox.com/users/" .. player.UserId .. "/profile)", ["inline"] = true},
                {["name"] = "User", ["value"] = targetUsername, ["inline"] = true},
                {["name"] = "Reason", ["value"] = reason, ["inline"] = true},
                {["name"] = "Ban Time", ["value"] = "Till: " .. (durationTimestamp or "Permanent"), ["inline"] = true},
                {["name"] = "Case ID", ["value"] = caseID, ["inline"] = true},
                {["name"] = "Date", ["value"] = getFormattedDateTime(), ["inline"] = true}
            },
            ["thumbnail"] = {
                ["url"] = getRobloxProfilePicture(targetPlayer.UserId)
            }
        }}
    }

    HttpService:PostAsync(discordWebhookUrl, HttpService:JSONEncode(discordData), Enum.HttpContentType.ApplicationJson)

    local trelloCardData = {
        ["name"] = caseID .. " | " .. targetUsername,
        ["desc"] = "# Game Ban\n\n" ..
                   "- **Staff Member:** [" .. player.Name .. "](https://www.roblox.com/users/" .. player.UserId .. "/profile)\n" ..
                   "- **Rank:** [" .. player:GetRoleInGroup(groupId) .. "](https://www.roblox.com/users/" .. player.UserId .. "/profile)\n" ..
                   "- **Username:** [" .. targetUsername .. "](https://www.roblox.com/users/" .. targetPlayer.UserId .. "/profile)\n" ..
                   "- **Roblox ID:** " .. targetPlayer.UserId .. "\n" ..
                   "- **Reason:** " .. reason .. "\n" ..
                   "- **Ban Time:** " .. durationText .. "\n" ..
                   "- **Case ID:** " .. caseID .. "\n" ..
                   "- **Date:** " .. getFormattedDateTime(),
        ["pos"] = "top",
        ["idList"] = trelloListId,
        ["keepFromSource"] = "all",
        ["key"] = trelloKey,
        ["token"] = trelloToken
    }

    local trelloUrl = "https://api.trello.com/1/cards"
    HttpService:PostAsync(trelloUrl, HttpService:JSONEncode(trelloCardData), Enum.HttpContentType.ApplicationJson)

    player:SendNotification({
        Title = "Ban Command",
        Text = "Successfully banned " .. targetUsername
    })
end)

So uhm, first of all u gotta have these requirements:

  • Check for HTTP Requests Enabled: ensure that HTTP requests are enabled in ur rblx game settings. This is necessary for making requests to Discord and Trello.
  • Error Handling for HTTP Requests: add error handling to your HTTP requests to capture any issues with sending data to Discord or Trello. This can help u debug where the failure is occurring.
  • Ensure Valid URLs and Credentials: double-check ur webhook URL, Trello API key, token, board ID, and list ID to ensure they are correct and active.
  • Print Debugging: use print statements to check the flow of ur script and ensure that each part is executing as expected.
  • Role Check Logic: verify ur hasRequiredRole logic. ensure the roles and rank checks are as intended.
    and if u did everything, and it didn’t work, here’s an updated script with error handling and debugging:
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")

local discordWebhookUrl = "https://webhook.lewisakura.moe/api/"
local trelloKey = "" -- Add your Trello key here
local trelloToken = "" -- Add your Trello token here
local trelloBoardId = "" -- Add your Trello board ID here
local trelloListId = "" -- Add your Trello list ID here
local groupId = 0 -- Add your group ID here

local function generateCaseID()
    local randomDigits = math.random(1000, 9999)
    return "GB" .. randomDigits
end

local function getRobloxProfilePicture(userId)
    return "https://www.roblox.com/headshot-thumbnail/image?userId=" .. userId .. "&width=420&height=420&format=png"
end

local function formatDuration(duration)
    if not duration then
        return "Permanent", "Permanent"
    end

    local amount, unit = duration:match("(%d+)([mhdwmy])")
    local durationText, durationTimestamp
    if unit == "m" then
        durationText = amount .. " Minutes"
        durationTimestamp = os.time() + (tonumber(amount) * 60)
    elseif unit == "h" then
        durationText = amount .. " Hours"
        durationTimestamp = os.time() + (tonumber(amount) * 3600)
    elseif unit == "d" then
        durationText = amount .. " Days"
        durationTimestamp = os.time() + (tonumber(amount) * 86400)
    elseif unit == "w" then
        durationText = amount .. " Weeks"
        durationTimestamp = os.time() + (tonumber(amount) * 604800)
    elseif unit == "m" then
        durationText = amount .. " Months"
        durationTimestamp = os.time() + (tonumber(amount) * 2592000)
    elseif unit == "y" then
        durationText = amount .. " Years"
        durationTimestamp = os.time() + (tonumber(amount) * 31536000)
    else
        return "Permanent", "Permanent"
    end

    return durationText, "<t:" .. math.floor(durationTimestamp) .. ":F>"
end

local function getFormattedDateTime()
    local dateTime = os.date("*t")
    return string.format("%02d/%02d/%04d %02d:%02d:%02d %s EST", 
        dateTime.month, dateTime.day, dateTime.year, 
        (dateTime.hour % 12 == 0) and 12 or (dateTime.hour % 12), 
        dateTime.min, dateTime.sec, 
        dateTime.hour >= 12 and "PM" or "AM")
end

local function hasRequiredRole(player)
    local roleRank = player:GetRankInGroup(groupId)
    return roleRank >= 247 or (roleRank >= 241 and roleRank <= 242) or (roleRank >= 235 and roleRank <= 236)
end

game.ReplicatedStorage.BanUser.OnServerEvent:Connect(function(player, targetUsername, reason, duration)
    print("BanUser event triggered by", player.Name)
    
    if not hasRequiredRole(player) then
        player:Kick("You do not have permission to use this command.")
        return
    end

    local targetPlayer = Players:FindFirstChild(targetUsername)
    if not targetPlayer then
        player:Kick("User not found.")
        return
    end

    local caseID = generateCaseID()
    local durationText, durationTimestamp = formatDuration(duration)
    targetPlayer:Kick("Banned: " .. reason .. " | Case ID: " .. caseID)

    local discordData = {
        ["embeds"] = {{
            ["title"] = "Ban Log",
            ["color"] = tonumber("2b2d31", 16),
            ["fields"] = {
                {["name"] = "Staff", ["value"] = "[`" .. player.Name .. "`](https://www.roblox.com/users/" .. player.UserId .. "/profile)", ["inline"] = true},
                {["name"] = "Rank", ["value"] = "[`" .. player:GetRoleInGroup(groupId) .. "`](https://www.roblox.com/users/" .. player.UserId .. "/profile)", ["inline"] = true},
                {["name"] = "User", ["value"] = targetUsername, ["inline"] = true},
                {["name"] = "Reason", ["value"] = reason, ["inline"] = true},
                {["name"] = "Ban Time", ["value"] = "Till: " .. (durationTimestamp or "Permanent"), ["inline"] = true},
                {["name"] = "Case ID", ["value"] = caseID, ["inline"] = true},
                {["name"] = "Date", ["value"] = getFormattedDateTime(), ["inline"] = true}
            },
            ["thumbnail"] = {
                ["url"] = getRobloxProfilePicture(targetPlayer.UserId)
            }
        }}
    }

    -- Sending Discord Webhook
    local success, response = pcall(function()
        return HttpService:PostAsync(discordWebhookUrl, HttpService:JSONEncode(discordData), Enum.HttpContentType.ApplicationJson)
    end)

    if not success then
        print("Failed to send Discord webhook:", response)
    else
        print("Discord webhook sent successfully")
    end

    local trelloCardData = {
        ["name"] = caseID .. " | " .. targetUsername,
        ["desc"] = "# Game Ban\n\n" ..
                   "- **Staff Member:** [" .. player.Name .. "](https://www.roblox.com/users/" .. player.UserId .. "/profile)\n" ..
                   "- **Rank:** [" .. player:GetRoleInGroup(groupId) .. "](https://www.roblox.com/users/" .. player.UserId .. "/profile)\n" ..
                   "- **Username:** [" .. targetUsername .. "](https://www.roblox.com/users/" .. targetPlayer.UserId .. "/profile)\n" ..
                   "- **Roblox ID:** " .. targetPlayer.UserId .. "\n" ..
                   "- **Reason:** " .. reason .. "\n" ..
                   "- **Ban Time:** " .. durationText .. "\n" ..
                   "- **Case ID:** " .. caseID .. "\n" ..
                   "- **Date:** " .. getFormattedDateTime(),
        ["pos"] = "top",
        ["idList"] = trelloListId,
        ["keepFromSource"] = "all",
        ["key"] = trelloKey,
        ["token"] = trelloToken
    }

    local trelloUrl = "https://api.trello.com/1/cards"
    local success, response = pcall(function()
        return HttpService:PostAsync(trelloUrl, HttpService:JSONEncode(trelloCardData), Enum.HttpContentType.ApplicationJson)
    end)

    if not success then
        print("Failed to create Trello card:", response)
    else
        print("Trello card created successfully")
    end

    player:SendNotification({
        Title = "Ban Command",
        Text = "Successfully banned " .. targetUsername
    })
end)

if u want smth else im here

1 Like

Do you have commissions open? Or you sell your services?

1 Like

i mean, here’s my user in ds, if u wish for that: infinuts

I’ve only one question to you. Did you use the Chat GPT to create it? It’s looks like typical scripting of Chat GPT where it’s kicks you if you don’t have required permissions, I’ve tried to script also such scripts with Chat GPT and it’s looks the same. Also what I want to say more that if you are using trello for saving your bans then instead of saving user’s username for script where it checks use better user ID, because user can also change their username and there will be no sense then of just saving their username.