Skip to content

Commit

Permalink
Add get_hash to CommandTree
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeshardmind committed Jan 18, 2025
1 parent d5c80b6 commit 116fff5
Showing 1 changed file with 34 additions and 9 deletions.
43 changes: 34 additions & 9 deletions discord/app_commands/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from __future__ import annotations
import logging
import inspect
from hashlib import blake2b

from typing import (
Any,
Expand Down Expand Up @@ -62,7 +63,7 @@
from .translator import Translator, locale_str
from ..errors import ClientException, HTTPException
from ..enums import AppCommandType, InteractionType
from ..utils import MISSING, _get_as_snowflake, _is_submodule, _shorten
from ..utils import MISSING, _get_as_snowflake, _is_submodule, _shorten, _to_json
from .._types import ClientT


Expand Down Expand Up @@ -1076,6 +1077,17 @@ async def set_translator(self, translator: Optional[Translator]) -> None:
await translator.load()
self._state._translator = translator

async def _get_payload(self, *, guild: Optional[Snowflake] = None) -> List[Dict[str, Any]]:
commands = self._get_all_commands(guild=guild)

translator = self.translator
if translator:
payload = [await command.get_translated_payload(self, translator) for command in commands]
else:
payload = [command.to_dict(self) for command in commands]

return payload

async def sync(self, *, guild: Optional[Snowflake] = None) -> List[AppCommand]:
"""|coro|
Expand Down Expand Up @@ -1116,13 +1128,7 @@ async def sync(self, *, guild: Optional[Snowflake] = None) -> List[AppCommand]:
if self.client.application_id is None:
raise MissingApplicationID

commands = self._get_all_commands(guild=guild)

translator = self.translator
if translator:
payload = [await command.get_translated_payload(self, translator) for command in commands]
else:
payload = [command.to_dict(self) for command in commands]
payload = await self._get_payload(guild=guild)

try:
if guild is None:
Expand All @@ -1131,7 +1137,7 @@ async def sync(self, *, guild: Optional[Snowflake] = None) -> List[AppCommand]:
data = await self._http.bulk_upsert_guild_commands(self.client.application_id, guild.id, payload=payload)
except HTTPException as e:
if e.status == 400 and e.code == 50035:
raise CommandSyncFailure(e, commands) from None
raise CommandSyncFailure(e, self._get_all_commands(guild=guild)) from None
raise

return [AppCommand(data=d, state=self._state) for d in data]
Expand Down Expand Up @@ -1315,3 +1321,22 @@ async def _call(self, interaction: Interaction[ClientT]) -> None:
else:
if not interaction.command_failed:
self.client.dispatch('app_command_completion', interaction, command)

async def get_hash(self, *, guild: Optional[Snowflake] = None) -> str:
"""|coro|
Returns a hash for tree's state, either for the global tree
if no guild is provided, or the guild specific portions of
the tree if a guild is provided.
This can be used to avoid uneccessary syncing.
Parameters
-----------
guild: Optional[:class:`~discord.abc.Snowflake`]
"""
payload = await self._get_payload(guild=guild)
# versioning allows the method to be changed in the future
# blake2 is the fastest collision resistant hash guaranteed
# to be available in the standard library at time of writing.
return "v1:" + blake2b(_to_json(payload).encode()).hexdigest()

0 comments on commit 116fff5

Please sign in to comment.