Why is my Roblox-Discord webhook not working?

Greetings! I wrote a Roblox script that’s supposed to send an embed message whenever it detects a user going over the 9 CPS (clicks per second) limit. However, neither the prints nor the webhook seem to be working. Could someone help me troubleshoot this?

local HttpService = game:GetService("HttpService")
local UserInputService = game:GetService("UserInputService")
local GroupService = game:GetService("GroupService")
local WebhookURL = "" 
local GroupId = 

local function sendToDiscord(embed)
  local success, response = pcall(function()
    local data = {
      ["embeds"] = {embed}
    }
    local encodedData = HttpService:JSONEncode(data)
    local headers = {
      ["Content-Type"] = "application/json"
    }
    return HttpService:PostAsync(WebhookURL, encodedData, Enum.HttpContentType.ApplicationJson, false, headers)
  end)
  if success then
    print("ACL | Sent the embed successfully.")
  else
    warn("ACL | Failed to send embed:", response)
  end
end

local function getRank(playerId)
  local success, result = pcall(function()
    return GroupService:GetRankInGroup(playerId, GroupId)
  end)
  if success then
    return result.Name or "Unknown"
  else
    warn("Failed to get player rank:", result)
    return "Unknown"
  end
end

local clicks = 0
local lastClickTime = tick() 

local function onInputBegan(input)
  if input.UserInputType == Enum.UserInputType.MouseButton1 then
    clicks = clicks + 1
    local currentTime = tick()
    local timeSinceLastClick = currentTime - lastClickTime

    if timeSinceLastClick < 1 then
      clicks = clicks + 1
    else
      clicks = 1
    end

    lastClickTime = currentTime

    local clickRate = clicks

 
    local playerName = input.User.Name
    local playerID = input.User.UserId
    local playerRank = getRank(playerID)

    if clickRate > 9 then
      print("ACL | Exceeded the limit.")

      local embed = {
        ["title"] = "⚠️ Auto-clicker Alert",
        ["description"] = playerName .. " has exceeded the 9 CPS limit",
        ["color"] = tonumber(0x2b2d31),
        ["thumbnail"] = {
          ["url"] = "https://www.roblox.com/Thumbs/Avatar.ashx?userid=" .. tostring(playerID) .. "&x=100&y=100&format=png"
        },
        ["fields"] = {
          {
            ["name"] = "Current CPS:",
            ["value"] = clickRate,
            ["inline"] = true
          },
          {
            ["name"] = "User ID:",
            ["value"] = playerID,
            ["inline"] = true
          },
          {
            ["name"] = "Rank:",
            ["value"] = playerRank,
            ["inline"] = true
          }
        }
      }

      sendToDiscord(embed)
    end

    clicks = 0 
  end
end

UserInputService.InputBegan:Connect(onInputBegan)
1 Like

Discord banned posts from roblox, so using a discord webhook link wont work.
Im pretty sure this proxy website still works as a workaround

1 Like
local HttpService = game:GetService("HttpService")
local UserInputService = game:GetService("UserInputService")

-- Replace with your Discord Webhook URL
local WebhookURL = "YOUR_WEBHOOK_URL_HERE" 

local clickCount = 0
local startTime = 0
local CPSLimit = 9

-- Function to send a message to Discord
local function sendToDiscord(embed)
	local success, response = pcall(function()
		local data = {
			["embeds"] = {embed}
		}
		local encodedData = HttpService:JSONEncode(data)
		local headers = {
			["Content-Type"] = "application/json"
		}
		return HttpService:PostAsync(WebhookURL, encodedData, Enum.HttpContentType.ApplicationJson, false, headers)
	end)
	if success then
		print("ACL | Sent the embed successfully.")
	else
		warn("ACL | Failed to send embed:", response)
	end
end

-- Function to create an embed message
local function createEmbed(username, cps)
	return {
		["title"] = "CPS Alert",
		["description"] = username .. " has exceeded the CPS limit with " .. cps .. " clicks per second.",
		["color"] = 16711680 -- Red color
	}
end

