Skip to content

Commit 91306d7

Browse files
committed
Feat: Add support for Application Emoji
1 parent 5b07e41 commit 91306d7

File tree

4 files changed

+126
-3
lines changed

4 files changed

+126
-3
lines changed

interactions/api/http/http_requests/emojis.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,88 @@ async def delete_guild_emoji(
110110
Route("DELETE", "/guilds/{guild_id}/emojis/{emoji_id}", guild_id=guild_id, emoji_id=emoji_id),
111111
reason=reason,
112112
)
113+
114+
async def get_application_emojis(self, application_id: "Snowflake_Type") -> list[discord_typings.EmojiData]:
115+
"""
116+
Fetch all emojis for this application
117+
118+
Args:
119+
application_id: The id of the application
120+
121+
Returns:
122+
List of emojis
123+
124+
"""
125+
result = await self.request(Route("GET", f"/applications/{application_id}/emojis"))
126+
result = cast(dict, result)
127+
return cast(list[discord_typings.EmojiData], result["items"])
128+
129+
async def get_application_emoji(
130+
self, application_id: "Snowflake_Type", emoji_id: "Snowflake_Type"
131+
) -> discord_typings.EmojiData:
132+
"""
133+
Fetch an emoji for this application
134+
135+
Args:
136+
application_id: The id of the application
137+
emoji_id: The id of the emoji
138+
139+
Returns:
140+
Emoji object
141+
142+
"""
143+
result = await self.request(Route("GET", f"/applications/{application_id}/emojis/{emoji_id}"))
144+
return cast(discord_typings.EmojiData, result)
145+
146+
async def create_application_emoji(
147+
self, payload: dict, application_id: "Snowflake_Type", reason: str | None = None
148+
) -> discord_typings.EmojiData:
149+
"""
150+
Create an emoji for this application
151+
152+
Args:
153+
application_id: The id of the application
154+
name: The name of the emoji
155+
imagefile: The image file to use for the emoji
156+
157+
Returns:
158+
Emoji object
159+
160+
"""
161+
result = await self.request(
162+
Route("POST", f"/applications/{application_id}/emojis"), payload=payload, reason=reason
163+
)
164+
return cast(discord_typings.EmojiData, result)
165+
166+
async def edit_application_emoji(
167+
self, application_id: "Snowflake_Type", emoji_id: "Snowflake_Type", name: str
168+
) -> discord_typings.EmojiData:
169+
"""
170+
Edit an emoji for this application
171+
172+
Args:
173+
application_id: The id of the application
174+
emoji_id: The id of the emoji
175+
name: The new name for the emoji
176+
177+
Returns:
178+
Emoji object
179+
180+
"""
181+
result = await self.request(
182+
Route("PATCH", f"/applications/{application_id}/emojis/{emoji_id}"), payload={"name": name}
183+
)
184+
return cast(discord_typings.EmojiData, result)
185+
186+
async def delete_application_emoji(
187+
self, application_id: discord_typings.Snowflake, emoji_id: discord_typings.Snowflake
188+
) -> None:
189+
"""
190+
Delete an emoji for this application
191+
192+
Args:
193+
application_id: The id of the application
194+
emoji_id: The id of the emoji
195+
196+
"""
197+
await self.request(Route("DELETE", f"/applications/{application_id}/emojis/{emoji_id}"))

