Ban Logging for my Admin GUI

In part of a UI I am making for my own fun, I added when pressing the ban command it fires and event to send a webhook, but it now errors when I added the reason part and claims it is HTTP 400 (Bad Request)`

local chat = game:GetService("Chat")
local HTTPService = game:GetService("HttpService")
local storage = game:GetService("ReplicatedStorage")
local sendLog = storage.:WaitForChild("Ban")
local GameName = game:GetService("MarketplaceService"):GetProductInfo(game.PlaceId).Name


local webhooktosend = ""

sendLog.OnServerEvent:Connect(function(person, accused, text) --member
    local data = 
        {
            ["content"] = "",
            ["embeds"] = {{
                ["title"] = "__**Hybrid Karting Admin GUI**__",
                ["description"] = ""..person.Name.." has banned a player inside of "..GameName,
                ["type"] = "rich",
                ["color"] = tonumber(0xffffff),
                ["fields"] = {
                    {
                        ["name"] = "Reason",
                        ["value"] = text,
                        ["inline"] = true,
                    },
                    {
                        ["name"] = "Details",
                        ["value"] = "Player Effected: "..accused,
                        ["inline"] = true,
                    },    

                    {
                        ["name"] = "Game ran in:",
                        ["value"] = GameName,
                        ["inline"] = true,
                    },
                    {
                        ["name"] = "Moderator:",
                        ["value"] = person.Name,
                        ["inline"] = true,
                    },
                }
            }}
        }
    local JSON = HTTPService:JSONEncode(data)
    HTTPService:PostAsync(webhooktosend, JSON)

end)```

And this is to Fire the server in the Ban Button

local Frame = script.Parent.Parent.Parent.AdminFrame
local BanReason = Frame.Message
local PlayerBan = Frame.PlrNameLabel


Frame.Ban.MouseButton1Click:Connect(function()
    if BanReason.Text ~= "" then
        game:GetService("ReplicatedStorage"):WaitForChild("Ban"):FireServer(PlayerBan.Text)
    end
end)

Frame.Ban.MouseButton1Click:Connect(function()
    if PlayerBan.Text ~= "" then
        game:GetService("ReplicatedStorage"):WaitForChild("Ban"):FireServer(BanReason.Text)
    end
end)

Thank you!

1 Like

You can nolonger send webhooks through ROBLOX to discord, you’ll need to create your own proxy to do so.

Hey.

I’m pretty sure discord has banned all incoming requests from roblox so you’ll have to use your own proxy.

Thanks for the swift reply, it was working fine before we added the username for banned player.

You can use hooks.hyra.io
Heres an example:

local webhook = "your discord webhook url"
webhook = string.gsub(webhook, "https://discord.com", "https://hooks.hyra.io")
local http = game:GetService("HttpService")

local info = {
		["username"] = "",
		["avatar_url"] = "",
		["content"] = "This is content",
		["embeds"] = {{
			["title"] = "This is embed tittle",
			["description"] = "This is embed description",
			["type"] = "rich",
			["color"] = tonumber(0xffffff),
		}}
	}

info = http:JSONEncode(info)
http:PostAsync(webhook, info)

It’s still erroring with HTTP 400 (Bad Request)

get herokuapp proxy it should help atleast I use it

create mainmodule in serverscriptservice and change name to ProxyService
and put this script inside of it

local http = game:GetService('HttpService')
local _get = http.GetAsync
local _post = http.PostAsync
local _decode = http.JSONDecode

local POST_METHODS = {'POST', 'PUT', 'PATCH'}
local GET_METHODS = {'GET', 'DELETE'}

local ProxyService = {}

local processBody = function (body)
	local pos, _, match = body:find('"""(.+)"""$')
	local data = _decode(http, match)
	local res = {
		headers = data.headers,
		status = data.status,
		body = body:sub(1, pos - 1)
	}
	return res
end

local httpGet = function (...)
	local body = _get(http, ...)
	return processBody(body)
end

local httpPost = function (...)
	local body = _post(http, ...)
	return processBody(body)
end

local getHeaders = function (this, method, target, headers, overrideProto)
	local sendHeaders = headers or {}
	sendHeaders['proxy-access-key'] = this.accessKey
	sendHeaders['proxy-target'] = target
	if overrideProto then
		sendHeaders['proxy-target-override-proto'] = overrideProto
	end
	if method ~= 'GET' and method ~= 'POST' then
		sendHeaders['proxy-target-override-method'] = method
	end
	if headers then
		for header, value in next, headers do
			local headerLower = header:lower();
			if headerLower == 'user-agent' then
				sendHeaders['user-agent'] = nil
				sendHeaders['proxy-override-user-agent'] = value
			end
		end
	end
	return sendHeaders
end

local generatePostHandler = function (method)
	return function (self, target, path, data, contentType, compress, headers, overrideProto)
		local sendHeaders = getHeaders(self, method, target, headers, overrideProto)
		return httpPost(self.root .. path, data, contentType, compress, sendHeaders)
	end
end

local generateGetHandler = function (method)
	return function (self, target, path, nocache, headers, overrideProto)
		local sendHeaders = getHeaders(self, method, target, headers, overrideProto)
		return httpGet(self.root .. path, nocache, sendHeaders)
	end
end

local urlProcessor = function (callback)
	return function (self, url, ...)
		local _, endpos = url:find('://')
		local nextpos = url:find('/', endpos + 1) or #url + 1
		local target = url:sub(endpos + 1, nextpos - 1)
		local path = url:sub(nextpos)
		return callback(self, target, path, ...)
	end
end

local generateWithHandler = function (handler, method, handlerMethod)
	ProxyService[method:sub(1,1):upper() .. method:sub(2):lower()] = urlProcessor(handler(method))
end

for _, method in next, POST_METHODS do
	generateWithHandler(generatePostHandler, method)
end
for _, method in next, GET_METHODS do
	generateWithHandler(generateGetHandler, method)
end

function ProxyService:New(root, accessKey)
	if root:sub(#root, #root) == '/' then
		root = root:sub(1, #root - 1)
	end
	if not root:find('^http[s]?://') then
		error('Root must include http:// or https:// at the beginning')
	end
	self.root = root
	self.accessKey = accessKey
	return self
end

return ProxyService

and then use this as webhook

local HttpService = game:GetService("HttpService")
local DiscordWebhookURL = "Webhook Here"

local ProxyService = require(game:GetService('ServerScriptService').ProxyService)

local Proxy = ProxyService:New('https://proxyservace.herokuapp.com/','808f51410b476d3686b9ae947b1cff7083cbe82fab0e339471309e4e075f2014')

    local MessageData = {
        ["content"] = "";
        ["username"] = "Yay";
        ["embeds"] = {{
            ["type"]= "rich",
            ["color"]= tonumber(0xffffff),
            ["fields"]={
                {

                    ["name"]= "Anything".,
                    ["value"]= "Yey",

                    ["inline"]=true}}}}
    }

    MessageData = HttpService:JSONEncode(MessageData)
    -- JSONEncode is used to convert the Lua Table into a JSON String.

        Proxy:Post(DiscordWebhookURL, MessageData)

You see, it works for the other webhook I do, just not this one that is why im a tad confused.

what it says? if it says something then show it

So, as it is an Admin UI, I have tested the other page that also uses a webhook does not error and it sends, but whenever I added the part accused I got that error.

I have managed to fix this, I was passing the event through twice when I could have done it all in one, thanks for the help!