WebhookProxy | Discord webhooks go brrrrrrr

Do you know how to implement the queue into @LuaScape 's V3 module? @lewisakura

I’ve tried using the code from here WebhookProxy | Discord webhooks go brrrrrrr - #42 by LewisTehMinerz

Within V3, but CJ’s code does not divide the webhook URL into smaller parts.
I got a group using the proxy, and since I can’t get CJ’s error logging module to support queue, it manages to get the webhook ratelimited.

Also, is there a way I can remove the ratelimit from a webhook, if it calms down on the sending?
Or is that putting it into a perm block?

Summary
--[[WARNING!!! MAKE SURE THIS MODULE IS IN SERVER STORAGE OR SERVER SCRIPT SERVICE]]

-- This module was created by LuaScape (Roblox: Snawrk)
-- Proxy Created By LewisTehMinerz
-- DO NOT Edit the code below unless you know what you're doing!
---------------------------------------------------------------------------------------

local webhookService = {}

local https = game:GetService("HttpService")


function webhookService:createMessage(url, message : string)
	local data = {
		["content"] = message
	}
	local finalData = https:JSONEncode(data)
	local finalUrl = string.gsub(url, "discord.com", "webhook.lewistehminerz.dev")
	local finalBackupUrl = string.gsub(url, "discord.com", "webhook.newstargeted.com")
	local good, bad = pcall(function()
		https:PostAsync(finalUrl, finalData)
	end)
	if good then
		print("Webhook Request Success!")
	else
		print("Webhook Request Failed " .. bad .. " Trying backup URL")
		https:PostAsync(finalBackupUrl, finalData)
		print("Attempted request with backup URL, if webhook does not send then both URLS are down or you have a bad request.")
	end
end


function webhookService:createEmbed(url, title : string, message :string , fields, image)
	local data = {
		['content'] = "",
		['embeds'] = {{
			["image"] = {["url"] = image},
			['title'] = "**"..title.."**",
			['description'] = message,
			['type'] = "rich",
			["color"] = tonumber(0xffffff),
			['fields'] = fields

		},
		},
	}
	local finalData = https:JSONEncode(data)
	local finalUrl = string.gsub(url, "discord.com", "webhook.lewistehminerz.dev")
	local finalBackupUrl = string.gsub(url, "discord.com", "webhook.newstargeted.com")
	
	local good, bad = pcall(function()
		https:PostAsync(finalUrl, finalData)
	end)
	if good then
		print("Webhook Request Success!")
	else
		print("Webhook Request Failed " .. bad .. " Trying backup URL")
		https:PostAsync(finalBackupUrl, finalData)
		print("Attempted request with backup URL, if webhook does not send then both URLS are down or you have a bad request.")
		
	end
end


function webhookService:createAuthorEmbed(url, authorName : string, iconurl, description : string, fields)
	local data = {
		["embeds"] = {{
			["author"] = {
				["name"] = authorName,
				["icon_url"] = iconurl,
			},
			["description"] = description,
			["color"] = tonumber(0xFFFAFA),
			["fields"] = fields
			
			
		}},
	}
	
	local finalData = https:JSONEncode(data)
	local finalUrl = string.gsub(url, "discord.com", "webhook.lewistehminerz.dev")
	local finalBackupUrl = string.gsub(url, "discord.com", "webhook.newstargeted.com")
	
	local good, bad = pcall(function()
		https:PostAsync(finalUrl, finalData)
	end)
	if good then
		print("Webhook Request Success!")
	else
		print("Webhook Request Failed " .. bad .. " Trying backup URL")
		https:PostAsync(finalBackupUrl, finalData)
		print("Attempted request with backup URL, if webhook does not send then both URLS are down or you have a bad request.")
	end
end


return webhookService

Hi all,

I will be changing the domain from webhook.lewistehminerz.dev to webhook.lewisakura.moe. There will be a redirect for a few months (until lewistehminerz.dev expires) but I no longer recommend using the old domain. Please change ASAP.

Thank you!

2 Likes

I got a suggestion for the webhook system. @lewisakura
Maybe have the option to send each rate-limited, blocked and does not exist webhook ID (Not token) to a certain public discord channel, so people can see if their ID is banned or ratelimited.
(Posted once each 12 hour if spam from one ID is posted), that way a webhook URL to post ID’s does not spam discord API :slight_smile:

