aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Matteo Bertucci <[email protected]>2021-10-04 20:39:51 +0200
committerGravatar GitHub <[email protected]>2021-10-04 20:39:51 +0200
commit16918d7c4d3925884b6ce5d1c4c326be4304f3f6 (patch)
treeebaf3ad701f2381345d10d060b53cad85007aec8
parentMerge pull request #1841 from python-discord/allow-helpers-to-edit-their-own-... (diff)
parentMove all monkey patches to their own file (diff)
Merge pull request #1853 from python-discord/catch-403-from-Typing-calls
Monkey patch http.send_typing to catch 403s
-rw-r--r--bot/__init__.py9
-rw-r--r--bot/command.py18
-rw-r--r--bot/monkey_patches.py50
3 files changed, 55 insertions, 22 deletions
diff --git a/bot/__init__.py b/bot/__init__.py
index 8f880b8e6..a1c4466f1 100644
--- a/bot/__init__.py
+++ b/bot/__init__.py
@@ -5,8 +5,7 @@ from typing import TYPE_CHECKING
from discord.ext import commands
-from bot import log
-from bot.command import Command
+from bot import log, monkey_patches
if TYPE_CHECKING:
from bot.bot import Bot
@@ -17,9 +16,11 @@ log.setup()
if os.name == "nt":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
+monkey_patches.patch_typing()
+
# Monkey-patch discord.py decorators to use the Command subclass which supports root aliases.
# Must be patched before any cogs are added.
-commands.command = partial(commands.command, cls=Command)
-commands.GroupMixin.command = partialmethod(commands.GroupMixin.command, cls=Command)
+commands.command = partial(commands.command, cls=monkey_patches.Command)
+commands.GroupMixin.command = partialmethod(commands.GroupMixin.command, cls=monkey_patches.Command)
instance: "Bot" = None # Global Bot instance.
diff --git a/bot/command.py b/bot/command.py
deleted file mode 100644
index 0fb900f7b..000000000
--- a/bot/command.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from discord.ext import commands
-
-
-class Command(commands.Command):
- """
- A `discord.ext.commands.Command` subclass which supports root aliases.
-
- A `root_aliases` keyword argument is added, which is a sequence of alias names that will act as
- top-level commands rather than being aliases of the command's group. It's stored as an attribute
- also named `root_aliases`.
- """
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.root_aliases = kwargs.get("root_aliases", [])
-
- if not isinstance(self.root_aliases, (list, tuple)):
- raise TypeError("Root aliases of a command must be a list or a tuple of strings.")
diff --git a/bot/monkey_patches.py b/bot/monkey_patches.py
new file mode 100644
index 000000000..9c0a22bfb
--- /dev/null
+++ b/bot/monkey_patches.py
@@ -0,0 +1,50 @@
+import logging
+from datetime import datetime, timedelta
+
+from discord import Forbidden, http
+from discord.ext import commands
+
+log = logging.getLogger(__name__)
+
+
+class Command(commands.Command):
+ """
+ A `discord.ext.commands.Command` subclass which supports root aliases.
+
+ A `root_aliases` keyword argument is added, which is a sequence of alias names that will act as
+ top-level commands rather than being aliases of the command's group. It's stored as an attribute
+ also named `root_aliases`.
+ """
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.root_aliases = kwargs.get("root_aliases", [])
+
+ if not isinstance(self.root_aliases, (list, tuple)):
+ raise TypeError("Root aliases of a command must be a list or a tuple of strings.")
+
+
+def patch_typing() -> None:
+ """
+ Sometimes discord turns off typing events by throwing 403's.
+
+ Handle those issues by patching the trigger_typing method so it ignores 403's in general.
+ """
+ log.info("Patching send_typing, which should fix things breaking when discord disables typing events. Stay safe!")
+
+ original = http.HTTPClient.send_typing
+ last_403 = None
+
+ async def honeybadger_type(self, channel_id: int) -> None: # noqa: ANN001
+ nonlocal last_403
+ if last_403 and (datetime.now() - last_403) < timedelta(minutes=5):
+ log.warning("Not sending typing event, we got a 403 less than 5 minutes ago.")
+ return
+ try:
+ await original(self, channel_id)
+ except Forbidden:
+ last_403 = datetime.now()
+ log.warning("Got a 403 from typing event!")
+ pass
+
+ http.HTTPClient.send_typing = honeybadger_type