-
Notifications
You must be signed in to change notification settings - Fork 0
/
discord.py
156 lines (125 loc) · 5.34 KB
/
discord.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
'''Methods to interact with Discord API.
Only a small subset of API endpoints are accounted for here.
Based on the Discord API Documentation https://discord.com/developers/docs/intro
'''
from http.client import responses
import os
from typing import Dict
import requests
from dotenv import load_dotenv
load_dotenv()
API_BASE = 'https://discordapp.com/api'
# Environment variables (all required)
BOT_TOKEN = os.environ.get('DISCORD_BOT_TOKEN')
CLIENT_ID = os.environ.get('DISCORD_CLIENT_ID')
CLIENT_SECRET = os.environ.get('DISCORD_CLIENT_SECRET')
REDIRECT_URI = os.environ.get('DISCORD_REDIRECT_URI')
SERVER_ID = os.environ.get('DISCORD_SERVER_ID')
VERIFIED_ROLE_ID = os.environ.get('DISCORD_VERIFIED_ROLE_ID')
# Authorization header with the bot token that allows us to do everything
HEADERS = {
'Authorization': 'Bot ' + BOT_TOKEN,
}
# The url users are redirected to to initiate the OAuth2 flow
OAUTH_URL = f'https://discord.com/api/oauth2/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=guilds.join%20identify'
def get_tokens(code):
'''
Given an authorization code, request the access and refresh tokens for a Discord user.
Returns the tokens. Throws an error if invalid request.
Discord docs: https://discord.com/developers/docs/topics/oauth2
'''
response = requests.post(f'{API_BASE}/oauth2/token',
data={
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI,
'scope': 'identity guilds.join'
},
headers={
'Content-Type': 'application/x-www-form-urlencoded'
}
)
response.raise_for_status()
tokens = response.json()
return tokens
def get_user_info(access_token):
'''
Given an access token, get a Discord user's info including id, username, discriminator, avatar url, etc.
Throws an error if invalid request.
Discord docs: https://discord.com/developers/docs/resources/user#get-current-user
'''
response = requests.get(f'{API_BASE}/users/@me', headers={
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
)
response.raise_for_status()
user = response.json()
return user
def get_member(user_id: str) -> Dict:
'''
Retreive a server member. Includes the user, their server nickname, roles, etc.
Discord docs: https://discord.com/developers/docs/resources/guild#get-guild-member
'''
response = requests.get(
f'{API_BASE}/guilds/{SERVER_ID}/members/{user_id}', headers=HEADERS)
response.raise_for_status()
return response.json()
def add_user_to_server(access_token: str, user_id: str, nickname: str):
'''
Given a Discord user's id, add them to the Discord server with their nickname
set as their RCS ID and with the verified role.
Discord docs: https://discord.com/developers/docs/resources/guild#add-guild-member
'''
response = requests.put(f'{API_BASE}/guilds/{SERVER_ID}/members/{user_id}',
json={
'access_token': access_token,
'nick': nickname,
'roles': [VERIFIED_ROLE_ID],
},
headers=HEADERS
)
response.raise_for_status()
return response
def kick_member_from_server(user_id: str):
'''
Remove a member from the server.
Discord docs: https://discord.com/developers/docs/resources/guild#remove-guild-member
'''
response = requests.delete(
f'{API_BASE}/guilds/{SERVER_ID}/members/{user_id}', headers=HEADERS)
response.raise_for_status()
return response
def set_member_nickname(user_id: str, nickname: str):
'''
Given a Discord user's id, set their nickname on the server.
Discord docs: https://discord.com/developers/docs/resources/guild#modify-guild-member
'''
response = requests.patch(f'{API_BASE}/guilds/{SERVER_ID}/members/{user_id}',
json={
'nick': nickname
},
headers=HEADERS
)
response.raise_for_status()
return response
def add_role_to_member(user_id: str, role_id: str):
'''
Add a role (identified by its id) to a member.
Discord docs: https://discord.com/developers/docs/resources/guild#add-guild-member-role
'''
response = requests.put(
f'{API_BASE}/guilds/{SERVER_ID}/members/{user_id}/roles/{role_id}', headers=HEADERS)
response.raise_for_status()
return response
def remove_role_from_member(user_id: str, role_id: str):
'''
Remove a role (identified by its id) from a member.
Discord docs: https://discord.com/developers/docs/resources/guild#remove-guild-member-role
'''
response = requests.delete(
f'{API_BASE}/guilds/{SERVER_ID}/members/{user_id}/roles/{role_id}', headers=HEADERS)
response.raise_for_status()
return response