Attempting to send a message when banned will return the ban reason already. Publicly revealing ban logs would be a privacy risk since it discloses who uses the service indirectly (with a bit of looking up you can find where a webhook belongs) and that’s not something I wish to do. If you want to work out why your webhooks are banned, you can work it out yourself by attempting a request.

Is there a way to run embeds through a queue to discord? @lewisakura

Nvm, I edited the script and made a queue work alongside my remote ban for Roblox.

PS: Script requires a discord webhook URL to report, and will error without one.

Solved:
Mas-Remote-ban (serverscriptservice).rbxm (6.7 KB)

hey @lewisakura!
we’re experiencing an issue where a large number of POST requests are getting completely eaten and never get sent to our webhook. originally we figured it was just the rate limiting but it’s chewing up more and more requests, never puts them in a queue to send or anything.
anything you can do or suggestions you got?

oops, we seemed to still be running hyra. that mightve been why.

EDIT: sending POST requests to the proxy is resulting in a 403 forbidden. guess well return to hyra AH anti-abuse is on. thats why. sorry lol

anyway. didnt someone earlier in this thread post a method that uses this proxy as its main, but when it failed, automatically switch to hyra as a backup?
i cant seem to find that post. does… anyone have it, if it even existed?
if not and it was deleted or this is a false memory, does anyone have an example of a script doing this so we can have a proxy when this one goes down?

Something like this?

local HttpService = game:GetService("HttpService")

local function sendHook (hook, username, content)
  local providers = {
    "https://hooks.hyra.io",
    "https://webhook.lewisakura.moe",
  }
  for i = 1, #providers do
    local suc, err = pcall(function ()
      local data = {
        ["username"] = username,
        ["content"] = content,
      }
      HttpService:PostAsync(providers[i] .. hook, HttpService:JSONEncode(data), Enum.HttpContentType.ApplicationJson)
    end)
    if suc then return true end -- sent with success
    if i == #providers then warn("Error all providers failed") return false end
  end
end
if sendHook("/api/webhooks/12345/abcdefg", "MyUsername", "This is the content") then
  -- hook sent to one of the listed providers
else
  -- all providers failed
end
2 Likes

Using this, and its returning error 403. I have http requests on, and I have also tried Hyra. Is something going on? I can’t really say if its down or not because I feel like its a problem on my end.

EDIT: nevermind i think today there were some roblox problems

Depending on the time you were using it, it might’ve been under anti-abuse mode, so it wouldn’t be your fault. You can check the website itself to see if it is.

It really is time for me to buy more IP addresses…

If you cant afford to have downtimes I suggest you host your own WebhookProxy (check github to know how to host) using Heroku, Railway or any other alternative service. I know it can cost some bucks. Also you can add an authentication layer so you can make sure only your games can send requests to your WebhookProxy

Hey all,

I implemented multiple IP addresses a couple of days ago as a hellish sideproject which I absolutely hated netplan hurts my soul simple fix to the abuse issues. If you haven’t noticed anything different, great, it’s doing its job! As far as end user experience goes, there should be no changes to how your webhooks get sent. The only difference is for newer users as they should have an easier time getting set up with less anti-abuse issues.

On top of this, the anti-abuse was modified to be more strict. These two changes should work together to provide a better experience for everyone.

Thanks for using the service, I’ll keep updating it and making it better.

2 Likes

I love the new change, so i can see what server is ratelimited :slight_smile:

Have you seen this error before @lewisakura

Your RabbitMQ shut itself down. Restart it, then restart the queue processor.

I figured it out, i had to rollback an update.
Because it had force updated rabbitmq to the latest, that wasn’t working properly.
So now i’m back at these versions.

RabbitMQ 3.11.5
Erlang 25.2

Could we perhaps post the uptime in % on the site also @lewisakura ?
Like Hyra does it.

I see no explanation of what these two options do.

autoBlock is the automatic moderation, which is enabled on the live proxy. trustProxy in this context toggles the proxy trusting mode of Express, which is if you’re running it behind nginx or the like (which would be a reverse proxy), allowing it to trust the IP address that gets issued by whatever’s running in front of it. Without that option, IP address identification wouldn’t work correctly.

Cool project! One of the few out there that are still actually working.

I was wondering if you’re also will be supporting non webhooks anytime soon?
I for example, require to access the Get Guild member API function of Discord but are unable to as there are (non as far as I could find?) services out there that support this, as they only support webhooks.

This sort of thing is better suited for something like a self-hosted ProxyService instance.