Skip to content

Commit 7aa26f3

Browse files
committed
Add new endpoints
Adding a lot of new endpoints
1 parent 9176d47 commit 7aa26f3

File tree

5 files changed

+389
-9
lines changed

5 files changed

+389
-9
lines changed

docs/changelog.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,20 @@ Master
44
======
55
- TwitchIO
66
- Additions
7-
- Added :func:`twitchio.PartialUser.create_custom_reward` to allow custom reward creations
7+
- Added following new PartialUser methods:
8+
- :func:`twitchio.PartialUser.create_custom_reward`
9+
- :func:`twitchio.PartialUser.chat_announcement`
10+
- :func:`twitchio.PartialUser.delete_chat_messages`
11+
- :func:`twitchio.PartialUser.fetch_channel_vips`
12+
- :func:`twitchio.PartialUser.add_channel_vip`
13+
- :func:`twitchio.PartialUser.remove_channel_vip`
14+
- :func:`twitchio.PartialUser.add_channel_moderator`
15+
- :func:`twitchio.PartialUser.remove_channel_moderator`
16+
- :func:`twitchio.PartialUser.start_raid`
17+
- :func:`twitchio.PartialUser.cancel_raid`
18+
- Added following new Client methods:
19+
- :func:`~twitchio.Client.fetch_chatters_colors`
20+
- :func:`~twitchio.Client.update_chatter_color`
821
- Add ``duration`` and ``vod_offset`` attributes to :class:`~twitchio.Clip`
922
- Added repr for :class:`~twitchio.CustomReward`
1023
- Bug fixes

twitchio/client.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,48 @@ async def delete_videos(self, token: str, ids: List[int]) -> List[int]:
718718

719719
return resp
720720

