Skip to content

Commit 5aad5b2

Browse files
committed
rewrote the library, adding new features and more
1 parent dc0825a commit 5aad5b2

File tree

1 file changed

+130
-125
lines changed

1 file changed

+130
-125
lines changed

discordoauth2.py

Lines changed: 130 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,148 @@
11
import requests
22

3-
# class User():
4-
# def __init__(self, data: dict):
5-
# self.id = int(data["id"])
6-
# self.username = data["username"]
7-
# self.avatar = data.get("avatar")
8-
# self.discriminator = data["discriminator"]
9-
# self.public_flags = data.get("public_flags")
10-
# self.flags = data.get("flags")
11-
# self.banner = data.get("banner")
12-
# self.accent_color = data.get("accent_color")
13-
# self.locale = data.get("locale")
14-
# self.mfa_enabled = data.get("mfa_enabled")
15-
# self.nitro_type = data.get("premium_type")
16-
# self.email = data.get("email")
17-
# self.email_verified = data.get("verified")
18-
19-
# @property
20-
# def avatar_url(self):
21-
# if not self.avatar: return None
22-
# return f"https://cdn.discordapp.com/avatars/{self.id}/{self.avatar}.{'png' if not self.avatar.startswith('a_') else '.gif'}?size=1024"
23-
24-
# @property
25-
# def banner_url(self):
26-
# if not self.banner: return None
27-
# return f"https://cdn.discordapp.com/banners/{self.id}/{self.banner}.{'png' if not self.avatar.startswith('a_') else '.gif'}?size=1024"
28-
29-
class access_token():
30-
def __init__(self, response, client):
31-
self.client = client
32-
self.expires = response["expires_in"]
33-
self.token = response["access_token"]
34-
self.scope = response["scope"].split(" ")
35-
self.refresh_token = response["refresh_token"]
3+
class PartialAccessToken():
4+
def __init__(self, access_token, client) -> None:
5+
self.client: Client = client
6+
self.token = access_token
367

37-
self.webhook = response.get("webhook")
38-
self.guild = response.get("guild")
8+
def fetch_identify(self):
9+
response = requests.get("https://discord.com/api/v10/users/@me", headers={
10+
"authorization": f"Bearer {self.token}"
11+
})
3912

40-
self.__identify_cache = None
41-
42-
def identify(self):
43-
if not "identify" in self.scope: raise exceptions.MissingScope(f"identify scope wasn't granted")
44-
response = requests.get(url="https://discord.com/api/v10/users/@me",headers={
45-
'Authorization': f'Bearer {self.token}'
46-
})
13+
if response.ok:
14+
return response.json()
15+
elif response.status_code == 401: raise exceptions.Forbidden(f"this AccessToken does not have the nessasary scope.")
16+
elif response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}", retry_after=response.json()['retry_after'])
17+
else:
18+
raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
19+
20+
def fetch_connections(self):
21+
response = requests.get("https://discord.com/api/v10/users/@me/connections", headers={
22+
"authorization": f"Bearer {self.token}"
23+
})
4724

48-
if response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}")
49-
elif not response.ok: raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
50-
user = response.json()
51-
self.__identify_cache = user
52-
return user
25+
if response.ok:
26+
return response.json()
27+
elif response.status_code == 401: raise exceptions.Forbidden(f"this AccessToken does not have the nessasary scope.")
28+
elif response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}", retry_after=response.json()['retry_after'])
29+
else:
30+
raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
31+
32+
def fetch_guilds(self):
33+
response = requests.get("https://discord.com/api/v10/users/@me/guilds", headers={
34+
"authorization": f"Bearer {self.token}"
35+
})
5336

54-
def connections(self):
55-
if not "connections" in self.scope: raise exceptions.MissingScope(f"connections scope wasn't granted")
56-
response = requests.get(url="https://discord.com/api/v10/users/@me/connections", headers={
57-
'Authorization': f'Bearer {self.token}'
58-
})
37+
if response.ok:
38+
return response.json()
39+
elif response.status_code == 401: raise exceptions.Forbidden(f"this AccessToken does not have the nessasary scope.")
40+
elif response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}", retry_after=response.json()['retry_after'])
41+
else:
42+
raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
43+
44+
def fetch_guild_member(self, guild_id):
45+
response = requests.get(f"https://discord.com/api/v10/users/@me/guilds/{guild_id}/member", headers={
46+
"authorization": f"Bearer {self.token}"
47+
})
5948

60-
if response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}")
61-
elif not response.ok: raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
62-
return response.json()
49+
if response.ok:
50+
return response.json()
51+
elif response.status_code == 401: raise exceptions.Forbidden(f"this AccessToken does not have the nessasary scope.")
52+
elif response.status_code == 404: raise exceptions.HTTPException(f"user is not in this guild.")
53+
elif response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}", retry_after=response.json()['retry_after'])
54+
else:
55+
raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
56+
57+
def join_guild(self, guild_id, nick = None, role_ids = None, mute = False, deaf = False):
58+
response = requests.put(f"https://discord.com/api/v10/guilds/{guild_id}/members/621878678405775379", headers={
59+
"authorization": f"Bot {self.client._Client__bot_token}"
60+
}, json={
61+
"access_token": self.token,
62+
"nick": nick,
63+
"roles": role_ids,
64+
"mute": mute,
65+
"deaf": deaf,
66+
})
6367

64-
def guilds(self):
65-
if not "guilds" in self.scope: raise exceptions.MissingScope(f"guilds scope wasn't granted")
66-
response = requests.get(url="https://discord.com/api/v10/users/@me/guilds",headers={
67-
'Authorization': f'Bearer {self.token}'
68-
})
69-
if response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}")
70-
elif not response.ok: raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
71-
return response.json()
68+
if response.status_code == 204:
69+
raise exceptions.HTTPException(f"member is already in the guild.")
70+
elif response.ok:
71+
return response.json()
72+
elif response.status_code == 401: raise exceptions.Forbidden(f"this AccessToken does not have the nessasary scope.")
73+
elif response.status_code == 403: raise exceptions.Forbidden(f"the Bot token must be for a bot in the guild that has permissions to create invites in the target guild and must have any other required permissions.")
74+
elif response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}", retry_after=response.json()['retry_after'])
75+
else:
76+
raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
7277

73-
def guilds_member(self, guild):
74-
if not "guilds.members.read" in self.scope: raise exceptions.MissingScope(f"guilds.members.read scope wasn't granted")
75-
response = requests.get(url=f"https://discord.com/api/v10/users/@me/guilds/{guild}/member",headers={
76-
'Authorization': f'Bearer {self.token}'
77-
})
78-
if response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}")
79-
elif not response.ok: raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
80-
return response.json()
81-
82-
def guilds_join(self, guild):
83-
if not self.__identify_cache: raise exceptions.BaseException(f"you must call identify before guilds.join!")
84-
if not "guilds.join" in self.scope: raise exceptions.MissingScope(f"guilds.join scope wasn't granted")
85-
response = requests.put(url=f"https://discord.com/api/v10/guilds/{guild}/members/{self.__identify_cache['id']}", json={
86-
'Authorization': f'Bot {self.client.bot_token}',
87-
}, headers={
88-
'access_token': self.token
89-
})
78+
class AccessToken(PartialAccessToken):
79+
def __init__(self, data: dict, client) -> None:
80+
super().__init__(data["access_token"], client)
9081

91-
if response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}")
92-
elif not response.ok: raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
93-
return response.json()
82+
self.expires = data.get("expires_in")
83+
self.scope = data.get("scope", "").split(" ")
84+
self.refresh_token = data.get("refresh_token")
85+
self.webhook = data.get("webhook")
86+
self.guild = data.get("guild")
9487