interactions/client/smart_cache.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ def place_guild_data(self, data: discord_typings.GuildData) -> Guild:
642642
643643
"""
644644
guild_id = to_snowflake(data["id"])
645-
guild: Guild = self.guild_cache.get(guild_id)
645+
guild: Guild | None = self.guild_cache.get(guild_id)
646646
if guild is None:
647647
guild = Guild.from_dict(data, self._client)
648648
self.guild_cache[guild_id] = guild
@@ -929,7 +929,7 @@ def place_emoji_data(self, guild_id: "Snowflake_Type", data: discord_typings.Emo
929929
with suppress(KeyError):
930930
del data["guild_id"] # discord sometimes packages a guild_id - this will cause an exception
931931

932-
emoji = CustomEmoji.from_dict(data, self._client, to_snowflake(guild_id))
932+
emoji = CustomEmoji.from_dict(data, self._client, to_optional_snowflake(guild_id))
933933
if self.emoji_cache is not None:
934934
self.emoji_cache[emoji.id] = emoji
935935

interactions/models/discord/application.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
from interactions.client.const import MISSING
66
from interactions.client.utils.attr_converters import optional
7+
from interactions.client.utils.serializer import to_image_data
78
from interactions.models.discord.asset import Asset
9+
from interactions.models.discord.emoji import PartialEmoji
810
from interactions.models.discord.enums import ApplicationFlags
11+
from interactions.models.discord.file import UPLOADABLE_TYPE
912
from interactions.models.discord.snowflake import Snowflake_Type, to_snowflake
1013
from interactions.models.discord.team import Team
1114
from .base import DiscordObject
@@ -88,3 +91,36 @@ def _process_dict(cls, data: Dict[str, Any], client: "Client") -> Dict[str, Any]
8891
def owner(self) -> "User":
8992
"""The user object for the owner of this application"""
9093
return self._client.cache.get_user(self.owner_id)
94+
95+
async def fetch_all_emoji(self) -> List[PartialEmoji]:
96+
"""Fetch all emojis for this application"""
97+
response = await self._client.http.get_application_emojis(self.id)
98+
return [self._client.cache.place_emoji_data(None, emoji) for emoji in response]
99+
100+
async def fetch_emoji(self, emoji_id: Snowflake_Type) -> PartialEmoji:
101+
"""Fetch an emoji for this application"""
102+
return await self._client.cache.place_emoji_data(
103+
None, self._client.http.get_application_emoji(self.id, emoji_id)
104+
)
105+
106+
async def create_emoji(self, name: str, imagefile: UPLOADABLE_TYPE) -> PartialEmoji:
107+
"""Create an emoji for this application"""
108+
data_payload = {
109+
"name": name,
110+
"image": to_image_data(imagefile),
111+
"roles": MISSING,
112+
}
113+
114+
return self._client.cache.place_emoji_data(
115+
None, await self._client.http.create_application_emoji(data_payload, self.id)
116+
)
117+
118+
async def edit_emoji(self, emoji_id: Snowflake_Type, name: str) -> PartialEmoji:
119+
"""Edit an emoji for this application"""
120+
return await self._client.cache.place_emoji_data(
121+
None, self._client.http.edit_application_emoji(self.id, emoji_id, name)
122+
)
123+
124+
async def delete_emoji(self, emoji_id: Snowflake_Type) -> None:
125+
"""Delete an emoji for this application"""
126+
return await self._client.http.delete_application_emoji(self.id, emoji_id)

interactions/models/discord/emoji.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class PartialEmoji(SnowflakeObject, DictSerializationMixin):
3838
"""The custom emoji name, or standard unicode emoji in string"""
3939
animated: bool = attrs.field(repr=True, default=False)
4040
"""Whether this emoji is animated"""
41+
available: bool = attrs.field(repr=False, default=True)
42+
"""whether this emoji can be used, may be false due to loss of Server Boosts"""
4143

4244
@classmethod
4345
def from_str(cls, emoji_str: str, *, language: str = "alias") -> Optional["PartialEmoji"]:
@@ -120,7 +122,7 @@ class CustomEmoji(PartialEmoji, ClientObject):
120122
_role_ids: List["Snowflake_Type"] = attrs.field(
121123
repr=False, factory=list, converter=optional(list_converter(to_snowflake))
122124
)
123-
_guild_id: "Snowflake_Type" = attrs.field(repr=False, default=None, converter=to_snowflake)
125+
_guild_id: "Snowflake_Type" = attrs.field(repr=False, default=None, converter=optional(to_snowflake))
124126

125127
@classmethod
126128
def _process_dict(cls, data: Dict[str, Any], client: "Client") -> Dict[str, Any]:

0 commit comments

Comments
 (0)