Skip to content

Instantly share code, notes, and snippets.

@lexicalunit
Last active September 30, 2021 21:56
Show Gist options
  • Save lexicalunit/362bd34bc02a7e8362e8e2b43c9426e2 to your computer and use it in GitHub Desktop.
Save lexicalunit/362bd34bc02a7e8362e8e2b43c9426e2 to your computer and use it in GitHub Desktop.
Automatically sync commands only if needed
import json
import logging
from typing import Any, List, cast
import discord
from deepdiff.diff import DeepDiff
from discord_slash import SlashCommand
from discord.ext.commands import Bot
logger = logging.getLogger(__name__)
settings = ...
class SpellBot(Bot):
slash: SlashCommand
def __init__(self):
super().__init__(
command_prefix="unused",
self_bot=True,
help_command=None,
intents=discord.Intents().default(),
)
async def on_ready(self):
await self.sync_commands_if_needed()
async def sync_commands_if_needed(self):
def strip_keys(d: dict, *keys: str):
for key in list(d.keys()):
if key in keys:
del d[key]
continue
val = d[key]
if isinstance(val, dict):
strip_keys(val, *keys)
elif isinstance(val, list):
for i in val:
if isinstance(i, dict):
strip_keys(i, *keys)
def strip_empty_values(d: dict, *keys: str):
for key in list(d.keys()):
val = d[key]
if key in keys:
if not val:
del d[key]
continue
if isinstance(val, dict):
strip_empty_values(val, *keys)
elif isinstance(val, list):
for i in val:
if isinstance(i, dict):
strip_empty_values(i, *keys)
remote_l: List[Any] = cast(
List[Any],
await self.slash.req.get_all_commands(settings.DEBUG_GUILD or None),
)
remote_d = {"data": remote_l}
strip_keys(
remote_d,
"application_id",
"version",
"default_permission",
"guild_id",
"id",
)
strip_empty_values(remote_d, "description")
remote_j = json.dumps(remote_d, sort_keys=True)
remote_d = json.loads(remote_j)
local_d = await self.slash.to_dict()
local_d = {"data": local_d["global"]}
strip_keys(local_d, "default_permission", "permissions")
strip_empty_values(local_d, "options", "required")
local_j = json.dumps(local_d, sort_keys=True)
local_d = json.loads(local_j)
diff = DeepDiff(remote_d, local_d, ignore_order=True)
if diff:
logger.info(f"change in commands detected: {diff=}")
await self.slash.sync_all_commands()
def build_bot() -> SpellBot:
bot = SpellBot()
bot.slash = SlashCommand(bot, debug_guild=settings.DEBUG_GUILD or None)
# ...load cogs...
return bot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment