Created
October 19, 2021 15:14
-
-
Save lewisakura/5308748d2d65a195ff580d4b9a54845f to your computer and use it in GitHub Desktop.
WebhookProxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local HttpService = game:GetService("HttpService") | |
local Proxy = {} | |
Proxy.__index = Proxy | |
local function safeReq(url: string, data: any) | |
local info = HttpService:RequestAsync({ | |
Url = url, | |
Method = "POST", | |
Body = HttpService:JSONEncode(data), | |
Headers = { | |
["Content-Type"] = "application/json" | |
} | |
}) | |
if info.StatusCode == 204 then return true, 204, nil end | |
local body = HttpService:JSONDecode(info.Body) | |
if not info.Success then | |
if info.StatusCode == 500 then | |
warn("[WebhookProxy] Proxy instance encountered an internal error. Silently failing.") | |
return true, 204, nil | |
else | |
return false, info.StatusCode, body.error | |
end | |
end | |
return true, info.StatusCode, body | |
end | |
local function processStatus(statusCode: number, body: any) | |
if statusCode == 403 then | |
if body.message == "This IP address has been banned." then | |
error("This Roblox server IP has been temporarily banned due to abuse.") | |
end | |
if body.message == "This webhook has been blocked. Please contact @Lewis_Schumer on the DevForum." then | |
error("This webhook has been blocked: " .. body.reason) | |
end | |
end | |
if statusCode == 429 then | |
warn( | |
"[WebhookProxy] Hit ratelimit. If you are seeing this warning often, consider using Proxy:Queue() instead. Otherwise, please enforce ratelimits yourself." | |
) | |
return nil | |
end | |
if statusCode == 404 then | |
error("Attempted to request to a non-existent webhook.") | |
end | |
if statusCode == 400 and not body.proxy then | |
error("Bad request: " .. body.message) | |
end | |
end | |
--[[ | |
Create a new proxy instance. | |
@param id The webhook ID. This is the first part of your webhook. | |
@param token The webhook token. This is the second part of your webhook. | |
@param instance The proxy to use. If not provided, uses the default WebhookProxy server. | |
@returns An instance of the proxy. | |
]] | |
function Proxy.new(id: string, token: string, instance: string?) | |
return setmetatable({ | |
_id = id, | |
_token = token, | |
_instance = instance or "https://webhook.lewistehminerz.dev" | |
}, Proxy) | |
end | |
--[[ | |
Queue a message. | |
@param data The message data. | |
@param threadId The thread to send the message to. | |
]] | |
function Proxy:Queue(data: any, threadId: string?) | |
if typeof(data) ~= "table" or (data.content == nil and data.embeds == nil and data.file == nil) then | |
error("Invalid data object. Expecting a table containing `content`, `embeds`, or `file`.") | |
end | |
local url = self._instance .. "/api/webhooks/" .. self._id .. "/" .. self._token .. "/queue" | |
if threadId then | |
url = url .. "?thread_id=" .. threadId | |
end | |
local success, statusCode, response = safeReq(url, data) | |
if success then return nil end | |
if statusCode == 403 and response.proxy and response.error == "Queues have been disabled." then | |
error("Queues are disabled on this instance of WebhookProxy.") | |
end | |
processStatus(statusCode, response) | |
return nil | |
end | |
--[[ | |
Send a message immediately. | |
@param data The message data. | |
@param waitForReply Whether or not to wait for a response. | |
@param threadId The thread to send the message to. | |
@returns If `waitForReply` is true, the message object. | |
]] | |
function Proxy:Send(data: any, waitForSend: boolean, threadId: string?) | |
if typeof(data) ~= "table" or (data.content == nil and data.embeds == nil and data.file == nil) then | |
error("Invalid data object. Expecting a table containing `content`, `embeds`, or `file`.") | |
end | |
local url = self._instance .. "/api/webhooks/" .. self._id .. "/" .. self._token | |
url = url .. "?wait=" .. tostring(waitForSend) | |
if threadId then | |
url = url .. "&thread_id=" .. threadId | |
end | |
local success, statusCode, response = safeReq(url, data) | |
if success then return response end | |
processStatus(statusCode, response) | |
end | |
return Proxy |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment