Skip to content
This repository was archived by the owner on Mar 8, 2022. It is now read-only.

Commit 6d64be5

Browse files
author
kuso-senpai
committed
added ratelimit handling
1 parent ab08023 commit 6d64be5

File tree

4 files changed

+97
-14
lines changed

4 files changed

+97
-14
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,18 @@ You can find more (and better) examples [here](https://github.com/discord-py-ui/
158158

159159
# Changelog
160160

161+
- <details>
162+
<summary>3.2.9</summary>
163+
## **Added**
164+
- ratelimit fix
165+
> The lib will now retry after the ratelimit reset and doesn't throw an HTTPException anymore
166+
167+
## **Fixed**
168+
- sync_commands
169+
> Got `KeyError` exception while syncing commands
170+
171+
</details>
172+
161173
- <details>
162174
<summary>3.2.8</summary>
163175

discord_ui/client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,11 @@ async def add_command(command):
303303
_id = str(x.id)
304304
api_coms = await self._get_guild_commands(_id)
305305
for apic in api_coms:
306-
if (added_commands["guilds"].get(int(_id)) is None and added_commands["guilds"].get(str(_id))) or added_commands["guilds"][_id].get(apic["name"]) is None:
306+
if added_commands["guilds"].get(int(_id)) is not None:
307+
_id = int(_id)
308+
elif added_commands["guilds"].get(str(_id)) is not None:
309+
_id = str(_id)
310+
if added_commands["guilds"].get(_id) is None or added_commands["guilds"][_id].get(apic["name"]) is None:
307311
logging.debug("deleting guild command '" + str(apic["name"]) + "' in guild " + str(_id))
308312
await delete_guild_command(self._discord, apic["id"], _id)
309313

discord_ui/http.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
import asyncio
12
from .errors import WrongType
2-
from .tools import MISSING, _or, components_to_dict
3+
from .tools import MISSING, _or, components_to_dict, setup_logger
34

45
import discord
56
from discord.http import Route
67

78
import json
89
from typing import List
910

11+
logging = setup_logger(__name__)
1012

1113
class BetterRoute(Route):
1214
BASE = "https://discord.com/api/v9"
@@ -109,3 +111,7 @@ def jsonifyMessage(content=MISSING, tts=False, embed: discord.Embed=MISSING, emb
109111
payload["stickers"] = [s.id for s in stickers]
110112

111113
return payload
114+
115+
def handle_rate_limit(data):
116+
logging.error("You are being rate limited. Retrying after " + str(data["retry_after"]) + " seconds")
117+
return asyncio.sleep(data["retry_after"])

discord_ui/slash/http.py

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import aiohttp
2+
from aiohttp.client_reqrep import ClientResponse
23
from ..tools import MISSING, get, setup_logger
3-
from ..http import BetterRoute
4+
from ..http import BetterRoute, handle_rate_limit
45

56
from discord.ext import commands as com
67
from discord.errors import Forbidden, HTTPException, NotFound
@@ -21,7 +22,7 @@ async def get_id(command_name, client: com.bot, guild_id=MISSING):
2122
async def delete_global_commands(client: com.Bot):
2223
commands = await client.http.request(BetterRoute("GET", f"/applications/{client.user.id}/commands"))
2324
for x in commands:
24-
await delete_global_command(client, x["id"])
25+
await delete_global_command(client, x["id"])
2526
async def delete_guild_commands(client: com.Bot, guild_id):
2627
try:
2728
commands = await client.http.request(BetterRoute("GET", f"/applications/{client.user.id}/guilds/{guild_id}/commands"))
@@ -31,37 +32,97 @@ async def delete_guild_commands(client: com.Bot, guild_id):
3132
logging.warn("got forbidden in " + str(guild_id))
3233

3334
async def delete_global_command(client: com.Bot, command_id):
34-
return await client.http.request(BetterRoute("DELETE", f"/applications/{client.user.id}/commands/{command_id}"))
35+
try:
36+
return await client.http.request(BetterRoute("DELETE", f"/applications/{client.user.id}/commands/{command_id}"))
37+
except HTTPException as ex:
38+
if ex.status == 429:
39+
await handle_rate_limit(await ex.response.json())
40+
return await delete_global_command(client, command_id)
41+
raise ex
3542
async def delete_guild_command(client: com.Bot, command_id, guild_id):
36-
return await client.http.request(BetterRoute("DELETE", f"/applications/{client.user.id}/guilds/{guild_id}/commands/{command_id}"))
43+
try:
44+
return await client.http.request(BetterRoute("DELETE", f"/applications/{client.user.id}/guilds/{guild_id}/commands/{command_id}"))
45+
except HTTPException as ex:
46+
if ex.status == 429:
47+
await handle_rate_limit(await ex.response.json())
48+
return await delete_guild_command(client, command_id, guild_id)
49+
else:
50+
raise ex
51+
except Exception as ex:
52+
print("caught exception", ex)
3753

3854
async def get_command_permissions(client: com.Bot, command_id, guild_id):
3955
try:
4056
return await client.http.request(BetterRoute("GET", f"/applications/{client.user.id}/guilds/{guild_id}/commands/{command_id}/permissions"))
4157
except NotFound:
4258
return {"id": command_id, "application_id": client.user.id, "permissions": []}
59+
except HTTPException as ex:
60+
if ex.status == 429:
61+
await handle_rate_limit(await ex.response.json())
62+
return await get_command_permissions(client, command_id, guild_id)
63+
else:
64+
raise ex
4365
async def update_command_permissions(application_id, token, guild_id, command_id, permissions):
4466
async with aiohttp.ClientSession() as client:
4567
async with client.put(f"https://discord.com/api/v9/applications/{application_id}/guilds/{guild_id}/commands/{command_id}/permissions",
4668
headers={"Authorization": "Bot " + token}, json={"permissions": permissions}) as response:
4769
if response.status == 200:
4870
return await response.json()
71+
elif response.status == 429:
72+
await handle_rate_limit(await response.json())
73+
return await update_command_permissions(application_id, token, guild_id, command_id, permissions)
4974
raise HTTPException(response, response.content)
5075

5176
async def create_global_command(command: dict, client: com.Bot):
52-
return await client.http.request(BetterRoute("POST", f"/applications/{client.user.id}/commands"), json=command)
77+
try:
78+
return await client.http.request(BetterRoute("POST", f"/applications/{client.user.id}/commands"), json=command)
79+
except HTTPException as ex:
80+
if ex.status == 429:
81+
await handle_rate_limit(await ex.response.json())
82+
return await create_global_command(command, client)
83+
raise ex
5384
async def create_guild_command(command, client: com.Bot, guild_id, permissions = []):
54-
data = await client.http.request(BetterRoute("POST", f"/applications/{client.user.id}/guilds/{guild_id}/commands"), json=command)
55-
return await update_command_permissions(client.user.id, client.http.token, guild_id, data["id"], permissions)
85+
try:
86+
data = await client.http.request(BetterRoute("POST", f"/applications/{client.user.id}/guilds/{guild_id}/commands"), json=command)
87+
return await update_command_permissions(client.user.id, client.http.token, guild_id, data["id"], permissions)
88+
except HTTPException as ex:
89+
if ex.status == 429:
90+
await handle_rate_limit(await ex.response.json())
91+
return await create_guild_command(command, client, guild_id, permissions)
92+
raise ex
5693

5794

5895
async def edit_global_command(command_id: str, client: com.Bot, new_command: dict):
59-
return await client.http.request(BetterRoute("PATCH", f"/applications/{client.user.id}/commands/{command_id}"), json=new_command)
96+
try:
97+
return await client.http.request(BetterRoute("PATCH", f"/applications/{client.user.id}/commands/{command_id}"), json=new_command)
98+
except HTTPException as ex:
99+
if ex.status == 429:
100+
await handle_rate_limit(await ex.response.json())
101+
return await edit_global_command(command_id, client, new_command)
102+
raise ex
60103
async def edit_guild_command(command_id, client: com.Bot, guild_id: str, new_command: dict, permissions: dict):
61-
data = await client.http.request(BetterRoute("PATCH", f"/applications/{client.user.id}/guilds/{guild_id}/commands/{command_id}"), json=new_command)
62-
return await update_command_permissions(client.user.id, client.http.token, guild_id, data["id"], permissions)
104+
try:
105+
data = await client.http.request(BetterRoute("PATCH", f"/applications/{client.user.id}/guilds/{guild_id}/commands/{command_id}"), json=new_command)
106+
return await update_command_permissions(client.user.id, client.http.token, guild_id, data["id"], permissions)
107+
except HTTPException as ex:
108+
if ex.status == 429:
109+
await handle_rate_limit(await ex.response.json())
110+
return await edit_guild_command(command_id, client, guild_id, new_command, permissions)
111+
raise ex
63112

64113
async def get_global_commands(client):
65-
return await client.http.request(BetterRoute("GET", f"/applications/{client.user.id}/commands"))
114+
try:
115+
return await client.http.request(BetterRoute("GET", f"/applications/{client.user.id}/commands"))
116+
except HTTPException as ex:
117+
if ex.status == 429:
118+
await handle_rate_limit(await ex.response.json())
119+
return await get_global_commands(client)
120+
raise ex
66121
async def get_guild_commands(client, guild_id):
67-
return await client.http.request(BetterRoute("GET", f"/applications/{client.user.id}/guilds/{guild_id}/commands"))
122+
try:
123+
return await client.http.request(BetterRoute("GET", f"/applications/{client.user.id}/guilds/{guild_id}/commands"))
124+
except HTTPException as ex:
125+
if ex.status == 429:
126+
await handle_rate_limit(await ex.response.json())
127+
return await get_guild_commands(client, guild_id)
128+
raise ex

0 commit comments

Comments
 (0)