Proxy is not sending message?

Hi!

I am using discord web hooks to send whether a player joins or leaves my game, and I added a footer that shows the player name and user id. (note: I’m not using web hooks, I’m using proxies and a website called Heroku)

Here is the script that basically sends the message to my server:

local webhookservice = require(game:GetService("ServerScriptService"):WaitForChild("WebhookService"))

local url =  "thisisadiscordwebhook.com"

game.Players.PlayerAdded:Connect(function(plr)
	local data = 
		{
			["contents"] = "",
			["username"] = plr.Name .. " - (#"..plr.userId..")",
			["avatar_url"] = "https://www.roblox.com/Thumbs/Avatar.ashx?x=500&y=500&Format=Png&userId="..plr.userId,
			["embeds"] = {{
				["title"]= plr.name,
				["description"] = plr.Name .. " joined the Game",
				["type"]= "rich",
				["color"]= tonumber(0x6AA84F),
				["fields"]={
					{
						["name"]="Event: Player joined",
						["value"]="User: **"..plr.Name.."** with ID: **"..plr.UserId.."** has joined [game](https://www.roblox.com/games/".. game.PlaceId..")/[Profile](https://www.roblox.com/users/"..plr.UserId.."/profile)",
						["inline"]=true}}}}
		}
webhookservice:createMessage(url , data)

(EDIT: No errors appear in the output.)

3 Likes

Unfortunately, Roblox doesn’t allow the discord port to be used anymore so you’ll have to make an external server to handle these requests.

1 Like

I think you should censor the url link because peoples might like steal or copy the link and do something with it

1 Like

I am not using webhooks only, but I am using a proxy server. The video I watched to get this working is here: How to use Discord webhooks with Roblox using a proxy server! - YouTube

so, is there any solution to the post i made?

thanks for reminding me! i have now edited it.

What is webhookservice? Could you add the code for that?

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

local Proxy = ProxyService:New('heroku links, ') 

---------------------------------------------------------------------------------------

local webhookService = {}

local https = game:GetService("HttpService")


function webhookService:createMessage(url, message)
	local data = {
		["content"] = message
	}
	local finalData = https:JSONEncode(data)
	Proxy:Post(url, finalData)
end

function webhookService:createEmbed(url, title, message, image)
	local data = {
		['content'] = "",
		['embeds'] = {{
			["image"] = {["url"] = image},
			['title'] = "**"..title.."**",
			['description'] = message,
			['type'] = "rich",
			["color"] = tonumber(0xffffff)
		}}
	}
	local finalData = https:JSONEncode(data)
	Proxy:Post(url, finalData)
end


return webhookService
1 Like

Could see the ProxyService as well as anything else required (omitting specific urls, assuming you have a working proxy)? Also, if you haven’t already, make sure the proxy works by sending a simple “test” message without embeds.

1 Like

Yes, the proxy does work.
image

Here is the script you requested:


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
1 Like

Use guilded api’s they are the same as discord. But upload to guilded servers.

1 Like

No, my api and scripts work fine, I just want to do something like this:

image

1 Like

Discord doesn’t want you to post things to the website, hence the whole them blocking the roblox domain. A proxy isn’t a good response to that, however moving to basically a replica of it and better channels for these logging systems, is. (Sorry if that came off as snappy! I didn’t mean too haha.)

Guilded is much better for channels and alot of other stuff however lacks in general chat.

Simply use embeds to do that and send it as the parm for the body if you are using RequestAsync to post to your proxy. If you are using PostAsync send it as the data param. Make sure both are Encoded with JSON since it only accepts strings.

You can now use PlayerAdded & PlayerRemoving to check when a user joins and then post that to your proxy using the module you made.

So I have to move to guilded just to use webhooks?

How would I use post async, then send the embed (the embed is in the original post, it just won’t send)

Yeah. Basically that or risk your data being put through a bunch of other endpoints.

It won’t send since you are setting the passed in JSON data as the content. From what It looks like your format also seems to bit inaccurate.

Updated Version(WebhookService):

function webhookService:createMessage(url, message)
	local finalData = https:JSONEncode(message)
	Proxy:Post(url, finalData)
end

Updated Version(MainFile):

--[=[
    @TODO: 
]=]

--> Services
local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")

--> Variables
local WebhookService = require(ServerScriptService:FindFirstChild("WebhookService"))
local URL = ""

--> Functions 
Players.PlayerAdded:Connect(function(Player)
    local Data = {
        embeds = {{
            title = Player.Name,
            description = "["..Player.Name.."joined the game!](https://www.roblox.com/users/"..Player.UserId.."/profile)",
            color= tonumber(0x6AA84F),
            fields = {
                {
                    name = "Event: PlayerJoined!",
                    value = "User: **"..Player.Name.."** with ID: **"..Player.UserId.."** has joined [game](https://www.roblox.com/games/"..game.PlaceId..")/[Profile](https://www.roblox.com/users/"..Player.UserId.."/profile)",
                }
            }
        }}
    }

    WebhookService:createMessage(URL , Data)
end)

You might need to adjust a few things here and there to fix it to your liking. I also went ahead and cleaned up your code a little bit.

3 Likes

I wouldn’t consider it risky, as everything is being handled on the server, and the file that has a link is in ServerScriptService(hopefully). Plus he’s using his proxy made using a trusted open-source. So he should be fine as long as he takes his precations to not leak the webhook to the clients.

No, he’s not passing his webhook through a bunch of other endpoints. It only passes Roblox’s API and his own proxy server. Which I believe was made using an open-sourced proxy server that’s safe to use as the code is similar.

2 Likes