**This is a major release, please see https://pytwitchapi.dev/en/v4.0.0/v4-migration.html for a migration guide!**
Keystone Features
-----------------
- EventSub now supports the newly added Websocket transport
- EventSub is now using TwitchObject based callback payloads instead of raw dictionaries
- Chat now supports Command Middleware, check out https://pytwitchapi.dev/en/v4.0.0/tutorial/chat-use-middleware.html for more info
- Added `UserAuthenticationStorageHelper` to cut down on common boilerplate code, check out https://pytwitchapi.dev/en/v4.0.0/tutorial/reuse-user-token.html for more info
Twitch
------
- Added new fields `ChannelInformation.is_branded_content` and `ChannelInformation.content_classification_labels` to response of `get_channel_information()`
- Added new parameters `modify_channel_information.is_branded_content` and `modify_channel_information.content_classification_labels` to `modify_channel_information()`
- Added new Endpoint "Get Content Classification Labels" `get_content_classification_labels()`
- Removed the following deprecated Endpoints:
- "Get Soundstrack Current Track"
- "Get SoundTrack Playlist"
- "Get Soundtrack Playlists"
- `get_polls()` now allows up to 20 poll IDs
- `get_channel_followers()` can now also be used without the required Scope or just with App Authentication
- Added new parameter `get_clips.is_featured` to `get_clips()` and added `object.api.Clip.is_featured` to result.
EventSub
--------
- Moved old EventSub from `twitchAPI.eventsub` to new package `twitchAPI.eventsub.webhook` and renamed it to `EventSubWebhook`
- Added new EventSub Websocket transport `EventSubWebsocket`
- All EventSub callbacks now use `object.base.TwitchObject` based Payloads instead of raw dictionaries. See :ref:`eventsub-available-topics` for a list of all available Payloads
- Added `EventSubBase.listen_channel_update_v2()`
- Added option for `EventSubWebhook` to specify a asyncio loop via `EventSubWebhook.callback_loop` in which to run all callbacks in
- Added option for `EventSubWebsocket` to specify a asyncio loop via `EventSubWebsocket.callback_loop` in which to run all callbacks in
- Added automatical removal of tailing ``/`` in `EventSubWebhook.callback_url` if present
- Fixed broken handling of malformed HTTP requests made to the callback endport of `EventSubWebhook`
- Made `EventSubWebhook` more easily mockable via ``twitch-cli`` by adding `EventSubWebhook.subscription_url`
- Added optional subscription revokation handler via `EventSubWebhook.revocation_handler` to `EventSubWebhook`
PubSub
------
- Handle Authorization Revoked messages (Thanks Braastos )
- Added option to specify a asyncio loop via `pubsub.PubSub.callback_loop` in which to run all callbacks in
Chat
----
- Added Chat Command Middleware, a way to decide if a command should run, see https://pytwitchapi.dev/en/v4.0.0/tutorial/chat-use-middleware.html for more info.
- Added the following default Chat Command Middleware:
- `ChannelRestriction`
- `UserRestriction`
- `StreamerOnly`
- `ChannelCommandCooldown`
- `ChannelUserCommandCooldown`
- `GlobalCommandCooldown`
- Added option to specify a asyncio loop via `callback_loop` in which to run all callbacks in
- Fixed errors raised in callbacks not being properly reported
- Added Hype Chat related fields to `ChatMessage`
- Improved logging
- Fixed KeyError when encountering some Notice events
- Added new reply tags `ChatMessage.reply_thread_parent_msg_id` and `ChatMessage.reply_thread_parent_user_login` to `ChatMessage`
- Reconnects no longer duplicate the channel join list
- `Chat.start()` now thows an error should Chat() not have been awaited
OAuth
-----
- Added `UserAuthenticationStorageHelper`, a easy plug and play way to generate user auth tokens only on demand
- Made it possible to mock all auth flows with ``twitch-cli``
Other
-----
- Added `AsyncIterTwitchObject.current_cursor()`
- Renamed module ``twitchAPI.types`` to `twitchAPI.type`
- Moved all API related TwitchObjects from module `twitchAPI.object` to `twitchAPI.object.api`
- Removed default imports from module `twitchAPI`