### Basic Twitch Chat Bot Setup with Command Registration (Python) Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/tutorial/chat-use-middleware.md Sets up a basic Twitch chat bot that registers two simple commands, 'one' and 'two'. This serves as the foundation for applying middleware in subsequent examples. It requires Twitch API credentials and scopes for chat read/edit. ```python import asyncio from twitchAPI import Twitch from twitchAPI.chat import Chat, ChatCommand from twitchAPI.oauth import UserAuthenticationStorageHelper from twitchAPI.types import AuthScope APP_ID = 'your_app_id' APP_SECRET = 'your_app_secret' SCOPES = [AuthScope.CHAT_READ, AuthScope.CHAT_EDIT] TARGET_CHANNEL = ['your_first_channel', 'your_second_channel'] async def command_one(cmd: ChatCommand): await cmd.reply('This is the first command!') async def command_two(cmd: ChatCommand): await cmd.reply('This is the second command!') async def run(): twitch = await Twitch(APP_ID, APP_SECRET) helper = UserAuthenticationStorageHelper(twitch, SCOPES) await helper.bind() chat = await Chat(twitch, initial_channel=TARGET_CHANNEL) chat.register_command('one', command_one) chat.register_command('two', command_two) chat.start() try: input('press Enter to shut down...\n') except KeyboardInterrupt: pass finally: chat.stop() await twitch.close() asyncio.run(run()) ``` -------------------------------- ### EventSub Listen/Unsubscribe (v2) Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/v3-migration.md Shows EventSub operations in v2, where `listen_` and `unsubscribe_` functions are synchronous. This example demonstrates listening to channel follows and unsubscribing from all events. ```python event_sub.unsubscribe_all() event_sub.listen_channel_follow(user_id, on_follow) ``` -------------------------------- ### EventSub Example (v4) using twitchAPI.eventsub Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/v4-migration.md This Python snippet demonstrates how to set up and use the EventSub module in pytwitchapi v4 for listening to channel follow events. It requires the `twitchAPI` library and `asyncio`. The function `eventsub_example` initializes EventSub, subscribes to follow events, and stops the service gracefully. Input and output are handled via standard console I/O and printed event data. ```python from twitchAPI.eventsub import EventSub import asyncio EVENTSUB_URL = 'https://url.to.your.webhook.com' async def on_follow(data: dict): print(data) async def eventsub_example(): # twitch setup is left out of this example event_sub = EventSub(EVENTSUB_URL, APP_ID, 8080, twitch) await event_sub.unsubscribe_all() event_sub.start() await event_sub.listen_channel_follow_v2(user.id, user.id, on_follow) try: input('press Enter to shut down...') finally: await event_sub.stop() await twitch.close() print('done') asyncio.run(eventsub_example()) ``` -------------------------------- ### EventSub Listen/Unsubscribe (v3 Async) Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/v3-migration.md Demonstrates EventSub operations in v3, where `listen_` and `unsubscribe_` functions are asynchronous and must be awaited. This example shows listening to channel follows and unsubscribing from all events. ```python await event_sub.unsubscribe_all() await event_sub.listen_channel_follow(user_id, on_follow) ``` -------------------------------- ### Use AsyncGenerator for Automatic Pagination (v3) Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/v3-migration.md Demonstrates the use of `AsyncGenerator` for automatically iterating through all API results, handling pagination seamlessly. This example fetches all stream tags. Developers should implement exit conditions for potentially endless streams. ```python async for tag in twitch.get_all_stream_tags(): print(tag.tag_id) ``` -------------------------------- ### EventSub Webhook Example (v4) using twitchAPI.eventsub.webhook Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/v4-migration.md This Python snippet shows how to utilize the `EventSubWebhook` class from `twitchAPI.eventsub.webhook` in v4 for handling Twitch EventSub events, specifically channel follows. It depends on `twitchAPI` and `asyncio`. The `eventsub_webhook_example` function sets up the webhook, subscribes to follow events, and manages the service lifecycle. It processes event data using a dedicated `ChannelFollowEvent` object. ```python from twitchAPI.eventsub.webhook import EventSubWebhook from twitchAPI.object.eventsub import ChannelFollowEvent import asyncio EVENTSUB_URL = 'https://url.to.your.webhook.com' async def on_follow(data: ChannelFollowEvent): print(f'{data.event.user_name} now follows {data.event.broadcaster_user_name}!') async def eventsub_webhook_example(): # twitch setup is left out of this example eventsub = EventSubWebhook(EVENTSUB_URL, 8080, twitch) await eventsub.unsubscribe_all() eventsub.start() await eventsub.listen_channel_follow_v2(user.id, user.id, on_follow) try: input('press Enter to shut down...') finally: await eventsub.stop() await twitch.close() print('done') asyncio.run(eventsub_webhook_example()) ``` -------------------------------- ### Twitch Pagination Helpers (Python) Source: https://context7.com/teekeks/pytwitchapi/llms.txt Demonstrates the use of helper functions for managing pagination and limiting results when interacting with the Twitch API. Includes examples for getting the first result, limiting the number of items, and manual cursor-based pagination. ```python from twitchAPI.twitch import Twitch from twitchAPI.helper import first, limit import asyncio async def main(): twitch = await Twitch('your_app_id', 'your_app_secret') try: # Get only the first result user = await first(twitch.get_users(logins='teekeks42')) print(f"First user: {user.display_name}") # Limit results to specific count print("\nTop 5 games:") async for game in limit(twitch.get_top_games(), 5): print(f" - {game.name}") # Manual pagination with cursor streams_generator = twitch.get_streams(first=20) # Get first page page1 = [] async for stream in streams_generator: page1.append(stream) if len(page1) >= 20: break print(f"\nGot {len(page1)} streams from page 1") # AsyncIterTwitchObject has metadata schedule = await twitch.get_channel_stream_schedule(broadcaster_id='12345') print(f"\nSchedule for {schedule.broadcaster_name}") print(f"Timezone: {schedule.vacation}") async for segment in limit(schedule, 5): print(f" {segment.title} at {segment.start_time}") finally: await twitch.close() asyncio.run(main()) ``` -------------------------------- ### Start and Stop EventSub Client Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.base.md Abstract methods to start and stop the EventSub client. The `start` method initiates the client and raises a `RuntimeError` if it's already running. The `stop` method gracefully shuts down the client, optionally unsubscribing from all known topics if configured. ```python # Start the client # await event_sub_client.start() # Stop the client # await event_sub_client.stop() ``` -------------------------------- ### Python EventSub Webhook Example for Channel Follows Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.webhook.md Demonstrates setting up and using the EventSub Webhook client to listen for channel follow events. It requires Twitch API credentials, a valid HTTPS callback URL, and handles user authentication. The example initializes the client, subscribes to follow events, and processes the event data within a callback function. ```python from twitchAPI.twitch import Twitch from twitchAPI.helper import first from twitchAPI.eventsub.webhook import EventSubWebhook from twitchAPI.object.eventsub import ChannelFollowEvent from twitchAPI.oauth import UserAuthenticator from twitchAPI.type import AuthScope import asyncio TARGET_USERNAME = 'target_username_here' EVENTSUB_URL = 'https://url.to.your.webhook.com' APP_ID = 'your_app_id' APP_SECRET = 'your_app_secret' TARGET_SCOPES = [AuthScope.MODERATOR_READ_FOLLOWERS] async def on_follow(data: ChannelFollowEvent): # our event happened, lets do things with the data we got! print(f'{data.event.user_name} now follows {data.event.broadcaster_user_name}!') async def eventsub_webhook_example(): # create the api instance and get the ID of the target user twitch = await Twitch(APP_ID, APP_SECRET) user = await first(twitch.get_users(logins=TARGET_USERNAME)) # the user has to authenticate once using the bot with our intended scope. # since we do not need the resulting token after this authentication, we just discard the result we get from authenticate() # Please read up the UserAuthenticator documentation to get a full view of how this process works auth = UserAuthenticator(twitch, TARGET_SCOPES) await auth.authenticate() # basic setup, will run on port 8080 and a reverse proxy takes care of the https and certificate eventsub = EventSubWebhook(EVENTSUB_URL, 8080, twitch) # unsubscribe from all old events that might still be there # this will ensure we have a clean slate await eventsub.unsubscribe_all() # start the eventsub client eventsub.start() # subscribing to the desired eventsub hook for our user # the given function (in this example on_follow) will be called every time this event is triggered # the broadcaster is a moderator in their own channel by default so specifying both as the same works in this example await eventsub.listen_channel_follow_v2(user.id, user.id, on_follow) # eventsub will run in its own process # so lets just wait for user input before shutting it all down again try: input('press Enter to shut down...') finally: # stopping both eventsub as well as gracefully closing the connection to the API await eventsub.stop() await twitch.close() print('done') # lets run our example asyncio.run(eventsub_webhook_example()) ``` -------------------------------- ### Charity Campaign Start Data Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.object.eventsub.md Contains details about a charity campaign that has started, including the broadcaster and charity information. ```APIDOC ## Charity Campaign Start Data Object ### Description Provides information related to the start of a charity campaign on Twitch. ### Fields - **id** (string) - The unique identifier for the charity campaign. - **broadcaster_id** (string) - The ID of the broadcaster running the campaign. - **broadcaster_login** (string) - The login name of the broadcaster. - **broadcaster_name** (string) - The display name of the broadcaster. - **charity_name** (string) - The name of the charity organization. ### Methods - **to_dict(include_none_values=False)** - Builds a dictionary representation of the object. `include_none_values` determines if fields with `None` values are included. ``` -------------------------------- ### Iterate Over API Results with IterTwitchObject (v3) Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/v3-migration.md Shows how to work with `IterTwitchObject`, a special type of `TwitchObject` that contains a list and other useful data. This example fetches a bits leaderboard and iterates through its entries, accessing rank, user name, and score. ```python lb = await twitch.get_bits_leaderboard() print(lb.total) for e in lb: print(f'#{e.rank:02d} - {e.user_name}: {e.score}') ``` -------------------------------- ### Channel Charity Campaign Start Event Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.md Listen for notifications when a broadcaster starts a charity campaign. ```APIDOC ## GET /eventsub/channel/charity/campaign/start ### Description Subscribes to notifications when a broadcaster starts a charity campaign. ### Method GET ### Endpoint /eventsub/channel/charity/campaign/start ### Parameters #### Query Parameters - **broadcaster_id** (string) - Required - The ID of the broadcaster to monitor. ### Response #### Success Response (200) - **event_type** (string) - The type of event, 'channel.charity_campaign.start'. - **payload** (object) - Contains details about the charity campaign, including ID, broadcaster info, campaign details, and start time. #### Response Example ```json { "event_type": "channel.charity_campaign.start", "payload": { "id": "campaign-abc", "broadcaster_id": "12345", "broadcaster_login": "exampleuser", "broadcaster_name": "Example User", "charity_name": "Example Charity", "charity_logo": "https://example.com/logo.png", "charity_website": "https://example.com/charity", "campaign_id": "campaign-123", "campaign_name": "Example Charity Drive", "campaign_goal_amount": 10000, "campaign_goal_currency": "USD", "campaign_current_amount": 0, "campaign_current_currency": "USD", "campaign_started_at": "2023-10-27T13:00:00Z", "campaign_ended_at": null } } ``` ``` -------------------------------- ### Channel Charity Campaign Start Subscription Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.base.md Subscribe to notifications when a broadcaster starts a charity campaign. Requires the channel read charity authentication scope. ```APIDOC ## POST /eventsub/subscriptions/channel.charity_campaign.start ### Description Subscribes to notifications when a broadcaster starts a charity campaign. This endpoint requires the `CHANNEL_READ_CHARITY` authentication scope. ### Method POST ### Endpoint /eventsub/subscriptions/channel.charity_campaign.start ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **broadcaster_user_id** (string) - Required - The ID of the broadcaster to monitor. - **callback** (function) - Required - The callback function to execute when the event occurs. ### Request Example ```json { "broadcaster_user_id": "12345", "callback": "async def handle_charity_start(event): ..." } ``` ### Response #### Success Response (200) - **subscription_id** (string) - The ID of the created subscription topic. #### Response Example ```json { "subscription_id": "abcdef12345" } ``` ### Errors - **EventSubSubscriptionConflict**: If a conflict exists with an existing subscription. - **EventSubSubscriptionTimeout**: If the subscription confirmation times out. - **EventSubSubscriptionError**: If the subscription fails for other reasons. - **TwitchBackendException**: If the subscription fails due to a Twitch backend error. ``` -------------------------------- ### Python Custom Middleware Example: Coin Flip Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/tutorial/chat-use-middleware.md This Python code defines a custom middleware `MyOwnCoinFlipMiddleware` by extending `BaseCommandMiddleware`. It implements a `can_execute` method that randomly returns True or False, simulating a 50% execution chance. The `was_executed` method is included for potential state updates but remains empty in this example. It requires `typing` and `random` modules. ```python from typing import Callable, Optional, Awaitable import random # Assuming BaseCommandMiddleware and ChatCommand are defined elsewhere # class BaseCommandMiddleware: # async def can_execute(self, cmd: ChatCommand) -> bool: # return True # async def was_executed(self, cmd: ChatCommand): # pass # class ChatCommand: # pass class MyOwnCoinFlipMiddleware(BaseCommandMiddleware): # it is best practice to add this part of the init function to be compatible with the default middlewares # but you can also leave this out should you know you dont need it def __init__(self, execute_blocked_handler: Optional[Callable[[ChatCommand], Awaitable[None]]] = None): self.execute_blocked_handler = execute_blocked_handler async def can_execute(self, cmd: ChatCommand) -> bool: # add your own logic here, return True if the command should execute and False otherwise return random.choice([True, False]) async def was_executed(self, cmd: ChatCommand): # this will be called whenever a command this Middleware is attached to was executed, use this to update your internal state # since this is a basic example, we do nothing here pass ``` ```python # Assuming 'chat' is an instance of your chat client and 'execute_ban_me' is a command function # chat.register_command('ban-me', execute_ban_me, command_middleware=[MyOwnCoinFlipMiddleware()]) ``` -------------------------------- ### GET /helix/schedule Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.twitch.md Retrieves scheduled broadcasts for a given channel. Supports filtering by specific stream segment IDs, start time, and pagination. ```APIDOC ## GET /helix/schedule ### Description Gets all scheduled broadcasts or specific scheduled broadcasts from a channel’s stream schedule. Requires App or User Authentication. ### Method GET ### Endpoint `/helix/schedule` ### Parameters #### Query Parameters - **broadcaster_id** (string) - Required - The user ID of the broadcaster whose stream schedule is being retrieved. - **stream_segment_ids** (list of strings) - Optional - A list of specific stream segment IDs to retrieve. Maximum 100 entries. - **start_time** (datetime) - Optional - A timestamp to start returning stream segments from. - **utc_offset** (string) - Optional - A timezone offset to be used for the schedule. - **first** (integer) - Optional - The maximum number of items to return per API call. Minimum 1, Maximum 25. Default: 20. - **after** (string) - Optional - Cursor for forward pagination. Typically handled by the library, but can be used for manual pagination. ### Request Example ```json { "broadcaster_id": "14970743", "stream_segment_ids": ["segment1_id", "segment2_id"], "start_time": "2023-10-27T10:00:00Z", "utc_offset": "+01:00", "first": 10, "after": "cursor_string" } ``` ### Response #### Success Response (200) - **data** (array of objects) - A list of stream schedule objects. - **id** (string) - The ID of the stream segment. - **start_time** (string) - The start time of the stream segment in ISO 8601 format. - **end_time** (string) - The end time of the stream segment in ISO 8601 format. - **title** (string) - The title of the stream segment. - **pagination** (object) - Object containing pagination information. - **cursor** (string) - Cursor for the next page of results. #### Response Example ```json { "data": [ { "id": "a1b2c3d4e5f6", "start_time": "2023-10-27T12:00:00Z", "end_time": "2023-10-27T14:00:00Z", "title": "My Awesome Stream" } ], "pagination": { "cursor": "next_cursor_string" } } ``` ### Errors - **TwitchAPIException**: If the request was malformed or a query parameter is missing or invalid. - **UnauthorizedException**: If authentication is not set or invalid. - **TwitchAuthorizationException**: If the used authentication token became invalid and re-authentication failed. - **TwitchBackendException**: If the Twitch API itself runs into problems. - **TwitchResourceNotFound**: If the broadcaster has not created a streaming schedule. - **ValueError**: If `stream_segment_ids` has more than 100 entries or if `first` is not in the range 1 to 25. ``` -------------------------------- ### GET /user/extensions/live Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.twitch.md Fetches information about the active extensions installed by a specified user. The user can be identified by their user ID or defaults to the authenticated user. Requires USER_READ_BROADCAST scope. ```APIDOC ## GET /user/extensions/live ### Description Gets information about active extensions installed by a specified user, identified by a user ID or the authenticated user. ### Method GET ### Endpoint /user/extensions/live ### Parameters #### Path Parameters None #### Query Parameters - **user_id** (Optional[str]) - ID of the user whose installed extensions will be returned. Defaults to the authenticated user if not provided. #### Request Body None ### Request Example None ### Response #### Success Response (200) - **UserActiveExtensions** (UserActiveExtensions) - An object containing information about the user's active extensions. #### Response Example ```json { "user_id": "string", "user_name": "string", "extensions": [ { "id": "string", "version": "string", "name": "string", "overlay": { "width": 0, "height": 0, "viewer_url": "string" }, "panel": { "width": 0, "height": 0, "viewer_url": "string" }, "mobile_ready": true } ] } ``` ``` -------------------------------- ### Initialize TwitchAPI Library (v2) Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/v3-migration.md Initializes the TwitchAPI library in v2, setting up synchronous refresh callbacks for application and user authentication. This version uses dictionaries for API responses. ```python from twitchAPI.twitch import Twitch def user_refresh(token: str, refresh_token: str): print(f'my new user token is: {token}') def app_refresh(token: str): print(f'my new app token is: {token}') twitch = Twitch('app_id', 'app_secret') twitch.app_auth_refresh_callback = app_refresh twitch.user_auth_refresh_callback = user_refresh ``` -------------------------------- ### Chat Client Initialization and Configuration Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.chat.md This section details the initialization of the Chat client and its various configuration parameters, along with the start method. ```APIDOC ## __init__ Chat Client ### Description Initializes the Chat client for the py-twitch-api library. This constructor allows for extensive configuration of the chat connection, bot behavior, and event loop handling. ### Method `__init__` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **twitch** (`Twitch`) - Required - A authenticated Twitch instance. * **connection_url** (`Optional[str]`) - Optional - An alternative connection URL. Defaults to `None`. * **is_verified_bot** (`bool`) - Optional - Set to `True` if your bot is verified by Twitch. Defaults to `False`. * **initial_channel** (`Optional[List[str]]`) - Optional - A list of channels to automatically join on startup. Defaults to `None`. * **callback_loop** (`Optional[AbstractEventLoop]`) - Optional - The asyncio event loop to be used for callbacks. Defaults to the one used by Chat. * **no_message_reset_time** (`Optional[float]`) - Optional - The time in minutes after which the connection is considered dead if no messages are received. Defaults to `10`. * **no_shared_chat_messages** (`bool`) - Optional - Filters out shared chat messages from other channels. Defaults to `True`. ### Class Attributes * **logger** (`Logger`) - The logger used for Chat-related log messages. * **twitch** (`Twitch`) - The Twitch instance being used. * **connection_url** (`str`) - Alternative connection URL. Defaults to `None`. * **ping_frequency** (`int`) - Frequency in seconds for sending ping messages. Should usually not be changed. * **ping_jitter** (`int`) - Jitter in seconds for ping messages. Should usually not be changed. * **listen_confirm_timeout** (`int`) - Time in seconds that any `listen_` should wait for its subscription to be completed. * **reconnect_delay_steps** (`List[int]`) - Time in seconds between reconnect attempts. * **log_no_registered_command_handler** (`bool`) - Controls if instances of commands issued in chat where no handler exists should be logged. Defaults to `True`. * **room_cache** (`Dict[str, ChatRoom]`) - Internal cache of all chat rooms the bot is currently in. * **join_timeout** (`int`) - Time in seconds till a channel join attempt times out. * **default_command_execution_blocked_handler** (`Optional[Callable[[ChatCommand], Awaitable[None]]]`) - The default handler to be called should a command execution be blocked by a middleware that has no specific handler set. ### Method #### `start()` Starts the Chat Client. * **Raises:** `RuntimeError` – if already started * **Return type:** `None` ### Request Example ```python # Example initialization (assuming 'twitch_instance' is an authenticated Twitch object) from twitchAPI.chat import Chat chat_client = Chat(twitch_instance, initial_channel=['channel1', 'channel2']) ``` ### Response #### Success Response (Initialization) No direct response body for initialization, but attributes are set. #### Response Example None ``` -------------------------------- ### Twitch Chat Bot Implementation in Python Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/index.md This Python script demonstrates how to set up and run a basic Twitch chat bot. It utilizes the PyTwitchAPI library to connect to Twitch, register event handlers for various chat events (ready, message, subscription), and define command responses. Dependencies include the 'twitchAPI' library. The bot requires Twitch application credentials (APP_ID, APP_SECRET) and user authentication scopes. ```python from twitchAPI.twitch import Twitch from twitchAPI.oauth import UserAuthenticator from twitchAPI.type import AuthScope, ChatEvent from twitchAPI.chat import Chat, EventData, ChatMessage, ChatSub, ChatCommand import asyncio APP_ID = 'my_app_id' APP_SECRET = 'my_app_secret' USER_SCOPE = [AuthScope.CHAT_READ, AuthScope.CHAT_EDIT] TARGET_CHANNEL = 'teekeks42' # this will be called when the event READY is triggered, which will be on bot start async def on_ready(ready_event: EventData): print('Bot is ready for work, joining channels') # join our target channel, if you want to join multiple, either call join for each individually # or even better pass a list of channels as the argument await ready_event.chat.join_room(TARGET_CHANNEL) # you can do other bot initialization things in here # this will be called whenever a message in a channel was send by either the bot OR another user async def on_message(msg: ChatMessage): print(f'in {msg.room.name}, {msg.user.name} said: {msg.text}') # this will be called whenever someone subscribes to a channel async def on_sub(sub: ChatSub): print(f'New subscription in {sub.room.name}:\n' f' Type: {sub.sub_plan}\n' f' Message: {sub.sub_message}') # this will be called whenever the !reply command is issued async def test_command(cmd: ChatCommand): if len(cmd.parameter) == 0: await cmd.reply('you did not tell me what to reply with') else: await cmd.reply(f'{cmd.user.name}: {cmd.parameter}') # this is where we set up the bot async def run(): # set up twitch api instance and add user authentication with some scopes twitch = await Twitch(APP_ID, APP_SECRET) auth = UserAuthenticator(twitch, USER_SCOPE) token, refresh_token = await auth.authenticate() await twitch.set_user_authentication(token, USER_SCOPE, refresh_token) # create chat instance chat = await Chat(twitch) # register the handlers for the events you want # listen to when the bot is done starting up and ready to join channels chat.register_event(ChatEvent.READY, on_ready) # listen to chat messages chat.register_event(ChatEvent.MESSAGE, on_message) # listen to channel subscriptions chat.register_event(ChatEvent.SUB, on_sub) # there are more events, you can view them all in this documentation # you can directly register commands and their handlers, this will register the !reply command chat.register_command('reply', test_command) # we are done with our setup, lets start this bot up! chat.start() # lets run till we press enter in the console try: input('press ENTER to stop\n') finally: # now we can close the chat bot and the twitch api client chat.stop() await twitch.close() # lets run our setup asyncio.run(run()) ``` -------------------------------- ### EventSub Webhook Initialization Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.webhook.md Initializes the EventSub Webhook client with the necessary configuration. This includes setting up the callback URL, port, and Twitch API authentication. ```APIDOC ## EventSub Webhook Initialization ### Description Initializes the EventSub Webhook client. ### Method Constructor (`__init__`) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **callback_url** (str) - Required - The full URL of the webhook. - **port** (int) - Required - The port on which this webhook should run. - **twitch** (Twitch) - Required - An app-authenticated instance of `Twitch`. - **ssl_context** (Optional[SSLContext]) - Optional - Optional SSL context to be used. Default: `None`. - **host_binding** (str) - Optional - The host to bind the internal server to. Default: `0.0.0.0`. - **subscription_url** (Optional[str]) - Optional - Alternative subscription URL, useful for development with the twitch-cli. - **callback_loop** (Optional[AbstractEventLoop]) - Optional - The asyncio event loop to be used for callbacks. - **revocation_handler** (Optional[Callable[[dict], Awaitable[None]]]) - Optional - Optional handler for when subscriptions get revoked. Default: `None`. - **message_deduplication_history_length** (int) - Optional - The amount of messages being considered for the duplicate message deduplication. Default: `50`. - **secret** (str) - Optional - A random secret string for added security. Default: A random 20 character long string. - **wait_for_subscription_confirm** (bool) - Optional - Set to false if you don't want to wait for a subscription confirm. Default: `True`. - **wait_for_subscription_confirm_timeout** (int) - Optional - Max time in seconds to wait for a subscription confirmation. Only used if `wait_for_subscription_confirm` is set to True. Default: `30`. - **unsubscribe_on_stop** (bool) - Optional - Unsubscribe all currently active Webhooks on calling `stop()`. Default: `True`. ### Request Example ```python from twitchAPI.webhook import EventSubWebhook from twitchAPI.twitch import Twitch twitch = Twitch("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") webhook = EventSubWebhook( callback_url="https://your.webhook.url", port=8080, twitch=twitch ) ``` ### Response None (initialization does not return a value). ``` -------------------------------- ### EventSubBase Class Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.base.md Documentation for the base EventSub client class, including its constructor, logger, and abstract methods for starting and stopping the client. ```APIDOC ## Class: EventSubBase ### Description EventSub integration for the Twitch Helix API. This is the base class for all EventSub Transport implementations. ### Parameters #### Constructor Parameters - **twitch** (Twitch) - Required - A Twitch app authenticated instance. - **logger_name** (str) - Required - The name of the logger to be used. #### Attributes - **logger** (Logger) - The logger instance used for EventSub related messages. ### Methods #### `start()` - **Description**: Starts the EventSub client. - **Type**: abstract method - **Return Type**: None - **Raises**: RuntimeError - if EventSub is already running. #### `stop()` - **Description**: Stops the EventSub client. This also unsubscribes from all known subscriptions if `unsubscribe_on_stop` is True. - **Type**: abstract async method - **Return Type**: None #### `unsubscribe_all()` - **Description**: Unsubscribe from all subscriptions. - **Type**: async method - **Return Type**: None #### `unsubscribe_all_known()` - **Description**: Unsubscribe from all subscriptions known to this client. - **Type**: async method - **Return Type**: None #### `unsubscribe_topic(topic_id)` - **Description**: Unsubscribe from a specific topic. - **Type**: async method - **Parameters**: - **topic_id** (str) - Required - The ID of the topic to unsubscribe from. - **Return Type**: bool ``` -------------------------------- ### Build a Twitch Chat Bot with Commands using Python Source: https://context7.com/teekeks/pytwitchapi/llms.txt This Python script outlines the creation of a functional Twitch chat bot using PyTwitchAPI. It includes setup for authentication, event handling for messages and subscriptions, and defining custom chat commands like '!hello' and '!say'. The bot requires application credentials, a target channel, and user authentication scopes. It listens for chat events and responds accordingly. ```python from twitchAPI.twitch import Twitch from twitchAPI.oauth import UserAuthenticator from twitchAPI.type import AuthScope, ChatEvent from twitchAPI.chat import Chat, ChatMessage, ChatCommand, ChatSub, EventData import asyncio APP_ID = 'your_app_id' APP_SECRET = 'your_app_secret' TARGET_CHANNEL = 'teekeks42' USER_SCOPE = [AuthScope.CHAT_READ, AuthScope.CHAT_EDIT] # Bot ready event async def on_ready(ready_event: EventData): print('Bot is ready, joining channels') await ready_event.chat.join_room(TARGET_CHANNEL) print(f'Joined {TARGET_CHANNEL}') # Chat message event async def on_message(msg: ChatMessage): print(f'[{msg.room.name}] {msg.user.name}: {msg.text}') # Subscription event async def on_sub(sub: ChatSub): if sub.is_gift: print(f'{sub.user.name} gifted a subscription!') else: print(f'{sub.user.name} subscribed!') # Command: !hello async def command_hello(cmd: ChatCommand): await cmd.reply(f'Hello @{cmd.user.name}!') # Command: !say async def command_say(cmd: ChatCommand): if cmd.parameter: await cmd.send(f'{cmd.user.name} says: {cmd.parameter}') else: await cmd.reply('Usage: !say ') ``` -------------------------------- ### GET /chat/settings Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.twitch.md Gets the broadcaster’s chat settings. Requires App authentication. ```APIDOC ## GET /chat/settings ### Description Gets the broadcaster’s chat settings. Requires App authentication. ### Method GET ### Endpoint `/chat/settings` ### Parameters #### Query Parameters - **broadcaster_id** (str) - Required - The ID of the broadcaster whose chat settings you want to get. - **moderator_id** (Optional[str]) - Optional - Required only to access the non_moderator_chat_delay or non_moderator_chat_delay_duration settings. Default: None ### Request Example ```json { "broadcaster_id": "broadcaster_id", "moderator_id": "moderator_id" } ``` ### Response #### Success Response (200) - **data** (ChatSettings) - An object containing the chat settings for the specified broadcaster. ``` -------------------------------- ### Channel Charity Campaign Start Subscription Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.websocket.md Subscribe to notifications when a broadcaster starts a charity campaign. Requires CHANNEL_READ_CHARITY scope. ```APIDOC ## POST /eventsub/subscriptions ### Description Subscribes to notifications when a broadcaster starts a charity campaign. This endpoint is part of the EventSub webhook subscription system. ### Method POST ### Endpoint /eventsub/subscriptions ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **type** (string) - Required - The type of event to subscribe to. For this endpoint, it is `channel.charity_campaign.start`. - **version** (string) - Required - The version of the event type. Typically `1`. - **condition** (object) - Required - The condition object for the subscription. - **broadcaster_user_id** (string) - Required - The ID of the broadcaster to monitor. - **transport** (object) - Required - The transport method for the notification. - **method** (string) - Required - The transport method, e.g., `webhook`. - **callback** (string) - Required - The URL to which notifications should be sent. ### Request Example ```json { "type": "channel.charity_campaign.start", "version": "1", "condition": { "broadcaster_user_id": "12345" }, "transport": { "method": "webhook", "callback": "https://your.server.com/twitch/events" } } ``` ### Response #### Success Response (200) - **data** (array) - An array containing the subscription information. - **id** (string) - The unique identifier for the subscription. - **status** (string) - The status of the subscription (e.g., "enabled", "webhook_callback_pending"). - **type** (string) - The type of the subscription. - **version** (string) - The version of the subscription. - **condition** (object) - The condition object for the subscription. - **transport** (object) - The transport object for the subscription. - **created_at** (string) - The timestamp when the subscription was created. #### Response Example ```json { "data": [ { "id": "abcdef123456", "status": "webhook_callback_pending", "type": "channel.charity_campaign.start", "version": "1", "condition": { "broadcaster_user_id": "12345" }, "transport": { "method": "webhook", "callback": "https://your.server.com/twitch/events" }, "created_at": "2023-10-26T12:00:00Z" } ] } ``` ### Errors - **EventSubSubscriptionConflict**: If a conflict was found with this subscription. - **EventSubSubscriptionTimeout**: If the subscription was not confirmed in time. - **EventSubSubscriptionError**: If the subscription failed. - **TwitchBackendException**: If the subscription failed due to a Twitch backend error. ``` -------------------------------- ### Mocking EventSub Webhook with PyTwitchAPI Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/tutorial/mocking.md This Python code sets up a webhook listener for the `channel.subscribe` EventSub event and prints the command to trigger it using `twitch-cli`. It requires `twitchAPI` and real client credentials for subscribing to live events, although the triggering is simulated. The output is a command-line instruction. ```python import asyncio from twitchAPI.oauth import UserAuthenticationStorageHelper from twitchAPI.eventsub.webhook import EventSubWebhook from twitchAPI.object.eventsub import ChannelSubscribeEvent from twitchAPI.helper import first from twitchAPI.twitch import Twitch from twitchAPI.type import AuthScope CLIENT_ID = 'REAL_CLIENT_ID' CLIENT_SECRET = 'REAL_CLIENT_SECRET' EVENTSUB_URL = 'https://my.eventsub.url' async def on_subscribe(data: ChannelSubscribeEvent): print(f'{data.event.user_name} just subscribed!') async def run(): twitch = await Twitch(CLIENT_ID, CLIENT_SECRET) auth = UserAuthenticationStorageHelper(twitch, [AuthScope.CHANNEL_READ_SUBSCRIPTIONS]) await auth.bind() user = await first(twitch.get_users()) eventsub = EventSubWebhook(EVENTSUB_URL, 8080, twitch) eventsub.start() sub_id = await eventsub.listen_channel_subscribe(user.id, on_subscribe) print(f'twitch event trigger channel.subscribe -F {EVENTSUB_URL}/callback -t {user.id} -u {sub_id} -s {eventsub.secret}') try: input('press ENTER to stop') finally: await eventsub.stop() await twitch.close() asyncio.run(run()) ``` -------------------------------- ### Channel Charity Campaign Start Events Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.webhook.md Subscribe to notifications when a broadcaster starts a charity campaign. Requires the CHANNEL_READ_CHARITY auth scope. ```APIDOC ## POST /eventsub/channel.charity_campaign.start ### Description Sends a notification when the broadcaster starts a charity campaign. ### Method POST ### Endpoint /eventsub/channel.charity_campaign.start ### Parameters #### Query Parameters - **broadcaster_user_id** (string) - Required - The ID of the broadcaster that you want to receive notifications about when they start a charity campaign. - **callback** (Callable) - Required - A function to handle incoming `CharityCampaignStartEvent` data. ### Request Body This endpoint does not have a request body. The parameters are passed as query parameters. ### Response #### Success Response (200) - **subscription_id** (string) - The ID of the topic subscription. #### Response Example ```json { "subscription_id": "abcdef12345" } ``` ### Errors - **EventSubSubscriptionConflict**: If a conflict was found with this subscription (e.g., already subscribed to this exact topic). - **EventSubSubscriptionTimeout**: If `wait_for_subscription_confirm` is true and the subscription was not fully confirmed in time. - **EventSubSubscriptionError**: If the subscription failed. - **TwitchBackendException**: If the subscription failed due to a Twitch backend error. ``` -------------------------------- ### POST /eventsub/goal_begin Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.eventsub.base.md Subscribes to the Channel Goal Begin event for a specified broadcaster. This event is triggered when a new channel goal is started. ```APIDOC ## POST /eventsub/goal_begin ### Description Subscribes to the Channel Goal Begin event for a specified broadcaster. This event is triggered when a new channel goal is started. ### Method POST ### Endpoint /eventsub/goal_begin ### Parameters #### Query Parameters - **broadcaster_user_id** (string) - Required - The ID of the user whose goal events you want to listen to. #### Request Body ```json { "callback": "function(event): awaitable[None]" } ``` ### Request Example ```json { "callback": "my_goal_begin_handler" } ``` ### Response #### Success Response (200) - **subscription_id** (string) - The ID of the created subscription. #### Response Example ```json { "subscription_id": "abc123xyz789" } ``` ### Authentication Requires `CHANNEL_READ_GOALS` scope. ``` -------------------------------- ### GET /shield-mode-status Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/modules/twitchAPI.twitch.md Gets the broadcaster’s Shield Mode activation status. Requires User Authentication with MODERATOR_READ_SHIELD_MODE or MODERATOR_MANAGE_SHIELD_MODE scope. ```APIDOC ## GET /shield-mode-status ### Description Gets the broadcaster’s Shield Mode activation status. ### Method GET ### Endpoint /shield-mode-status ### Parameters #### Query Parameters - **broadcaster_id** (string) - Required - The ID of the broadcaster whose Shield Mode activation status you want to get. - **moderator_id** (string) - Required - The ID of the broadcaster or a user that is one of the broadcaster’s moderators. ### Request Example ```json { "broadcaster_id": "12345", "moderator_id": "67890" } ``` ### Response #### Success Response (200) - **data** (array) - Shield Mode status details #### Response Example ```json { "data": [ { "is_active": true, "started_at": "2023-01-01T12:00:00Z" } ] } ``` ``` -------------------------------- ### Twitch Chat Bot with Global User and Channel Middleware (Python) Source: https://github.com/teekeks/pytwitchapi/blob/master/docs/tutorial/chat-use-middleware.md Extends the basic chat bot setup to include global middleware for restricting command usage. It uses `UserRestriction` to allow only 'user1' and `ChannelRestriction` to enforce commands only in 'your_first_channel'. Dependencies include `UserRestriction` and `ChannelRestriction` from `twitchAPI.chat.middleware`. ```python import asyncio from twitchAPI import Twitch from twitchAPI.chat import Chat, ChatCommand from twitchAPI.chat.middleware import UserRestriction, ChannelRestriction from twitchAPI.oauth import UserAuthenticationStorageHelper from twitchAPI.types import AuthScope APP_ID = 'your_app_id' APP_SECRET = 'your_app_secret' SCOPES = [AuthScope.CHAT_READ, AuthScope.CHAT_EDIT] TARGET_CHANNEL = ['your_first_channel', 'your_second_channel'] async def command_one(cmd: ChatCommand): await cmd.reply('This is the first command!') async def command_two(cmd: ChatCommand): await cmd.reply('This is the second command!') async def run(): twitch = await Twitch(APP_ID, APP_SECRET) helper = UserAuthenticationStorageHelper(twitch, SCOPES) await helper.bind() chat = await Chat(twitch, initial_channel=TARGET_CHANNEL) chat.register_command_middleware(UserRestriction(allowed_users=['user1'])) chat.register_command_middleware(ChannelRestriction(allowed_channel=['your_first_channel'])) chat.register_command('one', command_one) chat.register_command('two', command_two) chat.start() try: input('press Enter to shut down...\n') except KeyboardInterrupt: pass finally: chat.stop() await twitch.close() asyncio.run(run()) ```