Compare commits
10 Commits
b279a6c977
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| fc7cc89301 | |||
| 636ce6f914 | |||
| 7cbc08f35f | |||
| 52ff7d4150 | |||
| 4a8ecdf158 | |||
| a8c21af06e | |||
| dbb2c35504 | |||
| 899223dc56 | |||
| fbc628bc3b | |||
| bb99154131 |
@ -1,18 +1,18 @@
|
||||
repos:
|
||||
- repo: https://github.com/crate-ci/typos
|
||||
rev: v1.36.3
|
||||
rev: v1.42.0
|
||||
hooks:
|
||||
- id: typos
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.13.2
|
||||
rev: v0.14.13
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [ --fix ]
|
||||
- id: ruff-format
|
||||
|
||||
- repo: https://github.com/RobertCraigie/pyright-python
|
||||
rev: v1.1.405
|
||||
rev: v1.1.408
|
||||
hooks:
|
||||
- id: pyright
|
||||
|
||||
|
||||
170
README.md
170
README.md
@ -0,0 +1,170 @@
|
||||
# Twitch Client (Async)
|
||||
|
||||
An internal **async Twitch API client** built on top of **AioHTTPX**, providing typed access to the Twitch **Helix API** and **OAuth2** endpoints with built-in rate limiting and optional caching.
|
||||
|
||||
---
|
||||
|
||||
## What it provides
|
||||
|
||||
* `TwitchAPIClient` — async client for Twitch **Helix API**
|
||||
* `TwitchAuthClient` — async client for Twitch **OAuth2**
|
||||
* Built on **AioHTTPX** (aiohttp transport, Redis rate limiting & caching)
|
||||
* Strongly typed responses using **Pydantic models**
|
||||
* Automatic request parameter cleanup (`None` values removed)
|
||||
|
||||
---
|
||||
|
||||
## Installation (internal)
|
||||
|
||||
Configure your private package index, then:
|
||||
|
||||
```bash
|
||||
pip install twitchclient
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
### OAuth helper client
|
||||
|
||||
```python
|
||||
from twitchclient.auth import TwitchAuthClient
|
||||
from twitchclient import scopes
|
||||
|
||||
auth = TwitchAuthClient(
|
||||
client_id="CLIENT_ID",
|
||||
client_secret="CLIENT_SECRET",
|
||||
redirect_uri="https://your.app/callback",
|
||||
)
|
||||
|
||||
url = await auth.create_authorization_code_grant_flow_url(
|
||||
scope=[scopes.USER_READ_EMAIL, scopes.CHAT_READ],
|
||||
)
|
||||
```
|
||||
|
||||
### App access token
|
||||
|
||||
```python
|
||||
token = await auth.app_access_token()
|
||||
print(token.access_token)
|
||||
```
|
||||
|
||||
### User access token
|
||||
|
||||
```python
|
||||
token = await auth.user_access_token(code="AUTH_CODE")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Client
|
||||
|
||||
```python
|
||||
from twitchclient.api import TwitchAPIClient
|
||||
|
||||
client = TwitchAPIClient(
|
||||
client_id="CLIENT_ID",
|
||||
client_secret="CLIENT_SECRET",
|
||||
redirect_uri="https://your.app/callback",
|
||||
redis_url="redis://localhost:6379", # optional
|
||||
)
|
||||
```
|
||||
|
||||
* Base URL: `https://api.twitch.tv/helix`
|
||||
* `Client-Id` header is set automatically
|
||||
* Rate limit defaults to **700 req/min** when Redis is enabled
|
||||
|
||||
---
|
||||
|
||||
## Example usage
|
||||
|
||||
### Get channel information
|
||||
|
||||
```python
|
||||
channels = await client.get_channel_information(
|
||||
access_token=token.access_token,
|
||||
broadcaster_id=123456,
|
||||
)
|
||||
```
|
||||
|
||||
### Start a commercial
|
||||
|
||||
```python
|
||||
await client.start_commercial(
|
||||
access_token=token.access_token,
|
||||
broadcaster_id=123456,
|
||||
)
|
||||
```
|
||||
|
||||
### Cached request
|
||||
|
||||
Caching is controlled via the `X-Cache-TTL` header:
|
||||
|
||||
```python
|
||||
streams = await client.get_streams(
|
||||
access_token=token.access_token,
|
||||
game_id=509658,
|
||||
cache_time=30,
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rate limiting & caching
|
||||
|
||||
* **Redis-backed**
|
||||
* Shared key: `twitch`
|
||||
* Enabled automatically when `redis_url` is provided
|
||||
* Cache TTL is per-request (`X-Cache-TTL` header)
|
||||
|
||||
Implementation is inherited from **AioHTTPX transports** .
|
||||
|
||||
---
|
||||
|
||||
## Errors
|
||||
|
||||
All API methods raise typed exceptions:
|
||||
|
||||
* `ClientError(status_code, message)`
|
||||
* `InternalError(status_code, message)`
|
||||
|
||||
Defined in schema module .
|
||||
|
||||
---
|
||||
|
||||
## Scopes
|
||||
|
||||
OAuth scopes are defined as constants and typed literals:
|
||||
|
||||
```python
|
||||
from twitchclient import scopes
|
||||
|
||||
scopes.CHANNEL_READ_SUBSCRIPTIONS
|
||||
scopes.CHAT_READ
|
||||
```
|
||||
|
||||
See `scopes.py` for the full list .
|
||||
|
||||
---
|
||||
|
||||
## Typed responses
|
||||
|
||||
All successful responses return **Pydantic models**, e.g.:
|
||||
|
||||
* `ChannelsInformation`
|
||||
* `Streams`
|
||||
* `Users`
|
||||
* `EventsubSubscriptions`
|
||||
|
||||
Models live in `schema.py` .
|
||||
|
||||
---
|
||||
|
||||
## Notes & limitations
|
||||
|
||||
* Async-only (no sync client)
|
||||
* Internal API, no stability guarantees
|
||||
* Some endpoints still marked TODO (e.g. Guest Star)
|
||||
|
||||
---
|
||||
|
||||
@ -1,16 +1,11 @@
|
||||
[project]
|
||||
name = "twitchclient"
|
||||
version = "0.2.0"
|
||||
version = "1.1.0"
|
||||
description = "Client for Twitch API"
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
{ name = "Miwory", email = "miwory.uwu@gmail.com" }
|
||||
]
|
||||
authors = [{ name = "Miwory", email = "miwory.uwu@gmail.com" }]
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"aiohttpx>=1.3,<=2.0",
|
||||
"pydantic>=2.12,<=2.13",
|
||||
]
|
||||
dependencies = ["aiohttpx>=1.3,<=2.0", "pydantic>=2.12,<=2.13"]
|
||||
|
||||
[build-system]
|
||||
requires = ["uv_build>=0.9.2,<0.10.0"]
|
||||
@ -18,10 +13,10 @@ build-backend = "uv_build"
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"ruff==0.14.2",
|
||||
"pyright==1.1.406",
|
||||
"poethepoet==0.37.0",
|
||||
"pre-commit==4.3.0",
|
||||
"ruff==0.14.13",
|
||||
"pyright==1.1.408",
|
||||
"poethepoet==0.40.0",
|
||||
"pre-commit==4.5.1",
|
||||
]
|
||||
|
||||
[[tool.uv.index]]
|
||||
@ -41,6 +36,10 @@ _lint = "pre-commit run --all-files"
|
||||
lint = ["_git", "_lint"]
|
||||
check = "uv pip ls --outdated"
|
||||
|
||||
major = "uv version --bump major"
|
||||
minor = "uv version --bump minor"
|
||||
patch = "uv version --bump patch"
|
||||
|
||||
[tool.pyright]
|
||||
venvPath = "."
|
||||
venv = ".venv"
|
||||
@ -50,6 +49,7 @@ strictSetInference = true
|
||||
deprecateTypingAliases = true
|
||||
typeCheckingMode = "strict"
|
||||
pythonPlatform = "All"
|
||||
stubPath = "typings"
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py313"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
126
src/twitchclient/auth.py
Normal file
126
src/twitchclient/auth.py
Normal file
@ -0,0 +1,126 @@
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from aiohttpx import status as st
|
||||
from aiohttpx.client import AioHTTPXClient
|
||||
|
||||
from . import schema as s
|
||||
from . import scopes
|
||||
|
||||
|
||||
class TwitchAuthClient(AioHTTPXClient):
|
||||
def __init__(
|
||||
self,
|
||||
client_id: str,
|
||||
client_secret: str,
|
||||
redirect_uri: str,
|
||||
redis_url: str | None = None,
|
||||
):
|
||||
self.base_uri = 'https://id.twitch.tv/oauth2'
|
||||
self.client_id = client_id
|
||||
self.client_secret = client_secret
|
||||
self.redirect_uri = redirect_uri
|
||||
|
||||
super().__init__(
|
||||
base_url=self.base_uri,
|
||||
redis_url=redis_url,
|
||||
key='twitch' if redis_url else None,
|
||||
limit=700 if redis_url else None,
|
||||
logger='Twitch Auth',
|
||||
)
|
||||
|
||||
async def create_authorization_code_grant_flow_url(
|
||||
self,
|
||||
scope: list[scopes.Any],
|
||||
*,
|
||||
force_verify: bool = False,
|
||||
state: str | None = None,
|
||||
):
|
||||
url = 'https://id.twitch.tv/oauth2/authorize?'
|
||||
query = self.clean_dict(
|
||||
{
|
||||
'client_id': self.client_id,
|
||||
'redirect_uri': self.redirect_uri,
|
||||
'response_type': 'code',
|
||||
'scope': ' '.join(scope),
|
||||
'state': state,
|
||||
'force_verify': force_verify,
|
||||
}
|
||||
)
|
||||
|
||||
return url + urlencode(query)
|
||||
|
||||
async def app_access_token(self):
|
||||
req = await self.post(
|
||||
'/token',
|
||||
json={
|
||||
'client_id': self.client_id,
|
||||
'client_secret': self.client_secret,
|
||||
'grant_type': 'client_credentials',
|
||||
},
|
||||
)
|
||||
|
||||
match req.status_code:
|
||||
case st.OK:
|
||||
return s.AppAccessToken.model_validate(req.json())
|
||||
|
||||
case _:
|
||||
raise s.InternalError(req.status_code, 'Internal Server Error')
|
||||
|
||||
async def user_access_token(self, code: str):
|
||||
req = await self.post(
|
||||
'/token',
|
||||
json={
|
||||
'client_id': self.client_id,
|
||||
'client_secret': self.client_secret,
|
||||
'redirect_uri': self.redirect_uri,
|
||||
'grant_type': 'authorization_code',
|
||||
'code': code,
|
||||
},
|
||||
)
|
||||
|
||||
match req.status_code:
|
||||
case st.OK:
|
||||
return s.UserAccessToken.model_validate(req.json())
|
||||
|
||||
case st.BAD_REQUEST:
|
||||
return None
|
||||
|
||||
case _:
|
||||
raise s.InternalError(req.status_code, 'Internal Server Error')
|
||||
|
||||
async def validate_access_token(self, access_token: str):
|
||||
req = await self.get(
|
||||
'/validate',
|
||||
headers={'Authorization': f'OAuth {access_token}'},
|
||||
)
|
||||
|
||||
match req.status_code:
|
||||
case st.OK:
|
||||
return s.AccessTokenValidation.model_validate(req.json())
|
||||
|
||||
case st.UNAUTHORIZED:
|
||||
return None
|
||||
|
||||
case _:
|
||||
raise s.InternalError(req.status_code, 'Internal Server Error')
|
||||
|
||||
async def refresh_access_token(self, refresh_token: str):
|
||||
req = await self.post(
|
||||
'/token',
|
||||
json={
|
||||
'client_id': self.client_id,
|
||||
'client_secret': self.client_secret,
|
||||
'grant_type': 'refresh_token',
|
||||
'refresh_token': refresh_token,
|
||||
},
|
||||
)
|
||||
|
||||
match req.status_code:
|
||||
case st.OK:
|
||||
return s.UserAccessToken.model_validate(req.json())
|
||||
|
||||
case st.BAD_REQUEST:
|
||||
return None
|
||||
|
||||
case _:
|
||||
raise s.InternalError(req.status_code, 'Internal Server Error')
|
||||
0
src/twitchclient/eventsub/__init__.py
Normal file
0
src/twitchclient/eventsub/__init__.py
Normal file
51
src/twitchclient/eventsub/conditions.py
Normal file
51
src/twitchclient/eventsub/conditions.py
Normal file
@ -0,0 +1,51 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
user_id: str
|
||||
|
||||
|
||||
class Broadcaster(BaseModel):
|
||||
broadcaster_user_id: str
|
||||
|
||||
|
||||
class ToBroadcaster(BaseModel):
|
||||
to_broadcaster_user_id: str
|
||||
|
||||
|
||||
class FromBroadcaster(BaseModel):
|
||||
from_broadcaster_user_id: str
|
||||
|
||||
|
||||
class BroadcasterUser(Broadcaster, User):
|
||||
pass
|
||||
|
||||
|
||||
class BroadcasterModerator(Broadcaster):
|
||||
moderator_user_id: str
|
||||
|
||||
|
||||
class ClientID(BaseModel):
|
||||
client_id: str
|
||||
|
||||
|
||||
class Organization(BaseModel):
|
||||
organization_id: int
|
||||
category_id: int | None = None
|
||||
campaign_id: int | None = None
|
||||
|
||||
|
||||
class ExtensionClientID(BaseModel):
|
||||
extension_client_id: str
|
||||
|
||||
|
||||
Any = (
|
||||
Broadcaster
|
||||
| ToBroadcaster
|
||||
| FromBroadcaster
|
||||
| BroadcasterUser
|
||||
| BroadcasterModerator
|
||||
| ClientID
|
||||
| Organization
|
||||
| ExtensionClientID
|
||||
)
|
||||
43
src/twitchclient/eventsub/statuses.py
Normal file
43
src/twitchclient/eventsub/statuses.py
Normal file
@ -0,0 +1,43 @@
|
||||
from typing import Literal
|
||||
|
||||
ENABLED = Literal['enabled']
|
||||
PENDING = Literal['webhook_callback_verification_pending']
|
||||
FAILED = Literal['webhook_callback_verification_failed']
|
||||
EXCEEDED = Literal['notification_failures_exceeded']
|
||||
REVOKED = Literal['authorization_revoked']
|
||||
MODERATOR_REMOVED = Literal['moderator_removed']
|
||||
USER_REMOVED = Literal['user_removed']
|
||||
CHAT_USER_BANNED = Literal['chat_user_banned']
|
||||
VERSION_REMOVED = Literal['version_removed']
|
||||
BETA_MAINTENANCE = Literal['beta_maintenance']
|
||||
WEBSOCKET_DISCONNECTED = Literal['websocket_disconnected']
|
||||
WEBSOCKET_FAILED_PING_PONG = Literal['websocket_failed_ping_pong']
|
||||
WEBSOCKET_RECEIVED_INBOUND_TRAFFIC = Literal[
|
||||
'websocket_received_inbound_traffic'
|
||||
]
|
||||
WEBSOCKET_CONNECTION_UNUSED = Literal['websocket_connection_unused']
|
||||
WEBSOCKET_INTERNAL_ERROR = Literal['websocket_internal_error']
|
||||
WEBSOCKET_NETWORK_TIMEOUT = Literal['websocket_network_timeout']
|
||||
WEBSOCKET_NETWORK_ERROR = Literal['websocket_network_error']
|
||||
WEBSOCKET_FAILED_TO_RECONNECT = Literal['websocket_failed_to_reconnect']
|
||||
|
||||
Any = (
|
||||
ENABLED
|
||||
| PENDING
|
||||
| FAILED
|
||||
| EXCEEDED
|
||||
| REVOKED
|
||||
| MODERATOR_REMOVED
|
||||
| USER_REMOVED
|
||||
| CHAT_USER_BANNED
|
||||
| VERSION_REMOVED
|
||||
| BETA_MAINTENANCE
|
||||
| WEBSOCKET_DISCONNECTED
|
||||
| WEBSOCKET_FAILED_PING_PONG
|
||||
| WEBSOCKET_RECEIVED_INBOUND_TRAFFIC
|
||||
| WEBSOCKET_CONNECTION_UNUSED
|
||||
| WEBSOCKET_INTERNAL_ERROR
|
||||
| WEBSOCKET_NETWORK_TIMEOUT
|
||||
| WEBSOCKET_NETWORK_ERROR
|
||||
| WEBSOCKET_FAILED_TO_RECONNECT
|
||||
)
|
||||
564
src/twitchclient/eventsub/subscriptions.py
Normal file
564
src/twitchclient/eventsub/subscriptions.py
Normal file
@ -0,0 +1,564 @@
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from . import conditions as c
|
||||
from . import statuses as s
|
||||
from . import transports as t
|
||||
from . import types as st
|
||||
|
||||
|
||||
class BaseSubscription(BaseModel):
|
||||
id: str
|
||||
version: int
|
||||
status: s.Any
|
||||
cost: int
|
||||
created_at: datetime
|
||||
transport: t.Any
|
||||
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class AutomodMessageHold(BaseSubscription):
|
||||
type: st.AUTOMOD_MESSAGE_HOLD
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class AutomodMessageUpdate(BaseSubscription):
|
||||
type: st.AUTOMOD_MESSAGE_UPDATE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class AutomodSettingsUpdate(BaseSubscription):
|
||||
type: st.AUTOMOD_SETTINGS_UPDATE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class AutomodTermsUpdate(BaseSubscription):
|
||||
type: st.AUTOMOD_TERMS_UPDATE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelBitsUse(BaseSubscription):
|
||||
type: st.CHANNEL_BITS_USE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelUpdate(BaseSubscription):
|
||||
type: st.CHANNEL_UPDATE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class ChannelFollow(BaseSubscription):
|
||||
type: st.CHANNEL_FOLLOW
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class ChannelAdBreakBegin(BaseSubscription):
|
||||
type: st.CHANNEL_AD_BREAK_BEGIN
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelChatClear(BaseSubscription):
|
||||
type: st.CHANNEL_CHAT_CLEAR
|
||||
condition: c.BroadcasterUser
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelChatClearUserMessages(BaseSubscription):
|
||||
type: st.CHANNEL_CHAT_CLEAR_USER_MESSAGES
|
||||
condition: c.BroadcasterUser
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelChatMessage(BaseSubscription):
|
||||
type: st.CHANNEL_CHAT_MESSAGE
|
||||
condition: c.BroadcasterUser
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelChatMessageDelete(BaseSubscription):
|
||||
type: st.CHANNEL_CHAT_MESSAGE_DELETE
|
||||
condition: c.BroadcasterUser
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelChatNotification(BaseSubscription):
|
||||
type: st.CHANNEL_CHAT_NOTIFICATION
|
||||
condition: c.BroadcasterUser
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelChatSettingsUpdate(BaseSubscription):
|
||||
type: st.CHANNEL_CHAT_SETTINGS_UPDATE
|
||||
condition: c.BroadcasterUser
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelChatUserMessageHold(BaseSubscription):
|
||||
type: st.CHANNEL_CHAT_USER_MESSAGE_HOLD
|
||||
condition: c.BroadcasterUser
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelChatUserMessageUpdate(BaseSubscription):
|
||||
type: st.CHANNEL_CHAT_USER_MESSAGE_UPDATE
|
||||
condition: c.BroadcasterUser
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSharedChatSessionBegin(BaseSubscription):
|
||||
type: st.CHANNEL_SHARED_CHAT_SESSION_BEGIN
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSharedChatSessionUpdate(BaseSubscription):
|
||||
type: st.CHANNEL_SHARED_CHAT_SESSION_UPDATE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSharedChatSessionEnd(BaseSubscription):
|
||||
type: st.CHANNEL_SHARED_CHAT_SESSION_END
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSubscribe(BaseSubscription):
|
||||
type: st.CHANNEL_SUBSCRIBE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSubscriptionEnd(BaseSubscription):
|
||||
type: st.CHANNEL_SUBSCRIPTION_END
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSubscriptionGift(BaseSubscription):
|
||||
type: st.CHANNEL_SUBSCRIPTION_GIFT
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSubscriptionMessage(BaseSubscription):
|
||||
type: st.CHANNEL_SUBSCRIPTION_MESSAGE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelCheer(BaseSubscription):
|
||||
type: st.CHANNEL_CHEER
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelRaid(BaseSubscription):
|
||||
type: st.CHANNEL_RAID
|
||||
condition: c.ToBroadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelBan(BaseSubscription):
|
||||
type: st.CHANNEL_BAN
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelUnban(BaseSubscription):
|
||||
type: st.CHANNEL_UNBAN
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelUnbanRequestCreate(BaseSubscription):
|
||||
type: st.CHANNEL_UNBAN_REQUEST_CREATE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelUnbanRequestResolve(BaseSubscription):
|
||||
type: st.CHANNEL_UNBAN_REQUEST_RESOLVE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelModerate(BaseSubscription):
|
||||
type: st.CHANNEL_MODERATE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class ChannelModeratorAdd(BaseSubscription):
|
||||
type: st.CHANNEL_MODERATOR_ADD
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelModeratorRemove(BaseSubscription):
|
||||
type: st.CHANNEL_MODERATOR_REMOVE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
# TODO: Complete when subscription version is released
|
||||
# class ChannelGuestStarSessionBegin(BaseSubscription):
|
||||
# type: st.CHANNEL_GUEST_STAR_SESSION_BEGIN
|
||||
# condition: c.Broadcaster
|
||||
# default_version: int = 1
|
||||
|
||||
# TODO: Complete when subscription version is released
|
||||
# class ChannelGuestStarSessionEnd(BaseSubscription):
|
||||
# type: st.CHANNEL_GUEST_STAR_SESSION_END
|
||||
# condition: c.Broadcaster
|
||||
# default_version: int = 1
|
||||
|
||||
# TODO: Complete when subscription version is released
|
||||
# class ChannelGuestStarGuestUpdate(BaseSubscription):
|
||||
# type: st.CHANNEL_GUEST_STAR_GUEST_UPDATE
|
||||
# condition: c.Broadcaster
|
||||
# default_version: int = 1
|
||||
|
||||
# TODO: Complete when subscription version is released
|
||||
# class ChannelGuestStarSettingsUpdate(BaseSubscription):
|
||||
# type: st.CHANNEL_GUEST_STAR_SETTINGS_UPDATE
|
||||
# condition: c.Broadcaster
|
||||
# default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPointsAutomaticRewardRedemptionAdd(BaseSubscription):
|
||||
type: st.CHANNEL_POINTS_AUTOMATIC_REWARD_REDEMPTION_ADD
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class ChannelPointsCustomRewardAdd(BaseSubscription):
|
||||
type: st.CHANNEL_POINTS_CUSTOM_REWARD_ADD
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPointsCustomRewardUpdate(BaseSubscription):
|
||||
type: st.CHANNEL_POINTS_CUSTOM_REWARD_UPDATE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPointsCustomRewardRemove(BaseSubscription):
|
||||
type: st.CHANNEL_POINTS_CUSTOM_REWARD_REMOVE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPointsCustomRewardRedemptionAdd(BaseSubscription):
|
||||
type: st.CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_ADD
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPointsCustomRewardRedemptionUpdate(BaseSubscription):
|
||||
type: st.CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_UPDATE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPollBegin(BaseSubscription):
|
||||
type: st.CHANNEL_POLL_BEGIN
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPollProgress(BaseSubscription):
|
||||
type: st.CHANNEL_POLL_PROGRESS
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPollEnd(BaseSubscription):
|
||||
type: st.CHANNEL_POLL_END
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPredictionBegin(BaseSubscription):
|
||||
type: st.CHANNEL_PREDICTION_BEGIN
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPredictionProgress(BaseSubscription):
|
||||
type: st.CHANNEL_PREDICTION_PROGRESS
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPredictionLock(BaseSubscription):
|
||||
type: st.CHANNEL_PREDICTION_LOCK
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelPredictionEnd(BaseSubscription):
|
||||
type: st.CHANNEL_PREDICTION_END
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSuspiciousUserMessage(BaseSubscription):
|
||||
type: st.CHANNEL_SUSPICIOUS_USER_MESSAGE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelSuspiciousUserUpdate(BaseSubscription):
|
||||
type: st.CHANNEL_SUSPICIOUS_USER_UPDATE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelVIPAdd(BaseSubscription):
|
||||
type: st.CHANNEL_VIP_ADD
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelVIPRemove(BaseSubscription):
|
||||
type: st.CHANNEL_VIP_REMOVE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelWarningAcknowledgement(BaseSubscription):
|
||||
type: st.CHANNEL_WARNING_ACKNOWLEDGEMENT
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ChannelWarningSend(BaseSubscription):
|
||||
type: st.CHANNEL_WARNING_SEND
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class CharityDonation(BaseSubscription):
|
||||
type: st.CHARITY_DONATION
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class CharityCampaignStart(BaseSubscription):
|
||||
type: st.CHARITY_CAMPAIGN_START
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class CharityCampaignProgress(BaseSubscription):
|
||||
type: st.CHARITY_CAMPAIGN_PROGRESS
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class CharityCampaignStop(BaseSubscription):
|
||||
type: st.CHARITY_CAMPAIGN_STOP
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ConduitShardDisabled(BaseSubscription):
|
||||
type: st.CONDUIT_SHARD_DISABLED
|
||||
condition: c.ClientID
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class DropEntitlementGrant(BaseSubscription):
|
||||
type: st.DROP_ENTITLEMENT_GRANT
|
||||
condition: c.Organization
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ExtensionBitsTransactionCreate(BaseSubscription):
|
||||
type: st.EXTENSION_BITS_TRANSACTION_CREATE
|
||||
condition: c.ExtensionClientID
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class GoalBegin(BaseSubscription):
|
||||
type: st.GOAL_BEGIN
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class GoalProgress(BaseSubscription):
|
||||
type: st.GOAL_PROGRESS
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class GoalEnd(BaseSubscription):
|
||||
type: st.GOAL_END
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class HypeTrainBegin(BaseSubscription):
|
||||
type: st.HYPE_TRAIN_BEGIN
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class HypeTrainProgress(BaseSubscription):
|
||||
type: st.HYPE_TRAIN_PROGRESS
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class HypeTrainEnd(BaseSubscription):
|
||||
type: st.HYPE_TRAIN_END
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 2
|
||||
|
||||
|
||||
class ShieldModeBegin(BaseSubscription):
|
||||
type: st.SHIELD_MODE_BEGIN
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ShieldModeEnd(BaseSubscription):
|
||||
type: st.SHIELD_MODE_END
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ShoutoutCreate(BaseSubscription):
|
||||
type: st.SHOUTOUT_CREATE
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class ShoutoutReceived(BaseSubscription):
|
||||
type: st.SHOUTOUT_RECEIVED
|
||||
condition: c.BroadcasterModerator
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class StreamOnline(BaseSubscription):
|
||||
type: st.STREAM_ONLINE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class StreamOffline(BaseSubscription):
|
||||
type: st.STREAM_OFFLINE
|
||||
condition: c.Broadcaster
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class UserAuthorizationGrant(BaseSubscription):
|
||||
type: st.USER_AUTHORIZATION_GRANT
|
||||
condition: c.ClientID
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class UserAuthorizationRevoke(BaseSubscription):
|
||||
type: st.USER_AUTHORIZATION_REVOKE
|
||||
condition: c.ClientID
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class UserUpdate(BaseSubscription):
|
||||
type: st.USER_UPDATE
|
||||
condition: c.User
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
class WhisperReceived(BaseSubscription):
|
||||
type: st.WHISPER_RECEIVED
|
||||
condition: c.User
|
||||
default_version: int = 1
|
||||
|
||||
|
||||
Any = (
|
||||
AutomodMessageHold
|
||||
| AutomodMessageUpdate
|
||||
| AutomodSettingsUpdate
|
||||
| AutomodTermsUpdate
|
||||
| ChannelBitsUse
|
||||
| ChannelUpdate
|
||||
| ChannelFollow
|
||||
| ChannelAdBreakBegin
|
||||
| ChannelChatClear
|
||||
| ChannelChatClearUserMessages
|
||||
| ChannelChatMessage
|
||||
| ChannelChatMessageDelete
|
||||
| ChannelChatNotification
|
||||
| ChannelChatSettingsUpdate
|
||||
| ChannelChatUserMessageHold
|
||||
| ChannelChatUserMessageUpdate
|
||||
| ChannelSharedChatSessionBegin
|
||||
| ChannelSharedChatSessionUpdate
|
||||
| ChannelSharedChatSessionEnd
|
||||
| ChannelSubscribe
|
||||
| ChannelSubscriptionEnd
|
||||
| ChannelSubscriptionGift
|
||||
| ChannelSubscriptionMessage
|
||||
| ChannelCheer
|
||||
| ChannelRaid
|
||||
| ChannelBan
|
||||
| ChannelUnban
|
||||
| ChannelUnbanRequestCreate
|
||||
| ChannelUnbanRequestResolve
|
||||
| ChannelModerate
|
||||
| ChannelModeratorAdd
|
||||
| ChannelModeratorRemove
|
||||
| ChannelPointsAutomaticRewardRedemptionAdd
|
||||
| ChannelPointsCustomRewardAdd
|
||||
| ChannelPointsCustomRewardUpdate
|
||||
| ChannelPointsCustomRewardRemove
|
||||
| ChannelPointsCustomRewardRedemptionAdd
|
||||
| ChannelPointsCustomRewardRedemptionUpdate
|
||||
| ChannelPollBegin
|
||||
| ChannelPollProgress
|
||||
| ChannelPollEnd
|
||||
| ChannelPredictionBegin
|
||||
| ChannelPredictionProgress
|
||||
| ChannelPredictionLock
|
||||
| ChannelPredictionEnd
|
||||
| ChannelSuspiciousUserMessage
|
||||
| ChannelSuspiciousUserUpdate
|
||||
| ChannelVIPAdd
|
||||
| ChannelVIPRemove
|
||||
| ChannelWarningAcknowledgement
|
||||
| ChannelWarningSend
|
||||
| CharityDonation
|
||||
| CharityCampaignStart
|
||||
| CharityCampaignProgress
|
||||
| CharityCampaignStop
|
||||
| ConduitShardDisabled
|
||||
| DropEntitlementGrant
|
||||
| ExtensionBitsTransactionCreate
|
||||
| GoalBegin
|
||||
| GoalProgress
|
||||
| GoalEnd
|
||||
| HypeTrainBegin
|
||||
| HypeTrainProgress
|
||||
| HypeTrainEnd
|
||||
| ShoutoutCreate
|
||||
| ShoutoutReceived
|
||||
| StreamOnline
|
||||
| StreamOffline
|
||||
| UserAuthorizationGrant
|
||||
| UserAuthorizationRevoke
|
||||
| UserUpdate
|
||||
| WhisperReceived
|
||||
)
|
||||
22
src/twitchclient/eventsub/transports.py
Normal file
22
src/twitchclient/eventsub/transports.py
Normal file
@ -0,0 +1,22 @@
|
||||
from datetime import datetime
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class BaseWebhookTransport(BaseModel):
|
||||
method: Literal['webhook']
|
||||
callback: str
|
||||
|
||||
|
||||
class BaseWebsocketTransport(BaseModel):
|
||||
method: Literal['websocket']
|
||||
session_id: str
|
||||
connected_at: datetime
|
||||
|
||||
|
||||
class SubscribeWebhookTransport(BaseWebhookTransport):
|
||||
secret: str
|
||||
|
||||
|
||||
Any = BaseWebhookTransport | BaseWebsocketTransport
|
||||
201
src/twitchclient/eventsub/types.py
Normal file
201
src/twitchclient/eventsub/types.py
Normal file
@ -0,0 +1,201 @@
|
||||
from typing import Literal
|
||||
|
||||
# Automod types
|
||||
AUTOMOD_MESSAGE_HOLD = Literal['automod.message.hold']
|
||||
AUTOMOD_MESSAGE_UPDATE = Literal['automod.message.update']
|
||||
AUTOMOD_SETTINGS_UPDATE = Literal['automod.settings.update']
|
||||
AUTOMOD_TERMS_UPDATE = Literal['automod.terms.update']
|
||||
|
||||
# Channel types
|
||||
CHANNEL_BITS_USE = Literal['channel.bits.use']
|
||||
CHANNEL_UPDATE = Literal['channel.update']
|
||||
CHANNEL_FOLLOW = Literal['channel.follow']
|
||||
CHANNEL_AD_BREAK_BEGIN = Literal['channel.ad_break.begin']
|
||||
CHANNEL_CHAT_CLEAR = Literal['channel.chat.clear']
|
||||
CHANNEL_CHAT_CLEAR_USER_MESSAGES = Literal['channel.chat.clear_user_messages']
|
||||
CHANNEL_CHAT_MESSAGE = Literal['channel.chat.message']
|
||||
CHANNEL_CHAT_MESSAGE_DELETE = Literal['channel.chat.message_delete']
|
||||
CHANNEL_CHAT_NOTIFICATION = Literal['channel.chat.notification']
|
||||
CHANNEL_CHAT_SETTINGS_UPDATE = Literal['channel.chat_settings.update']
|
||||
CHANNEL_CHAT_USER_MESSAGE_HOLD = Literal['channel.chat.user_message_hold']
|
||||
CHANNEL_CHAT_USER_MESSAGE_UPDATE = Literal['channel.chat.user_message_update']
|
||||
CHANNEL_SHARED_CHAT_SESSION_BEGIN = Literal['channel.shared_chat.begin']
|
||||
CHANNEL_SHARED_CHAT_SESSION_UPDATE = Literal['channel.shared_chat.update']
|
||||
CHANNEL_SHARED_CHAT_SESSION_END = Literal['channel.shared_chat.end']
|
||||
CHANNEL_SUBSCRIBE = Literal['channel.subscribe']
|
||||
CHANNEL_SUBSCRIPTION_END = Literal['channel.subscription.end']
|
||||
CHANNEL_SUBSCRIPTION_GIFT = Literal['channel.subscription.gift']
|
||||
CHANNEL_SUBSCRIPTION_MESSAGE = Literal['channel.subscription.message']
|
||||
CHANNEL_CHEER = Literal['channel.cheer']
|
||||
CHANNEL_RAID = Literal['channel.raid']
|
||||
CHANNEL_BAN = Literal['channel.ban']
|
||||
CHANNEL_UNBAN = Literal['channel.unban']
|
||||
CHANNEL_UNBAN_REQUEST_CREATE = Literal['channel.unban_request.create']
|
||||
CHANNEL_UNBAN_REQUEST_RESOLVE = Literal['channel.unban_request.resolve']
|
||||
CHANNEL_MODERATE = Literal['channel.moderate']
|
||||
CHANNEL_MODERATOR_ADD = Literal['channel.moderator.add']
|
||||
CHANNEL_MODERATOR_REMOVE = Literal['channel.moderator.remove']
|
||||
CHANNEL_GUEST_STAR_SESSION_BEGIN = Literal['channel.guest_star_session.begin']
|
||||
CHANNEL_GUEST_STAR_SESSION_END = Literal['channel.guest_star_session.end']
|
||||
CHANNEL_GUEST_STAR_GUEST_UPDATE = Literal['channel.guest_star_guest.update']
|
||||
CHANNEL_GUEST_STAR_SETTINGS_UPDATE = Literal[
|
||||
'channel.guest_star_settings.update'
|
||||
]
|
||||
CHANNEL_POINTS_AUTOMATIC_REWARD_REDEMPTION_ADD = Literal[
|
||||
'channel.channel_points_automatic_reward_redemption.add'
|
||||
]
|
||||
CHANNEL_POINTS_CUSTOM_REWARD_ADD = Literal[
|
||||
'channel.channel_points_custom_reward.add'
|
||||
]
|
||||
CHANNEL_POINTS_CUSTOM_REWARD_UPDATE = Literal[
|
||||
'channel.channel_points_custom_reward.update'
|
||||
]
|
||||
CHANNEL_POINTS_CUSTOM_REWARD_REMOVE = Literal[
|
||||
'channel.channel_points_custom_reward.remove'
|
||||
]
|
||||
CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_ADD = Literal[
|
||||
'channel.channel_points_custom_reward_redemption.add'
|
||||
]
|
||||
CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_UPDATE = Literal[
|
||||
'channel.channel_points_custom_reward_redemption.update'
|
||||
]
|
||||
CHANNEL_POLL_BEGIN = Literal['channel.poll.begin']
|
||||
CHANNEL_POLL_PROGRESS = Literal['channel.poll.progress']
|
||||
CHANNEL_POLL_END = Literal['channel.poll.end']
|
||||
CHANNEL_PREDICTION_BEGIN = Literal['channel.prediction.begin']
|
||||
CHANNEL_PREDICTION_PROGRESS = Literal['channel.prediction.progress']
|
||||
CHANNEL_PREDICTION_LOCK = Literal['channel.prediction.lock']
|
||||
CHANNEL_PREDICTION_END = Literal['channel.prediction.end']
|
||||
CHANNEL_SUSPICIOUS_USER_MESSAGE = Literal['channel.suspicious_user.message']
|
||||
CHANNEL_SUSPICIOUS_USER_UPDATE = Literal['channel.suspicious_user.update']
|
||||
CHANNEL_VIP_ADD = Literal['channel.vip.add']
|
||||
CHANNEL_VIP_REMOVE = Literal['channel.vip.remove']
|
||||
CHANNEL_WARNING_ACKNOWLEDGEMENT = Literal['channel.warning.acknowledge']
|
||||
CHANNEL_WARNING_SEND = Literal['channel.warning.send']
|
||||
|
||||
# Charity types
|
||||
CHARITY_DONATION = Literal['channel.charity_campaign.donate']
|
||||
CHARITY_CAMPAIGN_START = Literal['channel.charity_campaign.start']
|
||||
CHARITY_CAMPAIGN_PROGRESS = Literal['channel.charity_campaign.progress']
|
||||
CHARITY_CAMPAIGN_STOP = Literal['channel.charity_campaign.stop']
|
||||
|
||||
# Conduit types
|
||||
CONDUIT_SHARD_DISABLED = Literal['conduit.shard.disabled']
|
||||
|
||||
# Drop types
|
||||
DROP_ENTITLEMENT_GRANT = Literal['drop.entitlement.grant']
|
||||
|
||||
# Extension types
|
||||
EXTENSION_BITS_TRANSACTION_CREATE = Literal[
|
||||
'extension.bits_transaction.create'
|
||||
]
|
||||
|
||||
# Goal types
|
||||
GOAL_BEGIN = Literal['channel.goal.begin']
|
||||
GOAL_PROGRESS = Literal['channel.goal.progress']
|
||||
GOAL_END = Literal['channel.goal.end']
|
||||
|
||||
# Hype Train types
|
||||
HYPE_TRAIN_BEGIN = Literal['channel.hype_train.begin']
|
||||
HYPE_TRAIN_PROGRESS = Literal['channel.hype_train.progress']
|
||||
HYPE_TRAIN_END = Literal['channel.hype_train.end']
|
||||
|
||||
# Shield Mode types
|
||||
SHIELD_MODE_BEGIN = Literal['channel.shield_mode.begin']
|
||||
SHIELD_MODE_END = Literal['channel.shield_mode.end']
|
||||
|
||||
# Shoutout types
|
||||
SHOUTOUT_CREATE = Literal['channel.shoutout.create']
|
||||
SHOUTOUT_RECEIVED = Literal['channel.shoutout.receive']
|
||||
|
||||
# Stream types
|
||||
STREAM_ONLINE = Literal['stream.online']
|
||||
STREAM_OFFLINE = Literal['stream.offline']
|
||||
|
||||
# User types
|
||||
USER_AUTHORIZATION_GRANT = Literal['user.authorization.grant']
|
||||
USER_AUTHORIZATION_REVOKE = Literal['user.authorization.revoke']
|
||||
USER_UPDATE = Literal['user.update']
|
||||
WHISPER_RECEIVED = Literal['user.whisper.message']
|
||||
|
||||
# Union type for all events
|
||||
Any = (
|
||||
AUTOMOD_MESSAGE_HOLD
|
||||
| AUTOMOD_MESSAGE_UPDATE
|
||||
| AUTOMOD_SETTINGS_UPDATE
|
||||
| AUTOMOD_TERMS_UPDATE
|
||||
| CHANNEL_BITS_USE
|
||||
| CHANNEL_UPDATE
|
||||
| CHANNEL_FOLLOW
|
||||
| CHANNEL_AD_BREAK_BEGIN
|
||||
| CHANNEL_CHAT_CLEAR
|
||||
| CHANNEL_CHAT_CLEAR_USER_MESSAGES
|
||||
| CHANNEL_CHAT_MESSAGE
|
||||
| CHANNEL_CHAT_MESSAGE_DELETE
|
||||
| CHANNEL_CHAT_NOTIFICATION
|
||||
| CHANNEL_CHAT_SETTINGS_UPDATE
|
||||
| CHANNEL_CHAT_USER_MESSAGE_HOLD
|
||||
| CHANNEL_CHAT_USER_MESSAGE_UPDATE
|
||||
| CHANNEL_SHARED_CHAT_SESSION_BEGIN
|
||||
| CHANNEL_SHARED_CHAT_SESSION_UPDATE
|
||||
| CHANNEL_SHARED_CHAT_SESSION_END
|
||||
| CHANNEL_SUBSCRIBE
|
||||
| CHANNEL_SUBSCRIPTION_END
|
||||
| CHANNEL_SUBSCRIPTION_GIFT
|
||||
| CHANNEL_SUBSCRIPTION_MESSAGE
|
||||
| CHANNEL_CHEER
|
||||
| CHANNEL_RAID
|
||||
| CHANNEL_BAN
|
||||
| CHANNEL_UNBAN
|
||||
| CHANNEL_UNBAN_REQUEST_CREATE
|
||||
| CHANNEL_UNBAN_REQUEST_RESOLVE
|
||||
| CHANNEL_MODERATE
|
||||
| CHANNEL_MODERATOR_ADD
|
||||
| CHANNEL_MODERATOR_REMOVE
|
||||
| CHANNEL_GUEST_STAR_SESSION_BEGIN
|
||||
| CHANNEL_GUEST_STAR_SESSION_END
|
||||
| CHANNEL_GUEST_STAR_GUEST_UPDATE
|
||||
| CHANNEL_GUEST_STAR_SETTINGS_UPDATE
|
||||
| CHANNEL_POINTS_AUTOMATIC_REWARD_REDEMPTION_ADD
|
||||
| CHANNEL_POINTS_CUSTOM_REWARD_ADD
|
||||
| CHANNEL_POINTS_CUSTOM_REWARD_UPDATE
|
||||
| CHANNEL_POINTS_CUSTOM_REWARD_REMOVE
|
||||
| CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_ADD
|
||||
| CHANNEL_POINTS_CUSTOM_REWARD_REDEMPTION_UPDATE
|
||||
| CHANNEL_POLL_BEGIN
|
||||
| CHANNEL_POLL_PROGRESS
|
||||
| CHANNEL_POLL_END
|
||||
| CHANNEL_PREDICTION_BEGIN
|
||||
| CHANNEL_PREDICTION_PROGRESS
|
||||
| CHANNEL_PREDICTION_LOCK
|
||||
| CHANNEL_PREDICTION_END
|
||||
| CHANNEL_SUSPICIOUS_USER_MESSAGE
|
||||
| CHANNEL_SUSPICIOUS_USER_UPDATE
|
||||
| CHANNEL_VIP_ADD
|
||||
| CHANNEL_VIP_REMOVE
|
||||
| CHANNEL_WARNING_ACKNOWLEDGEMENT
|
||||
| CHANNEL_WARNING_SEND
|
||||
| CHARITY_DONATION
|
||||
| CHARITY_CAMPAIGN_START
|
||||
| CHARITY_CAMPAIGN_PROGRESS
|
||||
| CHARITY_CAMPAIGN_STOP
|
||||
| CONDUIT_SHARD_DISABLED
|
||||
| DROP_ENTITLEMENT_GRANT
|
||||
| EXTENSION_BITS_TRANSACTION_CREATE
|
||||
| GOAL_BEGIN
|
||||
| GOAL_PROGRESS
|
||||
| GOAL_END
|
||||
| HYPE_TRAIN_BEGIN
|
||||
| HYPE_TRAIN_PROGRESS
|
||||
| HYPE_TRAIN_END
|
||||
| SHIELD_MODE_BEGIN
|
||||
| SHIELD_MODE_END
|
||||
| SHOUTOUT_CREATE
|
||||
| SHOUTOUT_RECEIVED
|
||||
| STREAM_ONLINE
|
||||
| STREAM_OFFLINE
|
||||
| USER_AUTHORIZATION_GRANT
|
||||
| USER_AUTHORIZATION_REVOKE
|
||||
| USER_UPDATE
|
||||
| WHISPER_RECEIVED
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
166
src/twitchclient/scopes.py
Normal file
166
src/twitchclient/scopes.py
Normal file
@ -0,0 +1,166 @@
|
||||
# Analytics
|
||||
from typing import Literal
|
||||
|
||||
ANALYTICS_READ_EXTENSIONS = 'analytics:read:extensions'
|
||||
ANALYTICS_READ_GAMES = 'analytics:read:games'
|
||||
|
||||
# Bits
|
||||
BITS_READ = 'bits:read'
|
||||
|
||||
# Channel
|
||||
CHANNEL_MANAGE_ADS = 'channel:manage:ads'
|
||||
CHANNEL_READ_ADS = 'channel:read:ads'
|
||||
CHANNEL_MANAGE_BROADCAST = 'channel:manage:broadcast'
|
||||
CHANNEL_READ_CHARITY = 'channel:read:charity'
|
||||
CHANNEL_EDIT_COMMERCIAL = 'channel:edit:commercial'
|
||||
CHANNEL_READ_EDITORS = 'channel:read:editors'
|
||||
CHANNEL_MANAGE_EXTENSIONS = 'channel:manage:extensions'
|
||||
CHANNEL_READ_GOALS = 'channel:read:goals'
|
||||
CHANNEL_READ_GUEST_STAR = 'channel:read:guest_star'
|
||||
CHANNEL_MANAGE_GUEST_STAR = 'channel:manage:guest_star'
|
||||
CHANNEL_READ_HYPE_TRAIN = 'channel:read:hype_train'
|
||||
CHANNEL_MANAGE_MODERATORS = 'channel:manage:moderators'
|
||||
CHANNEL_READ_POLLS = 'channel:read:polls'
|
||||
CHANNEL_MANAGE_POLLS = 'channel:manage:polls'
|
||||
CHANNEL_READ_PREDICTIONS = 'channel:read:predictions'
|
||||
CHANNEL_MANAGE_PREDICTIONS = 'channel:manage:predictions'
|
||||
CHANNEL_MANAGE_RAIDS = 'channel:manage:raids'
|
||||
CHANNEL_READ_REDEMPTIONS = 'channel:read:redemptions'
|
||||
CHANNEL_MANAGE_REDEMPTIONS = 'channel:manage:redemptions'
|
||||
CHANNEL_MANAGE_SCHEDULE = 'channel:manage:schedule'
|
||||
CHANNEL_READ_STREAM_KEY = 'channel:read:stream_key'
|
||||
CHANNEL_READ_SUBSCRIPTIONS = 'channel:read:subscriptions'
|
||||
CHANNEL_MANAGE_VIDEOS = 'channel:manage:videos'
|
||||
CHANNEL_READ_VIPS = 'channel:read:vips'
|
||||
CHANNEL_MANAGE_VIPS = 'channel:manage:vips'
|
||||
CHANNEL_BOT = 'channel:bot'
|
||||
CHANNEL_MODERATE = 'channel:moderate'
|
||||
|
||||
# clips
|
||||
CLIPS_EDIT = 'clips:edit'
|
||||
|
||||
# Moderation
|
||||
MODERATION_READ = 'moderation:read'
|
||||
MODERATOR_MANAGE_ANNOUNCEMENTS = 'moderator:manage:announcements'
|
||||
MODERATOR_MANAGE_AUTOMOD = 'moderator:manage:automod'
|
||||
MODERATOR_READ_AUTOMOD_SETTINGS = 'moderator:read:automod_settings'
|
||||
MODERATOR_MANAGE_AUTOMOD_SETTINGS = 'moderator:manage:automod_settings'
|
||||
MODERATOR_MANAGE_BANNED_USERS = 'moderator:manage:banned_users'
|
||||
MODERATOR_READ_BLOCKED_TERMS = 'moderator:read:blocked_terms'
|
||||
MODERATOR_MANAGE_BLOCKED_TERMS = 'moderator:manage:blocked_terms'
|
||||
MODERATOR_MANAGE_CHAT_MESSAGES = 'moderator:manage:chat_messages'
|
||||
MODERATOR_READ_CHAT_SETTINGS = 'moderator:read:chat_settings'
|
||||
MODERATOR_MANAGE_CHAT_SETTINGS = 'moderator:manage:chat_settings'
|
||||
MODERATOR_READ_CHATTERS = 'moderator:read:chatters'
|
||||
MODERATOR_READ_FOLLOWERS = 'moderator:read:followers'
|
||||
MODERATOR_READ_GUEST_STAR = 'moderator:read:guest_star'
|
||||
MODERATOR_MANAGE_GUEST_STAR = 'moderator:manage:guest_star'
|
||||
MODERATOR_READ_SHIELD_MODE = 'moderator:read:shield_mode'
|
||||
MODERATOR_MANAGE_SHIELD_MODE = 'moderator:manage:shield_mode'
|
||||
MODERATOR_READ_SHOUTOUTS = 'moderator:read:shoutouts'
|
||||
MODERATOR_MANAGE_SHOUTOUTS = 'moderator:manage:shoutouts'
|
||||
MODERATOR_READ_UNBAN_REQUESTS = 'moderator:read:unban_requests'
|
||||
MODERATOR_MANAGE_UNBAN_REQUESTS = 'moderator:manage:unban_requests'
|
||||
MODERATOR_READ_WARNINGS = 'moderator:read:warnings'
|
||||
MODERATOR_MANAGE_WARNINGS = 'moderator:manage:warnings'
|
||||
|
||||
# User
|
||||
USER_EDIT = 'user:edit'
|
||||
USER_EDIT_FOLLOWS = 'user:edit:follows'
|
||||
USER_READ_BLOCKED_USERS = 'user:read:blocked_users'
|
||||
USER_MANAGE_BLOCKED_USERS = 'user:manage:blocked_users'
|
||||
USER_READ_BROADCAST = 'user:read:broadcast'
|
||||
USER_MANAGE_CHAT_COLOR = 'user:manage:chat_color'
|
||||
USER_READ_EMAIL = 'user:read:email'
|
||||
USER_READ_EMOTES = 'user:read:emotes'
|
||||
USER_READ_FOLLOWS = 'user:read:follows'
|
||||
USER_READ_MODERATED_CHANNELS = 'user:read:moderated_channels'
|
||||
USER_READ_SUBSCRIPTIONS = 'user:read:subscriptions'
|
||||
USER_MANAGE_WHISPERS = 'user:manage:whispers'
|
||||
USER_BOT = 'user:bot'
|
||||
USER_READ_CHAT = 'user:read:chat'
|
||||
USER_WRITE_CHAT = 'user:write:chat'
|
||||
|
||||
# Chat
|
||||
CHAT_EDIT = 'chat:edit'
|
||||
CHAT_READ = 'chat:read'
|
||||
|
||||
# Whispers
|
||||
WHISPERS_READ = 'whispers:read'
|
||||
WHISPERS_EDIT = 'whispers:edit'
|
||||
|
||||
type Any = Literal[
|
||||
'analytics:read:extensions',
|
||||
'analytics:read:games',
|
||||
'bits:read',
|
||||
'channel:manage:ads',
|
||||
'channel:read:ads',
|
||||
'channel:manage:broadcast',
|
||||
'channel:read:charity',
|
||||
'channel:edit:commercial',
|
||||
'channel:read:editors',
|
||||
'channel:manage:extensions',
|
||||
'channel:read:goals',
|
||||
'channel:read:guest_star',
|
||||
'channel:manage:guest_star',
|
||||
'channel:read:hype_train',
|
||||
'channel:manage:moderators',
|
||||
'channel:read:polls',
|
||||
'channel:manage:polls',
|
||||
'channel:read:predictions',
|
||||
'channel:manage:predictions',
|
||||
'channel:manage:raids',
|
||||
'channel:read:redemptions',
|
||||
'channel:manage:redemptions',
|
||||
'channel:manage:schedule',
|
||||
'channel:read:stream_key',
|
||||
'channel:read:subscriptions',
|
||||
'channel:manage:videos',
|
||||
'channel:read:vips',
|
||||
'channel:manage:vips',
|
||||
'channel:bot',
|
||||
'channel:moderate',
|
||||
'clips:edit',
|
||||
'moderation:read',
|
||||
'moderator:manage:announcements',
|
||||
'moderator:manage:automod',
|
||||
'moderator:read:automod_settings',
|
||||
'moderator:manage:automod_settings',
|
||||
'moderator:manage:banned_users',
|
||||
'moderator:read:blocked_terms',
|
||||
'moderator:manage:blocked_terms',
|
||||
'moderator:manage:chat_messages',
|
||||
'moderator:read:chat_settings',
|
||||
'moderator:manage:chat_settings',
|
||||
'moderator:read:chatters',
|
||||
'moderator:read:followers',
|
||||
'moderator:read:guest_star',
|
||||
'moderator:manage:guest_star',
|
||||
'moderator:read:shield_mode',
|
||||
'moderator:manage:shield_mode',
|
||||
'moderator:read:shoutouts',
|
||||
'moderator:manage:shoutouts',
|
||||
'moderator:read:unban_requests',
|
||||
'moderator:manage:unban_requests',
|
||||
'moderator:read:warnings',
|
||||
'moderator:manage:warnings',
|
||||
'user:edit',
|
||||
'user:edit:follows',
|
||||
'user:read:blocked_users',
|
||||
'user:manage:blocked_users',
|
||||
'user:read:broadcast',
|
||||
'user:manage:chat_color',
|
||||
'user:read:email',
|
||||
'user:read:emotes',
|
||||
'user:read:follows',
|
||||
'user:read:moderated_channels',
|
||||
'user:read:subscriptions',
|
||||
'user:manage:whispers',
|
||||
'user:bot',
|
||||
'user:read:chat',
|
||||
'user:write:chat',
|
||||
'chat:edit',
|
||||
'chat:read',
|
||||
'whispers:read',
|
||||
'whispers:edit',
|
||||
]
|
||||
Reference in New Issue
Block a user