Last active
January 6, 2024 18:17
-
-
Save SpiralAPI/41f655ebca7fc8acae0a2117eafcc942 to your computer and use it in GitHub Desktop.
Queue-based Discord Webhook Proxy (Designed for roblox)
This file contains 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
# Made by SpiralAPI | |
# This system automatically ratelimits all requests, with the downside of not returning errors when there is an issue with your Webhook Data. | |
# Workaround: Don't switch your proxy to this one until you are certain that it is functional. | |
# If you do use this, I highly suggest hosting this alongside Nginx and UWSGI. Your welcome! | |
# edit: this is pretty old, it works but theres better ways to do it | |
# //IMPORTS | |
from flask import Flask, request, jsonify | |
import redis | |
import requests | |
import validators | |
from urllib.parse import urlparse | |
from threading import Thread | |
import json | |
import re | |
from time import sleep | |
# //Variables | |
app = Flask(__name__) | |
client = redis.Redis() # you must setup your own redis server! https://developer.redis.com/develop/python/#step-1-run-a-redis-server | |
RobloxIPs = ["103.140.28.0", "128.116.0.0", "128.116.2.0", "128.116.3.0", "128.116.4.0", "128.116.6.0", "128.116.8.0", "128.116.11.0", "128.116.13.0", "128.116.14.0", "128.116.15.0", "128.116.16.0", "128.116.17.0", "128.116.18.0", "128.116.19.0", "128.116.20.0", "128.116.23.0", "128.116.24.0", "128.116.25.0", "128.116.26.0", "128.116.27.0", "128.116.28.0", "128.116.29.0", "128.116.34.0", "128.116.35.0", "128.116.36.0", "128.116.37.0", "128.116.38.0", "128.116.39.0", "128.116.40.0", "128.116.41.0", "128.116.42.0", "128.116.43.0", "128.116.44.0", "128.116.45.0", "128.116.46.0", "128.116.49.0", "128.116.50.0", "128.116.51.0", "128.116.58.0", "128.116.59.0", "128.116.60.0", "128.116.62.0", "128.116.65.0", "128.116.67.0", "128.116.69.0", "128.116.70.0", "128.116.71.0", "128.116.72.0", "128.116.73.0", "128.116.74.0", "128.116.75.0", "128.116.76.0", "128.116.77.0", "128.116.78.0", "128.116.80.0", "128.116.81.0", "128.116.82.0", "128.116.83.0", "128.116.84.0", "128.116.85.0", "128.116.87.0", "128.116.88.0", "128.116.89.0", "128.116.95.0", "128.116.97.0", "128.116.99.0", "128.116.101.0", "128.116.102.0", "128.116.104.0", "128.116.105.0", "128.116.112.0", "128.116.114.0", "128.116.115.0", "128.116.116.0", "128.116.117.0", "128.116.118.0", "128.116.119.0", "128.116.120.0", "128.116.121.0", "128.116.122.0", "128.116.123.0", "128.116.124.0", "128.116.126.0", "128.116.127.0", "141.193.3.0", "205.201.62.0", "209.206.40.0", "209.206.40.0", "209.206.42.0", "209.206.43.0", "209.206.44.0"] | |
# //FUNCTIONS | |
def detect_special_character(pass_string): # special character detection. i got this off of stack overflow i think | |
regex= re.compile('[@_!#$%^&*()<>?/\|}{~:]') | |
if(regex.search(pass_string) == None): | |
res = False | |
else: | |
res = True | |
return(res) | |
def processQueue(): | |
while True: | |
task = client.blpop("discord_queue") # pops (retrives + deletes from list) the most recent object in the redis queue | |
data = json.loads(task[1]) # turn in to a python object | |
webhook_data = data["value"] | |
webhook_url = data["webhook_url"] | |
try: | |
req = requests.post(webhook_url, json=webhook_data) # sends the webhook with all data provided | |
if req.status_code == 200: | |
return jsonify({"response": "Success."}), 200 | |
except requests.exceptions.RequestException as error: | |
return jsonify({"response": error}), 500 | |
sleep(1/30) # important so that there aren't ratelimits! | |
# //APP FUNCTIONALITY | |
@app.route('/api', defaults={'path': ''}) # opens a new path "/api" | |
@app.route('/<path:path>', methods=["POST", "GET"]) # allows any path to follow "/api", for example "/api/hello" would work | |
def proxy(path): | |
webhookUrl = "https://discord.com/" + path | |
if not validators.url(webhookUrl) or detect_special_character(webhookUrl) and not urlparse(webhookUrl).hostname == "discord.com" and urlparse(webhookUrl).scheme: | |
jsonify({"response": "Webhook URL Invalid."}), 400 # checks to make sure the webhook url is valid | |
if not request.remote_addr in RobloxIPs: # i added this to prevent external use from NON roblox ip's however its not needed | |
return jsonify({"response": "Access denied. Make sure you are using this service on a ROBLOX server."}), 401 | |
if request.method == "POST": # the main usage. when posting to your servers endpoint it will run | |
data2 = {} | |
data = request.get_json() | |
data2["webhook_url"] = webhookUrl | |
data2["value"] = data | |
if data2 and "webhook_url" in data2: | |
client.rpush("discord_queue", json.dumps(data2)) # adds all webhook data in to the redis queue where it is then processed | |
return webhookUrl | |
elif request.method == "GET": # i dont really see any reason why you'd need this but i added it anyways | |
try: | |
resp = requests.get(webhookUrl) | |
return resp.json() | |
except: | |
return jsonify({"response": "Error returning webhook info."}), 500 | |
# //STARTUP | |
queue_thread = Thread(target=processQueue) # starts a new thread that executes the processQueue function | |
queue_thread.start() | |
app.run("0.0.0.0", 1050) # run your flask app. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment