Skip to content

Instantly share code, notes, and snippets.

@comhad
Last active June 19, 2021 20:50
Show Gist options
  • Save comhad/fb08abc2edc29af80ceb1bf3f433bb08 to your computer and use it in GitHub Desktop.
Save comhad/fb08abc2edc29af80ceb1bf3f433bb08 to your computer and use it in GitHub Desktop.
Implementing discord bot listing webhooks using a dedicated server exposed to the internet / VPS

Flask app for webhooks

Most discord bot listings use webhooks as a method of telling you who upvoted your bot, to recieve these webhooks, you need to have some kind of web server that's able to process them, if you don't have a dedicated web server that you can expose to the internet, you can read how to do this using other services here.

This method of recieving webhooks is generally easier to manage since you are recieving the data directly, however you need to remember that this is a web server and it will require the same security as if you were running any other site / API. The code below by default returns 403 errors if the token provided in the Authorization header is not correct or if header does not exist, you can use this in a firewall to determine if someone is trying to access it. (This returns a 403 for this event only, and does not stop people brute forcing for pages, or attempting a DoS attack)

There will be some variables for you to modify in the code, you should change the URL, to something long enough that people will not be able to find it through brute forcing pages. Change the token to your own that you give to the bot listing sites, make sure this token is long enough that it can't be brute forced easily. Change the content["user"] to content[""] and then the field you want to extract from the JSON data, look for the API docs on the site for what you are looking for.

Deployment

DO NOT USE THE DEFAULT FLASK SERVER, IT IS FOR DEVELOPMENT ONLY

There is guides on the internet for how to deploy a flask application to a server, use these guides. I use apache2 with the WGSI module, I also recommend you install a firewall that checks through apache2 logs for excessive 40X errors coming from a host.

Extras

  • Use prepared statements when dealing with databases, some discord users include quotes in their username.
  • Something i learned the hard way, if you are using sqlite3, read this stackoverflow post.
  • Use user IDs over usernames, a user ID is attached to one account and one account only, no matter how many times a user changes their name / discriminator, their ID will stay the same, so use this if you are adding records to a database.

Javascript

3061LRTAGSPKJMORMRT wrote a JavaScript version of the flask app and sent it to me, all credit for the JavaScript app goes to them. The same rules apply in not deploying this app using a development server, see here for why.

If this guide helped you please star this.

'''
- - - Basic flask webhook app - - -
Some services will send a webhook when a user upvotes
your bot, to use these webhooks on a dedicated server,
you will need to run an app that can recieve these
webhooks.
This is a template, you will have to adjust it based on
what service you are using and what data you are trying
to get. If you are unsure of what data gets sent, look
in the API docs.
(This requires a dedicated server exposed to the internet,
this can be a VPS or physical server that can be connected
to remotely, if you do not have a dedicated server / VPS
you can use, you can use an alternative option described
here : https://comhad.github.io/webhook.html )
DO NOT deploy this using the default flask server, you
should deploy it using WGSI module in apache2 or similar
setting.
'''
from flask import Flask, abort, request
app = Flask(__name__)
# Prepare flask app for use
@app.route("/path/to/upvote", methods = ["POST"]) # replace `/path/to/upvote` with what you think is most suitable, most discord bot listings use POST so the method should be fine
def upvote():
try :
auth = request.headers["Authorization"]
if auth == "token" : # Validate the Authorization header, change this token to your own
pass
else :
abort(403) # If the header is invalid
except KeyError :
abort(403) # If there is no Authorization header
content = request.get_json(force=True) # This will retrieve JSON for the request, even if the content-type doesn't state JSON
userid = content['user'] # This will depend on what service you are using and the data you want from the request
# . . .
# Do whatever you want here with the data
# Remember to use prepared statements if using databases, some people will include quotes in their usernames
return 'processed' # This is by default a 200 status code
if __name__ == "__main__":
app.run()
/*
This code was written and sent to me by https://github.com/3061LRTAGSPKJMORMRT, there
github will be linked in the above _webhooks.md file.
Remember to take the same precautions in not deploying this using a development server
and remembering to install a firewall.
*/
const http = require("http")
const express = require('express'); // make sure to install express from npm
const app = express();
app.use(express.json({extended: false}))
app.post("/dblwebhook", async (req, res) => { // make sure you put as http://your-server-name/dblwebhook
if(req.headers.authorization) {
if(req.headers.authorization === webhook_secret) { // replace webhook_secret with your webhook secret (the one you put in your application)
res.send({status: 200});
console.log(req.body.id) // logs the user id who voted
} else {
res.send({status: 401, error: 'The auth received does not match the one in your config file.'})
}
} else {
res.send({status: 403, error: 'There was no auth header in the webhook'})
}
})
http.createServer(app).listen(80); // or use another port
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment