An Async Bot/API wrapper for Twitch made in Python.

Overview

https://raw.githubusercontent.com/TwitchIO/TwitchIO/master/logo.png

TwitchIO is an asynchronous Python wrapper around the Twitch API and IRC, with a powerful command extension for creating Twitch Chat Bots. TwitchIO covers almost all of the new Twitch API and features support for commands, PubSub, Webhooks, and EventSub.

Documentation

For the Official Documentation: Click Here!

Support

For support using TwitchIO, please join the official support server on Discord.

Discord

Installation

TwitchIO requires Python 3.7+. You can download the latest version of Python here.

Windows

py -m pip install -U twitchio

Linux

python -m pip install -U twitchio

Access Tokens

Visit Token Generator for a simple way to generate tokens for use with TwitchIO.

Getting Started

A simple Chat Bot.

from twitchio.ext import commands


class Bot(commands.Bot):

    def __init__(self):
        # Initialise our Bot with our access token, prefix and a list of channels to join on boot...
        super().__init__(token='ACCESS_TOKEN', prefix='?', initial_channels=['...'])

    async def event_ready(self):
        # We are logged in and ready to chat and use commands...
        print(f'Logged in as | {self.nick}')

    @commands.command()
    async def hello(self, ctx: commands.Context):
        # Send a hello back!
        await ctx.send(f'Hello {ctx.author.name}!')


bot = Bot()
bot.run()

Contributing

TwitchIO currently uses the Black formatter to enforce sensible style formatting.

Before creating a Pull Request it is encouraged you install and run black on your code.

The Line Length limit for TwitchIO is 120.

For installation and usage of Black visit: Black Formatter

For integrating Black into your IDE visit: Black IDE Usage

Special Thanks

Thank you to all those who contribute and help TwitchIO grow.

Special thanks to:

SnowyLuma

Harmon

Tom

Tesence

Adure

Scragly

Chillymosh

If I have forgotten anyone please let me know <3: EvieePy

Comments
  • No event_ready if initial_channels is not passed

    No event_ready if initial_channels is not passed

    Hello there, I stumbled across the issue that my event ready function is not called if the initial_channels parameter is not passed to the client. Since it is an optional parameter, I don't think this is supposed to happen.

    Thanks in advance!

    from twitchio import Client
    from os import getenv
    
    token = getenv("TWITCH_OAUTH_TOKEN")
    secret = getenv("TWITCH_CLIENT_SECRET")
    
    client = Client(token=token, client_secret=secret)  # <- Here event_ready is never called
    # client = Client(token=token, client_secret=secret, initial_channels=['gronkhtv'])  # <- This works just fine
    
    
    @client.event()
    async def event_ready() -> None:
        print("Ready!")
    
    
    client.run()
    
    IRC 2.0 3.x 
    opened by CeroProgramming 12
  • A weird _process_data error in console

    A weird _process_data error in console

    Traceback (most recent call last):
      File ".../python3.8/site-packages/twitchio/websocket.py", line 308, in _process_data            
        await partial_(parsed)                                 
      File ".../python3.8/site-packages/twitchio/websocket.py", line 427, in _usernotice              
        tags = dict(x.split("=") for x in rawData.split(";"))  
    ValueError: dictionary update sequence element #21 has length 3; 2 is required
    

    I have no clue how or why this happened 🤔

    bug IRC 2.0 
    opened by Commaster 11
  • Bot connects to first letter of channel if 'initial_channels' is a string

    Bot connects to first letter of channel if 'initial_channels' is a string

    Describe the bug If a Bot is initialized by passing initial_channels as a string instead of a list, the Bot will treat the string as a list and attempt to connect to the first letter of the channel name.

    Are you using TwitchIO within a Discord Bot? No

    What commit of TwitchIO are you using? Version 1.2.1

    To Reproduce

    1. Create a file bot.py with the following code
    import os
    from twitchio.ext import commands
    from dotenv import load_dotenv
    load_dotenv() # load environment variables
    
    class Bot(commands.Bot):
        async def event_ready(self):
            print("I am online")
    
    bot = Bot(irc_token=os.environ['TMI_TOKEN'], client_id=os.environ['CLIENT_ID'], nick=os.environ['BOT_NICK'],
              prefix=os.environ['BOT_PREFIX'], initial_channels='example_channel')
    bot.run()
    
    1. Create a .env file with the required environment variables
    2. Run bot.py

    Expected behaviour Either the bot connects to the given channel name, or a TypeError is raised indicating that initial_channels expects a list or tuple.

    Additional context OS: Windows 10 Pro (1909)

    Traceback

    Task exception was never retrieved
    future: <Task finished name='Task-16' coro=<WebsocketConnection.auth_seq() done, defined at C:\Users\stevo\Documents\GitHub\twitch-bot\env\lib\site-packages\twitchio\websocket.py:200> exception=TimeoutError('Request to join the "e" channel has timed out. Make sure the channel exists.')>
    Traceback (most recent call last):
      File "C:\Python39\lib\asyncio\tasks.py", line 489, in wait_for
        fut.result()
    asyncio.exceptions.CancelledError
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "C:\Users\stevo\Documents\GitHub\twitch-bot\env\lib\site-packages\twitchio\websocket.py", line 280, in _join_channel
        await asyncio.wait_for(fut, timeout=10)
      File "C:\Python39\lib\asyncio\tasks.py", line 491, in wait_for
        raise exceptions.TimeoutError() from exc
    asyncio.exceptions.TimeoutError
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "C:\Users\stevo\Documents\GitHub\twitch-bot\env\lib\site-packages\twitchio\websocket.py", line 228, in auth_seq
        await self.join_channels(*channels)
      File "C:\Users\stevo\Documents\GitHub\twitch-bot\env\lib\site-packages\twitchio\websocket.py", line 271, in join_channels
        await asyncio.gather(*[self._join_channel(x) for x in channels])
      File "C:\Users\stevo\Documents\GitHub\twitch-bot\env\lib\site-packages\twitchio\websocket.py", line 284, in _join_channel
        raise asyncio.TimeoutError(
    asyncio.exceptions.TimeoutError: Request to join the "e" channel has timed out. Make sure the channel exists.
    
    opened by Stevoisiak 11
  • TypeError: unsupported operand type(s) for +: 'NoneType' and 'str', hash(self.name + self.channel.name)

    TypeError: unsupported operand type(s) for +: 'NoneType' and 'str', hash(self.name + self.channel.name)

    Traceback (most recent call last):
      File "/home/arch/.local/lib/python3.10/site-packages/twitchio/websocket.py", line 315, in _process_data
        return await self._code(parsed, parsed["code"])
      File "/home/arch/.local/lib/python3.10/site-packages/twitchio/websocket.py", line 359, in _code
        self._cache_add(parsed)
      File "/home/arch/.local/lib/python3.10/site-packages/twitchio/websocket.py", line 488, in _cache_add
        self._cache[channel].discard(user)
      File "/home/arch/.local/lib/python3.10/site-packages/twitchio/chatter.py", line 56, in __hash__
        return hash(self.name + self.channel.name)
    TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
    

    When I fetch the same users as the initial channels

    UAT = "some token"
    user = "user"
    class Bot(commands.Bot):
        def __init__(self):
            super().__init__(
                token=UAT,
                prefix="!",
                initial_channels=[user]
            )
        async def __ainit__(self):
            users = await self.fetch_users([user])
    bot = Bot()
    bot.loop.run_until_complete(bot.__ainit__())
    bot.run()
    
    bug IRC 2.0 
    opened by preeded 9
  • content not included on Message documentation.

    content not included on Message documentation.

    If you view the Message documentation seen here: https://twitchio.readthedocs.io/en/latest/reference.html#message their is no reference to the content instance variable. Is this intended? Definition of content on Message data class: https://github.com/TwitchIO/TwitchIO/blob/master/twitchio/message.py

    opened by ssmele 9
  • Sending Whisper Response to User

    Sending Whisper Response to User

    I am fairly new at playing with twitchio, so this is my first time building a bot with this library. Currently using: twitchio==2.1.3

    With that being said, I am trying to respond to chat based on two cases:

    1. Chat messages
    2. Whispers

    For example, if a user in chat says "Hello there bot" I have my bot responding with "Hello there {user}". However, if someone whispers the bot with the same style of text, I want the bot to whisper back to the user the same response.

    I can't seem to get the whisper part working...

    Here is my code that handles the event_message():

    async def event_message(self, message: Message) -> None:
    
            if message.echo:
                return
            
            new_message = message.content.__str__().lower()
            print(new_message)
            author = message.author.name
            print(author)
    
            await self.handle_commands(message)
    
            # check to see if someone chats/whispers a message that contains "hello"
            if "hello" in new_message:
                # check to see if message is from chat or whisper
                response = f"Hello there {author}"
                try:
                    print("Came from channel")
                    await message.channel.send(response)
                except:
                    print("Came from whisper")
                    ws = message.author._ws
                    whisper_resp = f"PRIVMSG #jtv :/w {message.author.channel} {response}\r\n"
                    await ws.send(whisper_resp)
                    #await message.author.send(response)
            
            return await super().event_message(message)
    

    The output I get is like so:

    PS C:\Programming\TwitchBot> python .\bot.py
    console_log: mybot is online!
    hello there from chat
    some_twitch_username
    Came from channel
    hello there from whisper
    some_twitch_username
    Came from channel ---> ignore this line (it is printing in the try statement before it errors out and falls to exception)
    Came from whisper
    

    In my except clause, I have tried every portion of the following:

    except:
            print("Came from whisper")
            ws = message.author._ws
            whisper_resp = f"PRIVMSG #jtv :/w {message.author.channel} {response}\r\n"
            await ws.send(whisper_resp)
            #await message.author.send(response)
    

    But neither of those error or send a whisper back. I tried checking the documentation but didn't really find anything pertaining to my scenario.

    Any help is appreciated! Thanks!

    opened by jbmcfarlin31 9
  • TimeoutError in Client.join_channels causes unhandled exception

    TimeoutError in Client.join_channels causes unhandled exception

    If Client.join_channels is called and a TimeoutError occurs while trying to join a channel, then an unhandled exception will be raised when this channel is removed from the _initial_channels list, because the channel is not an initial channel, but one passed in via join_channels.

    Traceback (most recent call last):
      File "/home/chill/.cache/pypoetry/virtualenvs/timedoutbot-5LVMUk6d-py3.7/lib/python3.7/site-packages/twitchio/websocket.py", line 265, in _join_future_handle
        await asyncio.wait_for(fut, timeout=10)
      File "/home/chill/.pyenv/versions/3.7.1/lib/python3.7/asyncio/tasks.py", line 423, in wait_for
        raise futures.TimeoutError()
    concurrent.futures._base.TimeoutError
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/chill/.cache/pypoetry/virtualenvs/timedoutbot-5LVMUk6d-py3.7/lib/python3.7/site-packages/twitchio/websocket.py", line 275, in _join_future_handle
        await self._process_data(data)
      File "/home/chill/.cache/pypoetry/virtualenvs/timedoutbot-5LVMUk6d-py3.7/lib/python3.7/site-packages/twitchio/websocket.py", line 284, in _process_data
        return await self._code(parsed, parsed["code"])
      File "/home/chill/.cache/pypoetry/virtualenvs/timedoutbot-5LVMUk6d-py3.7/lib/python3.7/site-packages/twitchio/websocket.py", line 321, in _code
        self._initial_channels.remove(parsed["batches"][0])
    ValueError: list.remove(x): x not in list
    
    bug IRC 2.0 
    opened by SamChill 9
  • Message._timestamp not set on commands that exist

    Message._timestamp not set on commands that exist

    Describe the bug When running a command that exists, it seems the Message._timestamp attribute doesn't exist

    Are you using TwitchIO within a Discord Bot? No

    What commit of TwitchIO are you using? 0.0.4a295+665c7ce

    To Reproduce Steps to reproduce the behaviour:

    1. Create a bot with cogs/modules
    2. Create a function in the Bot class event_message
    3. Put some way to show the timestamp of every message (print(message.timestamp))
    4. Run the bot
    5. Run a command that doesn't exist -> get timestamp
    6. Run a command that does exist -> get error

    Expected behaviour Have timestamp set on every message, no matter what.

    Screenshots

    (please complete the following information):

    • OS: Windows 10 64bit

    Additional context

    future: <Task finished coro=<Bot.event_message() done, defined at .\bot.py:54> exception=AttributeError('_timestamp')>
    Traceback (most recent call last):
      File ".\bot.py", line 57, in event_message
        timestamp = message.timestamp
      File "D:\Personal\Resilio Sync\My Files\twitch_bot\env\lib\site-packages\twitchio\dataclasses.py", line 88, in timestamp
        timestamp = datetime.datetime.utcfromtimestamp(self._timestamp/1000)
    AttributeError: _timestamp
    
    bug IRC 
    opened by bsquidwrd 9
  • Added fetch_channel_emotes & fetch_global_emotes methods

    Added fetch_channel_emotes & fetch_global_emotes methods

    Pull request summary

    Adding Channel and Global emotes API to fetch emotes.

    • Added ChannelEmote and GlobalEmote model class
    • Added get_channel_emotes & get_global_emotes to TwitchHTTP
    • Added fetch_channel_emotes & fetch_global_emotes to Client

    Checklist

    • [x] If code changes were made then they have been tested.
      • [ ] I have updated the documentation to reflect the changes.
      • [ ] I have updated the changelog with a quick recap of my changes.
    • [ ] This PR fixes an issue.
    • [x] This PR adds something new (e.g. new method or parameters).
    • [ ] This PR is a breaking change (e.g. methods or parameters removed/renamed)
    • [ ] This PR is not a code change (e.g. documentation, README, ...)
    opened by ZebcoWeb 8
  • SSL errors with id.twitch.tv

    SSL errors with id.twitch.tv

    The underlying exception seems to be:

    aiohttp.client_exceptions.ClientConnectorCertificateError: Cannot connect to host id.twitch.tv:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)')]
    

    For some reason twitchio won't work for me anymore due to SSL errors. Is this on Twitch's end? Is it an issue in aiohttp that can't be addressed in twitchio? Or is it just a configuration on my end? This previously worked fine then stopped after my latest OS update to macOS Monterey 12.2.1 so perhaps that's the culprit.

    opened by danzek 8
  • (2.x) Whisper

    (2.x) Whisper

    Hello! 🙋🏻‍♂️

    Would it be possible to provide a way to send a whisper message for an user? Something like:

    async def reply_as_whisper(ctx):
       await ctx.whisper("username", "The message content.")
    

    I came from tmi (whisper implementation) and this is a feature that I miss. I don't know if this information is relevant but, to use the whisper feature, it is first necessary to verify the bot through this Twitch form.

    Thanks for this library and for all abstraction provided.

    opened by rn4n 7
  • Modify create_prediction()

    Modify create_prediction()

    Pull request summary

    The list outcomes must contain a minimum of 2 choices and up to a maximum of 10 choices.

    Checklist

    • [x] If code changes were made then they have been tested.
      • [x] I have updated the documentation to reflect the changes.
      • [ ] I have updated the changelog with a quick recap of my changes.
    • [x] This PR fixes an issue.
    • [ ] This PR adds something new (e.g. new method or parameters).
    • [x] This PR is a breaking change (e.g. methods or parameters removed/renamed)
    • [ ] This PR is not a code change (e.g. documentation, README, ...)
    HTTP Breaking Change 2.0 
    opened by Xakka 1
  • Get Streams API Bug

    Get Streams API Bug

    Issues

    Background: I wanted to get top live streams by chosen languages.

    Issues I encountered:

    1. In TwitchHTTP class function get_streams does not provide type parameter (link).

      As said in twitch dev reference Get streams have parameter type:

      The type of stream to filter the list of streams by. Possible values are: all, live.
      The default is all.
      
    2. In Client fetch_streams function also does not have type parameter, but also introduce assert user_ids or game_ids or user_logins (link). This assert prohibits use of only languages parameter and none of parameters while twitch API allows that behavior.

    Possible solution

    1. Add type: Optional[Literal["all", "live"]] = None to both Client.fetch_streams and TwitchHTTP.get_streams as argument.
    2. Remove assert from Client.fetch_streams.
    bug HTTP 2.0 
    opened by sabal202 1
  • fix: auto-reconnect websocket/bot

    fix: auto-reconnect websocket/bot

    Pull request summary

    Twitch bot did not relogged automatically. The tasks which are created by asyncio.create_task() need to be collected to prevent task disappearing, see: https://docs.python.org/3/library/asyncio-task.html#creating-tasks

    Important: Save a reference to the tasks, to avoid a task disappearing mid-execution.

    Fixed disappearing of tasks by collecting and deleteing them within a defined cycle. With this fix, the websocket will reconnect automatically as intended.

    Checklist

    • [x] If code changes were made then they have been tested.
      • [ ] I have updated the documentation to reflect the changes.
      • [x] I have updated the changelog with a quick recap of my changes.
    • [x] This PR fixes an issue.
    • [ ] This PR adds something new (e.g. new method or parameters).
    • [ ] This PR is a breaking change (e.g. methods or parameters removed/renamed)
    • [ ] This PR is not a code change (e.g. documentation, README, ...)
    bug IRC 2.0 
    opened by TutorExilius 6
  • Enable command groups

    Enable command groups

    Pull request summary

    Re-enable command groups and fix the bug where a command could be called from outside of its group

    Checklist

    • [x] If code changes were made then they have been tested.
      • [ ] I have updated the documentation to reflect the changes.
      • [ ] I have updated the changelog with a quick recap of my changes.
    • [ ] This PR fixes an issue.
    • [x] This PR adds something new (e.g. new method or parameters).
    • [ ] This PR is a breaking change (e.g. methods or parameters removed/renamed)
    • [ ] This PR is not a code change (e.g. documentation, README, ...)
    new feature 2.0 EXT: commands 
    opened by broenn 1
  • Specify the maximum number of elements per page each endpoint can return.

    Specify the maximum number of elements per page each endpoint can return.

    General warning

    Note: This PR is the first step in my desire to provide a way for the user to request a specific number of result on endpoint allowing pagination, as discussed with several developers on Discord and completing the work previosuly started in #276 (and thus use the internal pagination of the request function, which is currently not used by high-level functions!). This feature is not implemented in this PR.

    However, the features implemented in this PR can be considered independent and already offer new cool stuff, so I propose it for review.

    In this PR, I make a difference between the first parameter, which is the parameter sent to Twitch API when performing the HTTP request, and the first argument exposed by some methods as User.fetch_pools()

    Changes

    In the current version of TwitchIO, the number of elements requested to endpoints when pagination is enabled is 100 by default, this is set by the get_limit() subfunction:

    def get_limit():
        if limit is None:
            return "100"
        to_get = limit - len(data)
        return str(to_get) if to_get < 100 else "100"
    

    This leads to two main issues:

    • For endpoints where the maximum value allowed for firstis less than 100, we have to do a little trick by adding a "first" parameter when calling the fetch_ method, this is currently the case for 4 methods: get_reward_redemptions, get_polls, get_predictions, get_channel_schedule. These functions are the ONLY functions exposing a first parameter. All the other ones suppose by default that first=100 due to the get_limit() function.
    • For endpoints allowing higher values than 100, you will receive 100 data and no more. Endpoints like entitlements/drops allows 1000 results per page.

    This PR fix all of this by specifying the maximum value allowed by first when requesting the endpoint. This is done by adding a new parameter, max_elements_per_page to the request() method, containing this information.

    Below, I listed all endpoint using the "first" parameter, with their min, default and max value. For each endpoint, the value of the max_elements_per_page argument is the maximum value allowed to first by the documentation.

    | Method | Endpoint | min | default | max | Implemented in TwitchIO | |--------|-------------------------------------------|-----|---------|------|----------------------------| | GET | analytics/extensions | 1 | 20 | 100 | X | | GET | analytics/games | 1 | 20 | 100 | X | | GET | extensions/transactions | 1 | 20 | 100 | get_extension_transactions | | GET | channel_points/custom_rewards/redemptions | 1 | 20 | 50 | get_reward_redemptions | | GET | chat/chatters | 1 | 100 | 1000 | X, BETA | | GET | clips | 1 | 20 | 100 | get_clips | | GET | entitlements/drops | 1 | 20 | 1000 | get_entitlements | | GET | extensions/live | 1 | 20 | 100 | X | | GET | games/top | 1 | 20 | 100 | get_top_games | | GET | hypetrain/events | 1 | 1 | 100 | get_hype_train | | GET | moderation/banned | 1 | 20 | 100 | get_channel_bans | | GET | moderation/blocked_terms | 1 | 20 | 100 | X | | GET | moderation/moderators | 1 | 20 | 100 | get_channel_moderators | | GET | channels/vips | 1 | 20 | 100 | get_channel_vips | | GET | polls | 1 | 20 | 20 | get_polls | | GET | predictions | 1 | 20 | 25 | get_predictions | | GET | schedule | 1 | 20 | 25 | get_channel_schedule | | GET | search/categories | 1 | 20 | 100 | get_search_categories | | GET | search/channels | 1 | 20 | 100 | get_search_channels | | GET | soundtrack/playlist | 1 | 20 | 50 | X | | GET | soundtrack/playlists | 1 | 20 | 50 | X | | GET | streams | 1 | 20 | 100 | get_streams | | GET | streams/followed | 1 | 100 | 100 | X | | GET | streams/markers | 1 | 20 | 100 | get_stream_markers | | GET | subscriptions | 1 | 20 | 100 | get_channel_subscriptions | | GET | tags/streams | 1 | 20 | 100 | get_stream_tags | | GET | users/follows | 1 | 20 | 100 | get_user_follows | | GET | users/blocks | 1 | 20 | 100 | X | | GET | videos | 1 | 20 | 100 | get_videos |

    (Note that for /videos, we can specify first parameter only if we specify the game_id or user_id query parameter. This condition has been implemented in this PR)

    In fetch_ methods exposing a first argument, it has been rerouted to the limit attribute of request() to avoid any breaking change.

    Moreover, the following functions:

    • get_predictions
    • get_channel_schedule
    • get_polls

    Can implement pagination, but were delivered with pagination=False. Activate the pagination in these functions doesn't change or break anything and allow them to benefit from this PR. So I did it.

    Finally, I disabled the assertion breaking the request when full_body was True as the same time as paginate, since the body is returned before the evaluation of paginate. This will prevent any futher bug in the future.

    I tested all helix endpoints with both app token and user token to validate this PR.

    Checklist

    • [X] If code changes were made then they have been tested.
      • [X] I have updated the documentation to reflect the changes.
      • [X] I have updated the changelog with a quick recap of my changes.
    • [ ] This PR fixes an issue.
    • [X] This PR adds something new (e.g. new method or parameters).
    • [ ] This PR is a breaking change (e.g. methods or parameters removed/renamed)
    • [ ] This PR is not a code change (e.g. documentation, README, ...)
    opened by graille 0
  • player.play() doesn't correctly handle sound files with non-default format

    player.play() doesn't correctly handle sound files with non-default format

    I'm trying to use the new Sounds ext, and I have noticed that playing mp3 files with only one channel produces weird result - I'd say the file is played at 2x speed, or the pitch is shifted up. Converting the file to stereo fixes the issue.

    MediaInfo output for mono file:

    General
    Complete name                            : Minion General [email protected]@ForMe01.mp3
    Format                                   : MPEG Audio
    File size                                : 25.3 KiB
    Duration                                 : 1 s 619 ms
    Overall bit rate mode                    : Constant
    Overall bit rate                         : 128 kb/s
    Genre                                    : Other
    
    Audio
    Format                                   : MPEG Audio
    Format version                           : Version 1
    Format profile                           : Layer 3
    Duration                                 : 1 s 620 ms
    Bit rate mode                            : Constant
    Bit rate                                 : 128 kb/s
    Channel(s)                               : 1 channel
    Sampling rate                            : 44.1 kHz
    Frame rate                               : 38.281 FPS (1152 SPF)
    Compression mode                         : Lossy
    Stream size                              : 25.3 KiB (100%)
    

    MediaInfo output for stereo file:

    General
    Complete name                            : Minion General [email protected]@ForMe01.mp3
    Format                                   : MPEG Audio
    File size                                : 26.0 KiB
    Duration                                 : 1 s 645 ms
    Overall bit rate mode                    : Constant
    Overall bit rate                         : 128 kb/s
    Genre                                    : Other
    Writing library                          : LAME3.100
    
    Audio
    Format                                   : MPEG Audio
    Format version                           : Version 1
    Format profile                           : Layer 3
    Format settings                          : Joint stereo / MS Stereo
    Duration                                 : 1 s 646 ms
    Bit rate mode                            : Constant
    Bit rate                                 : 128 kb/s
    Channel(s)                               : 2 channels
    Sampling rate                            : 44.1 kHz
    Frame rate                               : 38.281 FPS (1152 SPF)
    Compression mode                         : Lossy
    Stream size                              : 25.7 KiB (99%)
    Writing library                          : LAME3.100
    
    2.0 EXT: sounds 
    opened by iarspider 3