721+
async def fetch_chatters_colors(self, user_ids: List[int], token: Optional[str] = None):
722+
"""|coro|
723+
724+
Fetches the color of a chatter.
725+
726+
Parameters
727+
-----------
728+
user_ids: List[:class:`int`]
729+
List of user ids to fetch the colors for
730+
token: Optional[:class:`str`]
731+
An oauth token with the channel:read:redirect scope
732+
733+
Returns
734+
--------
735+
List[:class:`twitchio.ChatterColor`]
736+
"""
737+
data = await self._http.get_user_chat_color(user_ids, token)
738+
return [models.ChatterColor(self._http, x) for x in data]
739+
740+
async def update_chatter_color(self, token: str, user_id: int, color: str):
741+
"""|coro|
742+
743+
Updates the color of the specified user in the specified channel/broadcaster's chat.
744+
745+
Parameters
746+
-----------
747+
token: :class:`str`
748+
An oauth token with the user:manage:chat_color scope.
749+
user_id: :class:`int`
750+
The ID of the user whose color is being updated, this must match the user ID in the token.
751+
color: :class:`str`
752+
Turbo and Prime users may specify a named color or a Hex color code like #9146FF.
753+
Please see the Twitch documentation for more information.
754+
755+
Returns
756+
--------
757+
None
758+
"""
759+
await self._http.put_user_chat_color(
760+
token=token, user_id=str(user_id), color=color
761+
)
762+
721763
async def get_webhook_subscriptions(self):
722764
"""|coro|
723765

twitchio/http.py

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ async def get_goals(self, broadcaster_id: str, token: str):
927927
return await self.request(Route("GET", "goals", query=[("broadcaster_id", broadcaster_id)], token=token))
928928

929929
async def get_chat_settings(
930-
self, broadcaster_id: str, moderator_id: Optional[str] = None, token: Optional[str] = None
930+
self, broadcaster_id: str, token: Optional[str] = None, moderator_id: Optional[str] = None
931931
):
932932
q = [("broadcaster_id", broadcaster_id)]
933933
if moderator_id and token:
@@ -936,9 +936,9 @@ async def get_chat_settings(
936936

937937
async def patch_chat_settings(
938938
self,
939+
token: str,
939940
broadcaster_id: str,
940941
moderator_id: str,
941-
token: str,
942942
emote_mode: Optional[bool] = None,
943943
follower_mode: Optional[bool] = None,
944944
follower_mode_duration: Optional[int] = None,
@@ -969,3 +969,69 @@ async def patch_chat_settings(
969969
}
970970
data = {k: v for k, v in data.items() if v is not None}
971971
return await self.request(Route("PATCH", "chat/settings", query=q, body=data, token=token))
972+
973+
async def post_chat_announcement(
974+
self, token: str, broadcaster_id: str, moderator_id: str, message: str, color: Optional[str] = "primary"
975+
):
976+
q = [("broadcaster_id", broadcaster_id), ("moderator_id", moderator_id)]
977+
body = {"message": message, "color": color}
978+
return await self.request(Route("POST", "chat/announcements", query=q, body=body, token=token))
979+
980+
async def delete_chat_messages(
981+
self, token: str, broadcaster_id: str, moderator_id: str, message_id: Optional[str] = None
982+
):
983+
q = [("broadcaster_id", broadcaster_id), ("moderator_id", moderator_id)]
984+
if message_id:
985+
q.append(("message_id", message_id))
986+
return await self.request(Route("DELETE", "moderation/chat", query=q, token=token))
987+
988+
async def put_user_chat_color(self, token: str, user_id: str, color: str):
989+
q = [("user_id", user_id), ("color", color)]
990+
return await self.request(Route("PUT", "chat/color", query=q, token=token))
991+
992+
async def get_user_chat_color(self, user_ids: List[int], token: Optional[str] = None):
993+
if len(user_ids) > 100:
994+
raise ValueError("You can only get up to 100 user chat colors at once")
995+
q = [("user_id", str(user_id)) for user_id in user_ids]
996+
return await self.request(Route("GET", "chat/color", query=q, token=token))
997+
998+
async def post_channel_moderator(self, token: str, broadcaster_id: str, user_id: str):
999+
q = [("broadcaster_id", broadcaster_id), ("user_id", user_id)]
1000+
return await self.request(Route("POST", "moderation/moderators", query=q, token=token))
1001+
1002+
async def delete_channel_moderator(self, token: str, broadcaster_id: str, user_id: str):
1003+
q = [("broadcaster_id", broadcaster_id), ("user_id", user_id)]
1004+
return await self.request(Route("DELETE", "moderation/moderators", query=q, token=token))
1005+
1006+
async def get_channel_vips(
1007+
self, token: str, broadcaster_id: str, first: int = 20, user_ids: Optional[List[str]] = None
1008+
):
1009+
q = [("broadcaster_id", broadcaster_id), ("first", first)]
1010+
if first > 100:
1011+
raise ValueError("You can only get up to 100 VIPs at once")
1012+
if user_ids and len(user_ids) <= 100:
1013+
q.extend(("user_id", user_id) for user_id in user_ids)
1014+
else:
1015+
raise ValueError("You can can only specify up to 100 VIPs")
1016+
return await self.request(Route("GET", "channels/vips", query=q, token=token))
1017+
1018+
async def post_channel_vip(self, token: str, broadcaster_id: str, user_id: str):
1019+
q = [("broadcaster_id", broadcaster_id), ("user_id", user_id)]
1020+
return await self.request(Route("POST", "channels/vips", query=q, token=token))
1021+
1022+
async def delete_channel_vip(self, token: str, broadcaster_id: str, user_id: str):
1023+
q = [("broadcaster_id", broadcaster_id), ("user_id", user_id)]
1024+
return await self.request(Route("DELETE", "channels/vips", query=q, token=token))
1025+
1026+
async def post_whisper(self, token: str, from_user_id: str, to_user_id: str, message: str):
1027+
q = [("from_user_id", from_user_id), ("to_user_id", to_user_id)]
1028+
body = {"message": message}
1029+
return await self.request(Route("POST", "whispers", query=q, body=body, token=token))
1030+
1031+
async def post_raid(self, token: str, from_broadcaster_id: str, to_broadcaster_id: str):
1032+
q = [("from_broadcaster_id", from_broadcaster_id), ("to_broadcaster_id", to_broadcaster_id)]
1033+
return await self.request(Route("POST", "raids", query=q, token=token))
1034+
1035+
async def delete_raid(self, token: str, broadcaster_id: str):
1036+
q = [("broadcaster_id", broadcaster_id)]
1037+
return await self.request(Route("DELETE", "raids", query=q, token=token))

twitchio/models.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
"PollChoice",
7171
"Goal",
7272
"ChatSettings",
73+
"Raid",
74+
"ChatterColor"
7375
)
7476

7577

@@ -1559,3 +1561,47 @@ def __init__(self, http: "TwitchHTTP", data: dict):
15591561

15601562
def __repr__(self):
15611563
return f"<ChatSettings broadcaster={self.broadcaster} emote_mode={self.emote_mode} follower_mode={self.follower_mode} slow_mode={self.slow_mode} subscriber_mode={self.subscriber_mode} unique_chat_mode={self.unique_chat_mode}>"
1564+
1565+
1566+
class ChatterColor:
1567+
"""
1568+
Represents chatters current name color.
1569+
1570+
Attributes
1571+
-----------
1572+
user: :class:`~twitchio.PartialUser`
1573+
PartialUser of the chatter.
1574+
color: :class:`str`
1575+
The color of the chatter's name.
1576+
"""
1577+
1578+
__slots__ = ("user", "color")
1579+
1580+
def __init__(self, http: "TwitchHTTP", data: dict):
1581+
self.user = PartialUser(http, data["user_id"], data["user_login"])
1582+
self.color: str = data["color"]
1583+
1584+
def __repr__(self):
1585+
return f"<ChatterColor user={self.user} color={self.color}>"
1586+
1587+
1588+
class Raid:
1589+
"""
1590+
Represents a raid for a broadcaster / channel
1591+
1592+
Attributes
1593+
-----------
1594+
created_at: :class:`datetime.datetime`
1595+
Date and time of when the raid started.
1596+
is_mature: :class:`bool`
1597+
Indicates whether the stream being raided is marked as mature.
1598+
"""
1599+
1600+
__slots__ = ("created_at", "is_mature")
1601+
1602+
def __init__(self, data: dict):
1603+
self.created_at: datetime.datetime = parse_timestamp(data["created_at"])
1604+
self.is_mature: bool = data["is_mature"]
1605+
1606+
def __repr__(self):
1607+
return f"<Raid created_at={self.created_at} is_mature={self.is_mature}>"

0 commit comments

Comments
 (0)