Skip to content

Commit b6f793c

Browse files
Added fetch_channel_emotes & fetch_global_emotes methods (#331)
* Added fetch_channel_emotes & fetch_global_emotes methods * These changes are in response to PR comments * some fix update * fix an problem * Update models to reflect the rest of the libraries patters Co-authored-by: Tom <[email protected]>
1 parent 96b2365 commit b6f793c

File tree

6 files changed

+141
-2
lines changed

6 files changed

+141
-2
lines changed

docs/changelog.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
:orphan:
1+
:orphan:
2+
23

34
Master
45
======
56
- TwitchIO
67
- Additions
8+
- Added :func:`~twitchio.PartialUser.fetch_channel_emotes` to :class:`~twitchio.PartialUser`
9+
- Added :func:`~twitchio.Client.fetch_global_emotes` to :class:`~twitchio.Client`
710
- Added :func:`~twitchio.Client.event_channel_join_failure` event:
811
- This is dispatched when the bot fails to join a channel
912
- This also makes the channel join error message in logs optional

docs/reference.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ Channel
6666
:members:
6767
:inherited-members:
6868

69+
ChannelEmote
70+
------------
71+
.. attributetable:: ChannelEmote
72+
73+
.. autoclass:: ChannelEmote
74+
:members:
75+
:inherited-members:
76+
6977
ChannelInfo
7078
------------
7179
.. attributetable:: ChannelInfo
@@ -183,6 +191,14 @@ Game
183191
:members:
184192
:inherited-members:
185193

194+
GlobalEmote
195+
------------
196+
.. attributetable:: GlobalEmote
197+
198+
.. autoclass:: GlobalEmote
199+
:members:
200+
:inherited-members:
201+
186202
Goal
187203
------
188204
.. attributetable:: Goal

twitchio/client.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,20 @@ async def fetch_cheermotes(self, user_id: int = None):
572572
"""
573573
data = await self._http.get_cheermotes(str(user_id) if user_id else None)
574574
return [models.CheerEmote(self._http, x) for x in data]
575+
576+
async def fetch_global_emotes(self):
577+
"""|coro|
578+
579+
Fetches global emotes from the twitch API
580+
581+
Returns
582+
--------
583+
List[:class:`twitchio.GlobalEmote`]
584+
"""
585+
from .models import GlobalEmote
586+
587+
data = await self._http.get_global_emotes()
588+
return [GlobalEmote(self._http, x) for x in data]
575589

576590
async def fetch_top_games(self) -> List[models.Game]:
577591
"""|coro|
@@ -1019,4 +1033,4 @@ async def event_channel_join_failure(self, channel: str):
10191033
channel: `str`
10201034
The channel name that was attempted to be joined.
10211035
"""
1022-
logger.error(f'The channel "{channel}" was unable to be joined. Check the channel is valid.')
1036+
logger.error(f'The channel "{channel}" was unable to be joined. Check the channel is valid.')

twitchio/http.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,12 @@ async def get_bits_board(
334334
async def get_cheermotes(self, broadcaster_id: str):
335335
return await self.request(Route("GET", "bits/cheermotes", "", query=[("broadcaster_id", broadcaster_id)]))
336336

337+
async def get_channel_emotes(self, broadcaster_id: str):
338+
return await self.request(Route("GET", "chat/emotes", "", query=[("broadcaster_id", broadcaster_id)]))
339+
340+
async def get_global_emotes(self):
341+
return await self.request(Route("GET", "chat/emotes/global", ""))
342+
337343
async def get_extension_transactions(self, extension_id: str, ids: List[Any] = None):
338344
q = [("extension_id", extension_id)]
339345
if ids:

twitchio/models.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
"Clip",
3838
"CheerEmote",
3939
"CheerEmoteTier",
40+
"GlobalEmote",
41+
"ChannelEmote",
4042
"HypeTrainContribution",
4143
"HypeTrainEvent",
4244
"BanEvent",
@@ -174,6 +176,90 @@ def __repr__(self):
174176
return f"<CheerEmote prefix={self.prefix} type={self.type} order={self.order}>"
175177

176178

179+
class GlobalEmote:
180+
"""
181+
Represents a Global Emote
182+
183+
Attributes
184+
-----------
185+
id: :class:`str`
186+
The ID of the emote.
187+
name: :class:`str`
188+
The name of the emote.
189+
images: :class:`dict`
190+
Contains the image URLs for the emote. These image URLs will always provide a static (i.e., non-animated) emote image with a light background.
191+
format: List[:class:`str`]
192+
The formats that the emote is available in.
193+
scale: List[:class:`str`]
194+
The sizes that the emote is available in.
195+
theme_mode: List[:class:`str`]
196+
The background themes that the emote is available in.
197+
"""
198+
199+
__slots__ = (
200+
"id",
201+
"name",
202+
"images",
203+
"format",
204+
"scale",
205+
"theme_mode",
206+
"template"
207+
)
208+
209+
def __init__(self, http: "TwitchHTTP", data: dict):
210+
self.id: str = data["id"]
211+
self.name: str = data["name"]
212+
self.images: dict = data["images"]
213+
self.format: List[str] = data["format"]
214+
self.scale: List[str] = data["scale"]
215+
self.theme_mode: List[str] = data["theme_mode"]
216+
217+
def __repr__(self):
218+
return f"<GlobalEmote id={self.id} name={self.name}"
219+
220+
221+
class ChannelEmote(GlobalEmote):
222+
"""
223+
Represents a Channel Emote
224+
225+
Attributes
226+
-----------
227+
id: :class:`str`
228+
The ID of the emote.
229+
name: :class:`str`
230+
The name of the emote.
231+
images: :class:`dict`
232+
Contains the image URLs for the emote. These image URLs will always provide a static (i.e., non-animated) emote image with a light background.
233+
tier: :class:`str`
234+
The subscriber tier at which the emote is unlocked.
235+
type: :class:`str`
236+
The type of emote.
237+
set_id: :class:`str`
238+
An ID that identifies the emote set that the emote belongs to.
239+
format: List[:class:`str`]
240+
The formats that the emote is available in.
241+
scale: List[:class:`str`]
242+
The sizes that the emote is available in.
243+
theme_mode: List[:class:`str`]
244+
The background themes that the emote is available in.
245+
"""
246+
247+
__slots__ = (
248+
"tier",
249+
"type",
250+
"set_id"
251+
)
252+
253+
def __init__(self, http: "TwitchHTTP", data: dict):
254+
super().__init__(http, data)
255+
self.tier: str = data["tier"]
256+
self.type: str = data["emote_type"]
257+
self.set_id: str = data["emote_set_id"]
258+
259+
def __repr__(self):
260+
return f"<ChannelEmote id={self.id} name={self.name} type={self.type}>"
261+
262+
177263
class Clip:
178264
"""
179265
Represents a Twitch Clip

twitchio/user.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,20 @@ async def fetch_following_count(self, token: Optional[str] = None) -> int:
568568
"""
569569
data = await self._http.get_follow_count(token=token, from_id=str(self.id))
570570
return data["total"]
571+
572+
async def fetch_channel_emotes(self):
573+
"""|coro|
574+
575+
Fetches channel emotes from the user
576+
577+
Returns
578+
--------
579+
List[:class:`twitchio.ChannelEmote`]
580+
"""
581+
from .models import ChannelEmote
582+
583+
data = await self._http.get_channel_emotes(str(self.id))
584+
return [ChannelEmote(self._http, x) for x in data]
571585

572586
async def follow(self, userid: int, token: str, *, notifications=False):
573587
"""|coro|

0 commit comments

Comments
 (0)