Releases(v2.5.0)
  • v2.5.0(Oct 31, 2022)

  • v2.4.0(Aug 6, 2022)

    TwitchIO 2.4 brings a huge set of changes! We've implemented new endpoints, squashed tons of bugs, and fixed up the eventsub ext.

    Here's some bug fixes:

    • Added self.registered_callbacks = {} to Client.from_client_credentials
    • Allow empty or missing initial_channels to trigger Client.event_ready
    • Corrected CustomRewardRedemption.fulfill endpoint typo and creation
    • Corrected CustomRewardRedemption.refund endpoint typo and creation
    • Changed Client.join_channels logic to handle bigger channel lists better
    • Corrected Predictor slots and user keys, repr has also been added
    • Updated IRC parser to not strip colons from beginning of messages
    • Updated IRC parser to not remove multiple spaces when clumped together
    • Fixed Client.start exiting immediately (YES, this means Client.start works properly now!)
    • Chatters will now update correctly when someone leaves chat
    • Fixed a crash when twitch sends a RECONNECT notice

    We've added all the moderation endpoints, the new send_whisper endpoint (although this isn't very reliable, just like normal whispers). Added Client.fetch_channels to allow fetching of more than one channel with a single API call.

    Eventsub ext:

    • Added "Gift Subscriptions" subscriptions for gifting other users Subs
    • Added Re-subscription Message subscriptions for Resub messages
    • Added EventSubClient.delete_all_active_subscriptions for convenience
    • Created an Eventsub-specific CustomReward model

    And more!

    As always, check out the full changelist at https://twitchio.dev/en/latest/changelog.html

    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(May 27, 2022)

    We've revamped our documentation, check out https://twitchio.dev/en/latest/changelog.html for the full changelog.

    A few key highlights of this release:

    • Added retain_cache kwarg to Client and Bot. Default is True.
    • Added support for poll endpoints
    • fixed some bugs related to initial_channels
    • fixed the issues with ext.commands cooldown buckets always using the global bucket
    • fixed an issue with ext.commands.Bot.reload_module failing to reinstate the old module if an error occurred while reloading
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Mar 6, 2022)

    Version 2.2.0

    2.2.0 brings some exciting new features to TwitchIO, along with our usual span of bugfixes. The full changelog can be found at https://twitchio.dev, but here's some highlights:

    • more eventsub models! channel polls and predictions have both been implemented
    • more pubsub models! channel subscriptions are now covered by pubsub
    • Fixed pagination logic! This means that requests that ask for more than the default limit will now actually receive those extra responses
    • aiohttp requirements have been relaxed to include 3.8.1
    • And more! see the changelog for all the changes
    Source code(tar.gz)
    Source code(zip)
  • v2.1.5(Feb 14, 2022)

  • v2.1.4(Dec 16, 2021)

    2.1.4

    • TwitchIO

      • Chatter.is_mod now uses name instead of display_name
      • Added ChannelInfo to slots
      • Remove loop= parameter for asyncio.Event in websocket for 3.10 compatibility
    • ext.eventsub

      • ChannelCheerData now returns user if is_anonymous is False else None
    Source code(tar.gz)
    Source code(zip)
  • v2.1.3(Nov 29, 2021)

    2.1.3

    • Twitchio

      • Fix bug where chatter never checked for founder in is_subscriber
      • Fix rewards model so it can now handle pubsub and helix callbacks
    • ext.commands

      • Fix TypeError in Bot.from_client_credentials
    • GitHub Workflows

      • Added automatic version handling via release tag.
      • Added TwitchIO Manager bot
    Source code(tar.gz)
    Source code(zip)
  • v2.1.2(Nov 8, 2021)

    • Add Chatter.mention
    • Re-add raw_usernotice from V1.x
    • Fix echo messages for replies
    • Fix a bug where the wrong user would be whispered
    • Fix a bug inside User.modify_stream where the game_id key would be specified as "None" if not provided (GH#237)
    • Add support for teams and channelteams API routes
      • Team, ChannelTeams
      • Client.fetch_teams
      • PartialUser.fetch_channel_teams
    • Fix issue where Bot.from_client_credentials would result in an inoperable Bot instance (GH#239)
    • Added ext.pubsub.Websocket.pubsub_error to support being notified of pubsub errors
    • Added ext.pubsub.Websocket.pubsub_nonce to support being notified of pubsub nonces
    • Patch 2.1.1 bug which breaks library on 3.7 for ext.eventsub
    Source code(tar.gz)
    Source code(zip)
  • v2.1.1(Oct 31, 2021)

  • v2.1.0(Oct 28, 2021)

    This release brings a whole load of changes, please check the changelog on https://twitchio.readthedocs.org for a full list.

    Major changes for this release include:

    • Added the raw_usernotice event
    • Added support for the predictions API
    • added support for the schedules API
    • Update the library to use the iso8601 library to parse timestamps
    • fix Client.wait_for causing asyncio.InvalidState errors
    • fix bug in ext.pubsub where Pool.unsubscribe_topics would error out due to an error
    • fix bug in ext.eventsub where the ChannelBanData model would attempt to access nonexistent attributes from the event payload
    Source code(tar.gz)
    Source code(zip)
  • v2.0.6(Aug 27, 2021)

  • v2.0.5(Jul 28, 2021)

  • v2.0.4(Jul 28, 2021)

  • v2.0.3(Jul 27, 2021)

    Small bug fixes:

    • Fix a bug in search_channels resulting in a key error when creating users.
    • Added eventsub package to setup.py.
    • Stop echo messages from triggering commands by default.
    Source code(tar.gz)
    Source code(zip)
  • v2.0.2(Jul 20, 2021)

    Add an additional optional bool argument to routines, wait_first which waits the specified amount of hours, minutes or seconds before starting the first iteration. Does not have any effect when the time argument is passed. Defaults to False.

    Source code(tar.gz)
    Source code(zip)
  • v2.0.1(Jul 20, 2021)

  • v2.0.0(Jul 16, 2021)

  • v1.2.3(Apr 13, 2021)

  • v1.2.2(Mar 3, 2021)

  • 1.2.1(Jan 11, 2021)

Owner
TwitchIO
Organisation for the TwitchIO Lib
TwitchIO
Properly-formatted dynamic timestamps for Discord messages

discord-timestamps discord-timestamps generates properly-formatted dynamic timestamps for Discord messages, with support for Arrow objects. format

Ben Soyka 2 Mar 10, 2022
Easy & powerful bot to check if your all Telegram bots are working or not

Easy & powerful bot to check if your all Telegram bots are working or not. This bot status bot updates every 105 minutes & runs for 24x7 hours.

35 Dec 30, 2022
Make low level API wrapper in fast, easy.

The lowrapper is a library for quickly and easily creating an environment for tapping the API without implementation.

tasuren 1 Oct 25, 2022
This discord bot preview user 42intra login picture.

42intra_Pic BOT This discord bot preview user 42intra login picture. created by: @YOPI#8626 Using: Python 3.9 (64-bit) (You don't need 3.9 but some fu

Zakaria Yacoubi 7 Mar 22, 2022
This is a script to forward forward large number of documents to another telegram channel.

ChannelForward 😇 This is a Script to Forward Large Number of Documents to Another Telegram Channel. If You Try to Forward Very Large Number of Files

Anjana Madushanka 10 Jun 08, 2021
Clisd.py - UI framework with client side rendering for python

clisd.py Clisd is UI framework with client side rendering for python. It uses WA

2 Mar 25, 2022
Twitter bot code can be found in twitterBotAPI.py

NN Twitter Bot This github repository is BASED and is yanderedev levels of spaghetti Neural net code can be found in alexnet.py. Despite the name, it

167 Dec 19, 2022
Reverse engineering the dengue virus (under development construction)

Reverse engineering the dengue virus (under development 🚧 ) What is dengue? Dengue is a viral infection transmitted to humans through the bite of inf

kjain 4 Feb 09, 2022
This Instagram app created as a clone of instagram.Developed during Moringa Core.

Instagram This Instagram app created as a clone of instagram.Developed during Moringa Core. AUTHOR By: Nyagah Isaac Description This web-app allows a

Nyagah Isaac 1 Nov 01, 2021
Use Node JS Keywords In Python!!!

Use Node JS Keywords In Python!!!

Sancho Godinho 1 Oct 23, 2021
Telegram Group Calls Streaming bot with some useful features, written in Python with Pyrogram and Py-Tgcalls. Supporting platforms like Youtube, Spotify, Resso, AppleMusic, Soundcloud and M3u8 Links.

Yukki Music Bot Yukki Music Bot is a Powerful Telegram Music+Video Bot written in Python using Pyrogram and Py-Tgcalls by which you can stream songs,

Team Yukki 996 Dec 28, 2022
A Bot Telegram Anti Users Channel to automatic ban users who using channel to send message in group.

Tg_Anti_UsersChannel A Bot Telegram Anti Users Channel to automatic ban users who using channel to send message in group. Features: Automatic ban Whit

idzeroid 6 Dec 26, 2021
An instagram bot developed in Python with Selenium that helps you get more Instagram followers.

instabot An instagram bot developed in Python with Selenium that helps you get more Instagram followers. Install You’ll need to have: Python Selenium

65 Nov 22, 2022
This package allows interactions with the BuyCoins API.

The BuyCoins Python library allows interactions with the BuyCoins API from applications written in Python.

Abdulazeez Abdulazeez Adeshina 45 May 23, 2022
A bot that is an updated & modified version of calvinnfernando's WebReg-Bot

WaitList-Bot A bot that is an updated & modified version of calvinnfernando's WebReg-Bot to automate getting into waitlisted classes in UCSD WebReg on

Issac In 1 Dec 01, 2022
Osmopy - osmo python client library

osmopy Version 0.0.2 Tools for Osmosis wallet management and offline transaction

5 May 22, 2022
Discord Bot for SurPath Hub's server

Dayong Dayong is dedicated to helping Discord servers build and manage their communities. Multipurpose —lots of features, lots of automation. Self-hos

SurPath Hub 6 Dec 18, 2021
HTTP API for TON (The Open Network)

HTTP API for The Open Network Since TON nodes uses its own ADNL binary transport protocol, a intermediate service is needed for an HTTP connection. TO

66 Dec 28, 2022
Weather_besac is a French twitter bot that tweet the weather of the city of Besançon in Franche-Comté in France every day at 8am and 4pm.

Weather Bot Besac Weather_besac is a French twitter bot that tweet the weather of the city of Besançon in Franche-Comté in France every day at 8am and

Rgld_ 1 Nov 15, 2021
Python client for the Socrata Open Data API

sodapy sodapy is a python client for the Socrata Open Data API. Installation You can install with pip install sodapy. If you want to install from sour

Cristina 368 Dec 09, 2022