-- Function to track user clicks
local function onInputBegan(input, gameProcessed)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		if startTime == 0 then
			startTime = tick()
		end
		clickCount = clickCount + 1

		local elapsedTime = tick() - startTime
		if elapsedTime >= 1 then
			local cps = clickCount / elapsedTime
			print("CPS: " .. cps)

			if cps > CPSLimit then
				local username = game.Players.LocalPlayer.Name
				local embed = createEmbed(username, cps)
				sendToDiscord(embed)
			end

			-- Reset counters
			clickCount = 0
			startTime = 0
		end
	end
end

UserInputService.InputBegan:Connect(onInputBegan)

I tried to do this one as well and it doesn’t work either.

I replaced the webhook with the new one and still no message in the channel.


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

local WebhookURL = "" --Ensure this is correctly set
local GroupId = 0 --Ensure this is correctly set

local function sendToDiscord(embed)
    local success, response = pcall(function()
        local data = {
            ["embeds"] = {embed}
        }
        local encodedData = HttpService:JSONEncode(data)
        local headers = {
            ["Content-Type"] = "application/json"
        }
        return HttpService:PostAsync(WebhookURL, encodedData, Enum.HttpContentType.ApplicationJson, false, headers)
    end)
    if success then
        print("ACL | Sent the embed successfully.")
    else
        warn("ACL | Failed to send embed:", response)
    end
end

local function getRank(player)
    local success, result = pcall(function()
        return GroupService:GetRankInGroup(player.UserId, GroupId)
    end)
    if success then
        return result.Name or "Unknown"
    else
        warn("Failed to get player rank:", result)
        return "Unknown"
    end
end

local clicks = 0
local lastClickTime = tick()

local function onInputBegan(input, gameProcessed)
    if gameProcessed then return end
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        local player = Players:GetPlayerFromCharacter(input.Parent)
        if not player then return end

        clicks = clicks + 1
        local currentTime = tick()
        local timeSinceLastClick = currentTime • lastClickTime

        if timeSinceLastClick > 1 then
            clicks = 1
            lastClickTime = currentTime
        end

        local clickRate = clicks / timeSinceLastClick

        if clickRate > 9 then
            print("ACL | Exceeded the limit.")

            local embed = {
                ["title"] = "⚠️ Auto-clicker Alert",
                ["description"] = player.Name .. " has exceeded the 9 CPS limit",
                ["color"] = tonumber(0x2b2d31),
                ["thumbnail"] = {
                    ["url"] = "https://www.roblox.com/Thumbs/Avatar.ashx?userid=" .. tostring(player.UserId) .. "&x=100&y=100&format=png"
                },
                ["fields"] = {
                    {
                        ["name"] = "Current CPS:",
                        ["value"] = tostring(clickRate),
                        ["inline"] = true
                    },
                    {
                        ["name"] = "User ID:",
                        ["value"] = tostring(player.UserId),
                        ["inline"] = true
                    },
                    {
                        ["name"] = "Rank:",
                        ["value"] = getRank(player),
                        ["inline"] = true
                    }
                }
            }

            sendToDiscord(embed)
            clicks = 0
            lastClickTime = currentTime
        end
    end
end

UserInputService.InputBegan:Connect(onInputBegan)

This one didn’t work either… Could you show how it looks to you? Because that script looks very ChatGPT.

This is not a valid method of the GroupService. It should be player:GetRankInGroup(GroupId), as seen in this documentation.

Secondly, you can only use this HttpService method on the server, but UserInputService events only fire on the client. You need to use some type of RemoteEvent to tell the server to send an embed inside your onInputBegan function. The creating/encoding of the embed should be done in a server-side script (and of course the sending using HttpService:PostAsync()).

Keep in mind Discord webhooks won’t send from Roblox servers anymore. You’ll have to use a webhook proxy for your webhooks to reach Discord. There are various free proxy options that still exist but I would not recommend using them for reasons listed in this post.

Useful resources:
Player:GetRankInGroup() | Documentation - Roblox Creator Hub
Remote Events and Callbacks | Documentation - Roblox Creator Hub

I just wanted to add that I set up a webhook recently without a proxy, so Discord is presumably serving requests from Roblox again. However, you should be aware of rate limits from both Roblox and Discord.

Additionally, I was only able to execute your request without headers, and you might need a proxy to fetch thumbnail URLs.