Python Selfbots and Webhooks in Discord Pt. 1
Creating custom Discord selfbots when Discord's webhooks aren't enough.
My Inspiration
Like most of the small projects I get ideas for, this one came to me when I was bored and wanted to know if I could send a friend a message on Discord or Slack using a simple device like a Raspberry Pi.
My friends often have tech troubles and since we usually communicate over Discord or Slack. I figured it would make my life a little bit easier if I can just have them run a script and it will automatically send the results back to me through our DMs to help troubleshoot their issues.
Webhooks
This is generally the go to option if you are okay with performing smaller requests and tasks. Webhooks are quite easy to set up, but hamper the amount of control you have over your bot. Methods that use the API are favored and abide by the TOS, so if you like to live safely then this is the option for you.
See the Userbots section for more info on Discords TOS.
For instructions on creating Webhooks you can find the docs below:
Python
import requests
import json
if __name__ == '__main__':
wekbook_url = 'https://discordapp.com/api/webhooks/.../'
data = {
'text': 'A message sent with the power of Python in Discord.'
}
response = requests.post(wekbook_url, data=json.dumps(
data), headers={'Content-Type': 'application/json'})
print('Response: ' + str(response.text))
print('Response code: ' + str(response.status_code))
import requests
import json
if __name__ == '__main__':
wekbook_url = 'https://hooks.slack.com/services/{API_GUID}'
data = {
'icon_emoji' = ':ghost:',
'text': 'A message sent with the power of Python in Slack.',
'username': 'Python Bot',
'icon_emoji': ':robot_face:'
}
response = requests.post(wekbook_url, data=json.dumps(
data), headers={'Content-Type': 'application/json'})
print('Response: ' + str(response.text))
print('Response code: ' + str(response.status_code))
Userbots
This method is if you want more power over what your bot can do, for example with Slack you are unable to directly mention someone when using Webhooks. However a word of warning, you can be banned for using userbots as it is explicitly against the TOS (at least for Discord).
For Discord it is likely safer to strictly use the requests module, as Discord says you will be banned for logging in with your user account (through their module/api).
Which is why I will be using the selfbot repo Zenon.
Finding your Discord Auth token:
- Open the Discord App
- Press Ctrl+Shift+I (to open Chromium dev tools)
- Navigate to the Application Tab -> Storage -> Local Storage -> Discord.com
- In the filter bar type: "token" without quotes
- Press Ctrl+R (refresh Discord for the token to appear)
- Finally highlight to copy and retrieve your token.
Install dependencies
pip3 install requests, unidecode
Here we define a few functions allowing our bot to wait for a command in your chat channel of choice and respond with a custom message, that can optionally include their username (unicode formatted).
import requests
import random
import time
from unidecode import unidecode
token = "your-token-here"
discord = "https://discordapp.com/api/v6/"
chatid = 795743570995839018
def send_message(chatid, content, proxy=None): # it can also be use as a private message
return requests.post(discord + "channels/" + str(chatid) + "/messages#", proxies=proxy, data={"content":str(content), "nonce":str(random.randint(10000000, 99999999))}, headers={"Authorization":token}).text
def get_message(chatid, proxy=None):
res = requests.get(discord + "channels/" + str(chatid) + "/messages?limit=1", proxies=proxy, headers={"Authorization":token}).text
try:
content = res.split('"content": "')[1].split('"')[0]
except IndexError as e:
content = res.split('"message": "')[1].split('"')[0],res.split('"retry_after": ')[-1].split("\n")[0]
return content
def get_author_id(chatid, proxy=None):
res = requests.get(discord + "channels/" + str(chatid) + "/messages?limit=1", proxies=proxy, headers={"Authorization":token}).text
return res.split('"author":')[1].split('"id": "')[1].split('"')[0]
if __name__ == "__main__":
while True:
time.sleep(0.05) # To not spam the server
message = get_message(chatid)
if message == "!yobot":
send_message(chatid, f"How may I help you <@{get_author_id(chatid)}>?")
elif message[0] == "You are being rate limited.":
print(f"Waiting off the rate limit for {int(message[1])/1000}s")
time.sleep(int(message[1])/1000)
Prebuilt request functions
If you prefer to use a repo that already has prebuilt functions the Zenon repo on GitHub has a decent amount of predefined function to get you started.
Please stay tuned for updates and part 2!