FAQ

Frequently asked Questions

How do I send a message to a specific channel?

To send a message to a specific channel/broadcaster you should use send_message() on PartialUser. You can create a PartialUser with only the users ID with create_partialuser() on Client or Bot.

user = bot.create_partialuser(id="...")
await user.send_message(sender=bot.user, message="Hello World!")

If you are inside of a Command, consider using the available Context instead.

Why was IRC functionality removed from the core library?

Twitch has started recommending developers use EventSub in-place of IRC for Chat Bots.

IRC (especially the Twitch version; which doesn’t adhere strictly to the RFC) can be complicated to parse, and ultimately offers a less stable and less performant interface to interact with chat. On top of this Twitch has recently started adding more and more restrictions to IRC Chat Bots (including harsher ratelimits on JOINs and Sends).

Most applications will use EventSub already for various other subscriptions, and adding chat/messages on top of this is a straight forward and easy process. The benefits to developers is TwitchIO does less parsing of raw, (undocumented in a lot of cases) strings and can now easily create usable, sane objects from JSON sent over either websocket or webhook; this means less bugs, and less maintenance.

While indeed there is a small discrepancy between features of EventSub messages and IRC messages, the overall experience is more performant and easier to use. Twitch is also actively working on adding more data to these message payloads, and when they do, there will be a faster and easier turn-around for this data to be added into the library.

In the future, we are looking to devlop an ext that will run IRC, however the core lib going forward will stay with EventSub.

What is the difference between Client and Bot?

twitchio.ext.commands.Bot subclasses Client, which means that everything Client can do, and everything belonging to Client is also possible and available on Bot.

The benefit of Bot is that it is part of the ext.commands extension. This extension is a powerful and easy to use package that allows the creation of Command’s’ and Component’s which allow you to easily create chat based commands and sub-commands, with argument parsing and converters, guards for fine-grained permission control, cooldowns, the use of Context (featureful context around the invocation of commands; with many helpers) and more.

Used with Component’s and hot-reloading extension support you can easily manage your applications codebase with multiple modules and/or pacakges, with minimal down-time.

Why does TwitchIO use PartialUser in-place of a full User object?

The large majority of both Helix endpoints and EventSub subscriptions from Twitch only send partial data relating to the user.

Creating a complete User on all these events and endpoints would mean making an extra HTTP request, which is both needlessly slow and consumes ratelimit tokens.

Since Twitch only requires the ID of users to perform actions and make requests, PartialUser is an inexpensive way of having an object that can perform actions for or against the user. However if you need extra data about the user (such as profile image) you can always fetch the full data via twitchio.PartialUser.user(). Since the User subclasses PartialUser, all the methods available on PartialUser are also available on User.

You can also create a PartialUser with create_partialuser().

If you are using Command’s or anywhere Context is available, or are receiving a ChatMessage, consider looking at Chatter for a more complete object with more information and helpers.

How do I get the user IDs for BOT_ID and OWNER_ID?

If you do not know your user ID you can quickly fetch it using the fetch_users() method.

import asyncio
import twitchio

CLIENT_ID: str = "..."
CLIENT_SECRET: str = "..."

async def main() -> None:
    async with twitchio.Client(client_id=CLIENT_ID, client_secret=CLIENT_SECRET) as client:
        await client.login()
        user = await client.fetch_users(logins=["chillymosh", "my_bot"])
        for u in user:
            print(f"User: {u.name} - ID: {u.id}")

if __name__ == "__main__":
    asyncio.run(main())

How do I create a custom prefix(es) for Bot/AutoBot

Bot and AutoBot both allow a custom co-routine to be used to determine the prefix for Chat Commands. This coroutine can be used to assign prefixes based on channel, chatter or other variables. A small example is shown below:

from typing import Self

import twitchio
from twitchio.ext import commands

class Bot(commands.Bot):
    def __init__(self) -> None:
        super().__init__(..., prefix=self.custom_prefix)

    async def custom_prefix(self, bot: Self, message: twitchio.ChatMessage) -> None:
        # The prefix will be ? if the chatters name startswith "cool"
        # Otherwise it will default to "!"
        # This coroutine can be used to connect to a cache or database etc to provide
        # custom settable prefixes for example...

        if message.chatter.name.startswith("cool"):
            return "?"

        return "!"

The prefix can also be passed as or returned from this function as a list of str to allow multiple prefixes to be used.

Why do my tokens in .tio.tokens.json occasionally go missing?

This is usually caused by force closing the client while it is attempting to write to the file. If you use Ctrl + C to close your client, make sure you only do this once, and wait for up to 5 seconds.

Alternatively, and highly recommended, you should look at storing your tokens in a different medium, such as a SQL Database.

What is the default redirect URL for oauth?

The default redirect url to be provided in your Twitch Developer Console is http://localhost:4343/oauth/callback

Keep in mind that this should be adjusted if you change the address, port or use a custom domain with your adapter.