9588
class Client():
96-
def __init__(self, id, secret, redirect, bot_token=None):
97-
self.id = id
98-
self.secret = secret
99-
self.redirect = redirect
100-
self.bot_token = bot_token
101-
102-
def exchange_code(self, token):
103-
response = requests.post("https://discord.com/api/v10/oauth2/token", data={
104-
'client_id': self.id,
105-
'client_secret': self.secret,
106-
'grant_type': 'authorization_code',
107-
'code': token,
108-
'redirect_uri': self.redirect
109-
})
89+
def __init__(self, id, secret, redirect, bot_token=None):
90+
self.id = id
91+
self.redirect_url = redirect
92+
self.__secret = secret
93+
self.__bot_token = bot_token
94+
95+
def from_access_token(self, access_token):
96+
return PartialAccessToken(access_token, self)
97+
98+
def exchange_code(self, code):
99+
response = requests.post("https://discord.com/api/v10/oauth2/token", data={
100+
"grant_type": "authorization_code", "code": code,
101+
"client_id": self.id, "client_secret": self.__secret,
102+
"redirect_uri": self.redirect_url})
110103

111-
if response.status_code == 429: raise Exception(f"You are being Rate Limited")
112-
elif response.status_code != 200: raise Exception(f"Something went wrong. Status Code: {response.status_code}")
113-
return access_token(response.json(), self)
114-
115-
def refresh_token(self, refresh_token):
116-
response = requests.post("https://discord.com/api/v10/oauth2/token", data={
117-
'client_id': self.id,
118-
'client_secret': self.secret,
119-
'grant_type': 'refresh_token',
120-
'refresh_token': refresh_token
121-
})
104+
if response.ok:
105+
return AccessToken(response.json(), self)
106+
elif response.status_code == 400: raise exceptions.HTTPException("the code, client id, client secret or the redirect uri is invalid/don't match.")
107+
elif response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}", retry_after=response.json()['retry_after'])
108+
else:
109+
raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
110+
111+
def refresh_token(self, refresh_token):
112+
response = requests.post("https://discord.com/api/v10/oauth2/token", data={
113+
"grant_type": "refresh_token", "refresh_token": refresh_token,
114+
"client_id": self.id, "client_secret": self.__secret})
115+
116+
if response.ok:
117+
return AccessToken(response.json(), self)
118+
elif response.status_code == 400: raise exceptions.HTTPException("the refresh token, client id or client secret is invalid/don't match.")
119+
elif response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}", retry_after=response.json()['retry_after'])
120+
else:
121+
raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
122122

123-
if response.status_code == 429: raise Exception(f"You are being Rate Limited")
124-
elif response.status_code != 200: raise Exception(f"Something went wrong. Status Code: {response.status_code}")
125-
return access_token(response.json(), self)
126-
123+
def client_credentails_grant(self, scope):
124+
response = requests.post("https://discord.com/api/v10/oauth2/token", data={
125+
"grant_type": "client_credentials", "scope": " ".join(scope)},
126+
auth=(self.id, self.__secret))
127+
128+
if response.ok:
129+
return AccessToken(response.json(), self)
130+
elif response.status_code == 400: raise exceptions.HTTPException("the scope, client id or client secret is invalid/don't match.")
131+
elif response.status_code == 429: raise exceptions.RateLimited(f"You are being Rate Limited. Retry after: {response.json()['retry_after']}", retry_after=response.json()['retry_after'])
132+
else:
133+
raise exceptions.HTTPException(f"Unexpected HTTP {response.status_code}")
134+
127135
class exceptions():
128-
class BaseException(Exception):
129-
pass
136+
class BaseException(Exception):
137+
pass
130138

131-
class HTTPException(BaseException):
132-
pass
139+
class HTTPException(BaseException):
140+
pass
133141

134-
class RateLimited(HTTPException):
135-
def __init__(self, text, retry_after):
136-
self.retry_after = retry_after
137-
super().__init__(text)
142+
class RateLimited(HTTPException):
143+
def __init__(self, text, retry_after):
144+
self.retry_after = retry_after
145+
super().__init__(text)
138146

139-
class Forbidden(HTTPException):
140-
pass
141-
142-
class MissingScope(BaseException):
143-
pass
147+
class Forbidden(HTTPException):
148+
pass

0 commit comments

Comments
 (0)