Guides & Help

Installation

TwitchPy only uses python standard libraries and shouldn’t need you to install anything else.

Because TwitchPy is not a PyPi package, you should use:

pip install git+https://github.com/rexosorous/TwitchPy

Registering a Bot With Twitch

You can follow this guide: https://dev.twitch.tv/docs/authentication/#registration or any other countless guides on the internet to register your bot with twitch. Just make sure to save your bot’s username, client ID, and OAuth token.

Your First Bot

Now that you’ve registered a bot on twitch and gotten all the login credentials, we can build our first bot!

from TwitchPy import TwitchBot

login = {   "token": "your auth token",
            "user": "your bot name",
            "client_id": "the bot's client ID",
            "channel": "the channel to connect to"
}

bot = TwitchBot.Client(**login)
bot.run()

This is the minimal amount of effort you need to run a bot without any errors - we’ve created an instance of TwitchPy.TwitchBot.Client() and passed it our login information. Right now, we haven’t programmed in any features so the bot doesn’t do anything but sit in twitch chat.

In this example, we’ve hardcoded in our login credentials, but you may want to avoid doing this if you’re going to make your source code publicly available (like if you’re going to have a public git repo for it).

From here, we can start adding in some or all of TwitchPy’s features.

Creating Commands

Quickstart

To set up your own commands, TwitchPy requires you to create a class that inherits from TwitchPy.Commands.Cog and use @Commands.create() to create your commands.

Here’s a basic example:

from TwitchPy import TwitchBot, Commands

class MyCommands(Commands.Cog):         # make sure to inherit Commands.Cog
    def __init__(self, IRC):
        super().__init__(prefix='!')    # calling Commands.Cog's init is required!
        self.IRC = IRC                  # obtained from TwitchBot.Client so we can interact with chat

    @Commands.create()                  # decorator used to create the command
    async def ping(self, ctx):         # the function must take one argument: chat
        await self.IRC.send('pong')

bot = TwitchBot.Client(**login)
my_commands = MyCommands(bot.get_IRC())
bot.add_cogs(my_commands)                # don't forget to add the cog to the bot
bot.run()

Let’s break this down.

class MyCommands(Commands.Cog): - If you want to create your own commands, TwitchPy requires you to create a class that inherits from TwitchPy.Commands.Cog.

super().__init__(prefix='!) - You have to call TwitchPy.Commands.Cog’s init function which only has one argument. prefix is the part of the message at the beginning that let’s the bot know that the message is meant for it.

self.IRC = IRC - IRC is received from TwitchPy.TwitchBot.Client.get_IRC() and is an instance of TwitchPy.Websocket.IRC which is how you’ll be interacting and sending messages to twitch chat. For more information on this, check out Interacting With IRC.

@Commands.create() - A function decorator that creates commands and should precede every command function.

async def ping(self, ctx): - Command functions must be asynchronous (async) and accept only one argument, ctx , which is an instance of TwitchPy.ChatInfo.Chat which contains all the information about the message sent. You can access that information via its attributes which can be found in the references.

await self.IRC.send('pong') - TwitchPy.Websocket.IRC.send() is an asynchronous function and must be await ed. In this case, this function sends ‘pong’ to twitch chat.

bot.add_cogs(my_commmands) - After creating an instance of your command class, you have to add it to the bot via TwitchPy.Client.add_cogs().

With this we’ve created a bot with a command cog that uses the prefix ‘!’ and has one command called ‘ping’ that causes the bot to reply in chat with ‘pong’. So whenever a viewer types in chat ‘!ping’, the bot will say ‘pong’.

Naming Commands

In the last example, the bot used the function name as the command name, but that doesn’t have to be the case. TwitchPy.Commmands.create() has a kwarg field, name, which you can use to separate the function name from the command name.

@Commands.create(name='hello')
async def say_hello(self, ctx):
    await self.IRC.send('HeyGuys')

This command is executed whenever a viewer says ‘!hello’ and won’t execute when a viewer says ‘!say_hello’.

name can also take a list of strings which allows you to create functions with several names.

@Commands.create(name=['hello', 'hi', 'howdy'])
async def say_hello(self, ctx):
    await self.IRC.send('HeyGuys')

Here’s the same command as before, but with multiple names. So now the command will execute whenever a viewer says ‘!hello’ or ‘!hi’ or ‘!howdy’.

Note

Command names with spaces in it should work, but this isn’t something we test for, so use at your own risk.

Using Arguments

If you want a command to expect some arguments, then all you have to do is add arguments to the function definition like you normally would.

@Commands.create(name='mock'):
async def mock_user(self, ctx, user):
    msg = get_last_message(user)    # not a TwitchPy function. assume this exists somewhere in the program.
    mocked_msg = ''
    for char in msg:
        if random.choice([True, False]):
            mocked_msg += char.upper()
        else:
            mocked_msg += char.lower()
    await self.IRC.send(mocked_msg)

Here we have a command to mock a user’s last message they sent in chat by randomizing the capitalization of each character. Because of the nature of the command, we need one argument user. So mock_user() will only get called if a viewer types in chat ‘!mock {user}’ and not if they type ‘!mock’ or ‘!mock lorem ipsum’.

If you’re unsure how many arguments a function might accept, you can use *args which will end up being a list of strings (each being an arg).

@Commands.create(name='mock'):
async def mock_msg(self, ctx, *args):
    msg = ' '.join(args)
    mocked_msg = ''
    for char in msg:
        if random.choice([True, False]):
            mocked_msg += char.upper()
        else:
            mocked_msg += char.lower()
    await self.IRC.send(mocked_msg)

This is a command that mocks an entire message. So given the input ‘!mock hello world’, the bot might respond with ‘hELLO WOrlD’. Because of *args this command will execute regardless of how many args we send it.

Notice that mock_user() and mock_msg() both create a command with the name ‘mock’. This is completely fine as long as they expect different amounts of args (not including *args) - mock_user() has an argcount of 1 while mock_msg() has an argcount of 0. So whenever the mock command is called with only one arg, then mock_user() is called and if there’s any other argcounts, then mock_msg() will be called. That is to say, commands with more args (not counting *args) are prioritized first.

Note

If two commands have the same name and argcount, only one will execute

Note

TwitchPy makes no effort to convert any args into other data types (like ints or floats).

Permissions

Lastly, TwitchPy.Commands.create() let’s you limit who is allowed to use a command with the kwargs permission and whitelist.

permission takes a string and sets a base level for who can use this command based on the viewers’ loyalty / affiliation. The hierarchy is: 'broadcaster' > 'moderator' > 'subscriber' > 'everyone'.

@Commands.create(permission='moderator')
async def checkfollower(self, ctx, user):
    isfollower = self.API.follows_me(user)
    await self.IRC.send(str(isfollower))

This is a command that checks if a user is a follower of the channel or not. Because we don’t want everyone to be able to use this command, we set permission='moderator' which means that only moderators and broadcasters (the streamer) can use this command. If anyone else tries to use this command, the function checkfollower() does not get called.

Whitelisting

The kwarg whitelist takes a list of strings with each element being a username of someone whom you explicitly want to be able to use the command.

@Commands.create(whitelist='someviewer')
async def VIP(self, ctx):
    await self.IRC.send('PogChamp s in chat for someviewer!')

This is a command that can only be used by someviewer. If anyone else tries to use it (even the broadcaster), the function VIP simply won’t be called.

Using Both Permission & Whitelisting

If both permission and whitelist are defined, the permission will take precedence over whitelist.

@Commands.create(permission='moderator', whitelist='someviewer')
async def AmISpecial(self, ctx):
    await self.IRC.send('yes')

This command can only be used by any moderator, any broadcaster, and any viewer named ‘someviewer’.

Using Multiple Cogs

For bigger and more complex bots, you may want to split up your commands amongst multiple cogs to better organize your code. For example, you may want one cog dedicated for commands that send a constant/static messsage.

class MainCommands(Commands.Cog)
def __init__(self, IRC):
    super().__init__(prefix='!')
    self.IRC = IRC

@Commands.create()
async def foo(self, ctx):
    do_bar()


class CopyPastaCommands(Commands.Cog)
def __init__(self, IRC):
    super().__init__(prefix='?')
    self.IRC = IRC

@Commands.create()
async def help(self, ctx):
    await self.IRC.send('help message')


bot = TwitchBot.Client(**login)
main = MainCommands(bot.get_IRC())
copypasta = CopyPastaCommands(bot.get_IRC())
bot.add_cogs([main, copypasta])
bot.run()

Here we have CopyPastaCommands that we are going to dedicate for commands that send a constant/static message. We can use TwitchPy.TwitchBot.Client.add_cogs() to send both cogs in a list instead of calling add_cogs() twice.

Notice that the cogs have different prefixes from each other. This is the only possible with multiple cogs. So now help() won’t be called if a viewer says ‘!help’, but only if they say ‘?help’ because the prefix is different.

Note

If multiple separate cogs have the same prefix and have commands with the same name(s) and argcounts, all of those command functions will be called when the command executed, not just one.

Interacting With IRC

Sending Messages

TwitchPy.Websocket.IRC is the class that handles the IRC connection and is responsible for connecting to a channel, reading twitch chat, and sending messages to twitch chat. Most of the class’ functions aren’t useful or available to you, but the one that you should know is TwitchPy.Websocket.IRC.send(msg) where msg is the message you want sent to twitch chat. Because this function is an async function, it should be awaited.

from TwitchPy import TwitchBot, Commands

class MyCommands(Commands.Cog)
    def __init__(self, IRC):
        super().__init__(prefix='!')
        self.IRC = IRC

    @Commands.create():
        async def ping(self, ctx):
            await self.IRC.send('pong')

bot = TwitchBot.Client(**login)
mycog = MyCommands(bot.get_IRC())
bot.add_cogs([mycog])
bot.run()

To obtain the instance of TwitchPy.Websocket.IRC that the bot uses, you can use TwitchPy.TwitchBot.Client.IRC to access the attribute directly or use a getter function TwitchPy.TwitchBot.Client.get_IRC(). Either works and is perfectly fine to use.

Receiving Messages

Whenever a message is received from twitch chat, TwitchPy will create an instance of TwitchPy.ChatInfo.Chat which contains all the information about that message. This is the ctx parameter that’s sent to any command functions you create. You can read about all the attributes you can access in references, but here’s a short rundown of the important bits.

field data type description
ctx.msg str the message received. this includes any command prefixes and command names.
ctx.arg_msg str the message without the command prefix and name.
ctx.args list of str ctx.arg_msg split by spaces.
ctx.author object an instance of TwitchPy.UserInfo.User
ctx.author.name str who sent the message.
ctx.author.id str the ID of the viewer who sent the message.
ctx.author.broadcaster bool whether or not the viewer is the broadcaster/streamer.
ctx.author.moderator bool whether or not the viewer is a moderator.
ctx.author.subscriber bool whether or not the viewer is a subscriber.
ctx.author.sub_length int how long the viewer has been a sub.
ctx.author.badges list of str what badges the viewer has.

Here’s an example that pings the user who calls the command ‘!pingme’:

@Commands.create():
    async def pingme(self, ctx):
        await self.IRC.send(f'@{ctx.user.name}')

Chat History

By default, TwitchPy will also keep a history of every chat message received (not messages sent by the bot) during its runtime. This history is stored in the attribute TwitchPy.Websocket.IRC.chat_history, which is a list of TwitchPy.ChatInfo.Chat instances. Newest message will be stored in the front (position 0) while the oldest message will be stored in the rear (the last position).

Because the chat history is stored in a list, you can iterate through it quite simply with a loop:

@Commands.create()
async def get_newest_message(self, ctx, viewer):
    # echoes the newest message sent by a viewer
    for chat in IRC.chat_history:
        if chat.user.name == viewer:
            await IRC.send(chat.msg)
            return

Note

TwitchPy will only save messages after command invocations (if there is one). So in the above example, IRC.chat_history[0] will not be ‘!get_newest_message someviewer’ until after get_newest_message() has finished executing.

In most cases, this shouldn’t use a noticeable amount of memory, but in case you have a very active chat or streaming games that demand a lot of memory, or just don’t have that much memory to begin with, you can limit the number of messages saved to cut down on memory usage with TwitchPy.TwitchBot.Client’s kwarg, chatlimit which takes an int. For example TwitchPy.TwitchBot.Client(**login, chatlimit=100) will only save 100 messages at a time. When the limit is reached and a new message comes in, the oldest message will be deleted to make room for the new one. If you didn’t want to save any messages, just set chatlimit to 0: TwitchPy.TwitchBot.Client(**login, chatlimit=0)

Working With Twitch’s API

TwitchPy.API.Helix is the class that handles any calls to twitch’s API endpoints. This is mainly used to get information on certain viewers and to figure out who is following you. To get the instance of this that the bot uses, you can access the attribute directly with TwitchPy.TwitchBot.Client.API or use a getter function like TwitchPy.TwitchBot.Client.get_API().

Here’s a quick rundown of TwitchPy.API.Helix’s functions.

function description
get_user_info(user: [str]) returns a dict with all the information about the user(s)
get_my_followers() get a list of all of your followers
follows_me(user_id: str) figure out if a user is following you
get_viewers() get a list of all of the people watching you

This isn’t everything and doesn’t go quite in depth on what these functions are returning or what parameters they’re looking for. So if you’re looking for more detailed explanations, take a look at the references.

Running Functions Concurrently

You may find yourself wanting to run some function in the background or alongside the bot’s normal functions. Like maybe you’d like the bot to say ‘Don’t forget to SMASH that subscribe button!!!’ every 10 minutes in chat. For that you can create an async function and pass it to TwitchPy.TwitchBot.Client.run() in a list.

from TwitchPy import TwitchBot
import asyncio

class MyBackgroundTask:
    def __init__(self, IRC):
        self.IRC = IRC

    async def smash_reminder(self):
        self.IRC.send('Don\'t forget to SMASH that subscribe button!!!')
        await asyncio.sleep(10 * 60)

bot = TwitchBot.Client(**login_info)
smash_class = MyBackgroundTask(bot.get_IRC())
bot.run([smash_class.smash_reminder])

We support you sending in multiple functions to run concurrently which is why TwitchPy.TwitchBot.Client.run() expects a list.

Note

Any Functions you want to run concurrently CANNOT take any arguments, except for self if used correctly.

Note

Any functions you want to run concurrently MUST include await asyncio.sleep(x) where x is a time in seconds. This is what enables the concurrency. Without this, the bot will get stuck on one function and fail to work altogether.

Setting up a Logger

TwitchPy uses the logging library’s logger (with some added functionality to it) to print information about the bot’s functioning to the console and/or a file. By default, TwitchPy provides you a very basic logger that only prints to console. But of course, you can create your own loggers and customize the way they work.

Creating Loggers

TwitchPy uses two separate loggers: one reserved for logging to the console and one reserved for logging to a file. We simplistically just call these console and file. We separate them like this so you can customize the function of both separately, allowing one of the loggers to behave differently from the other. To create a logger, you first need to create an instance of TwitchPy.Logger.Logger and call TwitchPy.Logger.Logger.create_console_logger() and/or TwitchPy.Logger.Logger.create_file_logger() depending on which ones you want. And don’t forget to pass the instance of TwitchPy.Logger.Logger to TwitchPy.TwitchBot.Client

from TwitchPy import TwitchBot, Logger

MyLoggers = Logger.Logger()
MyLoggers.create_console_logger()
MyLoggers.create_file_logger(filename='MyLog.log', filemode='w')

bot = TwitchBot.Client(**login, logger=MyLoggers)

Notice here that TwitchPy.Logger.Logger.create_file_logger() has the kwargs filename and filemode. filename takes a string which represents what file it writes to and filemode takes a string which represents which file writing mode to use (which is basically just ‘w’ for write or ‘a’ for append).

Note

Both TwitchPy.Logger.Logger.create_console_logger() and TwitchPy.Logger.Logger.create_file_logger() have more kwargs, but we’ll discuss those in the coming sections.

Log Formatting

There are three different formatting options you can customize. All of which use python’s % string formatting. You can read about it here: https://docs.python.org/3/library/string.html#format-examples . But in short, whenever you want to include a variable in your string, you follow this syntax %(varname)s where the s at the end signifies that varname is a string. While % formatting allows different data types, you’ll only need to use s for the bot.

The three formatting options available to you is the general log format, date format, and chat format. In the following sections, we’ll be talking about how to use all of these for the console logger, but that doesn’t mean that these features are unique to it - you’ll be able to do all the same things with the file logger.

General Format

This is how you want your log messages to appear when they print to your console/file. To set a logger’s format, you can use the TwitchPy.Logger.Logger.create_console_logger()’s kwarg, fmt, sending a % formatted string.

For a list of all the attributes you can use, you can reference: https://docs.python.org/3/library/logging.html#logrecord-attributes

Here’s an example

MyLoggers.create_console_logger(fmt='[%(levelname)-8s] [%(module)-10s] [%(asctime)s] %(message)s')

This is the default fmt value and produces logs that look kind of like:

[INFO    ] [TwitchBot ] [18:29:22] bot is ready to run
[INFO    ] [TwitchBot ] [18:29:22] starting bot...
[BASIC   ] [Websocket ] [18:29:22] connecting to channel: loltyler1...
[BASIC   ] [Websocket ] [18:29:22] successfully connected to channel: loltyler1
[INFO    ] [Websocket ] [18:29:22] bot is now listening...

Note

Don’t connect your bots to channels without the streamer’s permission.

Date Format

This is how you want the date to be displayed when you use %(asctime)s. We follow python’s time.strftime()’s formatting so you can reference https://docs.python.org/3/library/time.html#time.strftime on all the ways you can customize how it’s formatted.

To set this, use the kwarg datefmt like so:

MyLoggers.create_console_logger(datefmt='%Y/%m/%d - %H:%M:%S')

This is the default behavior of the file logger and will print time that looks like:

2020/03/16 - 18:29:22

Chat Format

This is how you want chat messages to be formatted. This format is entirely TwitchPy, unlike the the others which were all a part of the logging library. So your variables should be in the scope of TwitchPy.ChatInfo.Chat . For a quick reference of the variables, you can look at Interacting With IRC , just make sure not to lead the variable names with ctx . Also, this is the only format that has to be sent to TwitchPy.Logger.Logger directly instead of through TwitchPy.Logger.Logger.create_console_logger() which means that both loggers will use this format.

To set this, use the kwarg chatfmt while intializing TwitchPy.Logger.Logger

MyLoggers = TwitchPy.Logger.Logger(chatfmt='%(user.name)s: %(msg)s')

This is the default behavior and will print chat messages that look like:

someviewer: PogChamp

Alternatively, you can set this later using TwitchPy.Logger.Logger.set_chatfmt()

MyLoggers.set_chatfmt('%(user.name)s: %(msg)s')

Filters

TwitchPy uses a custom filter (not to be confused with logging’s filters) that checks for log types to give you precise control over what each logger can and cannot see. For each message that TwitchPy tries to log, TwitchPy associates the message with a log type. Here’s a quick reference sheet for all of TwitchPy’s log types:

log type description
‘TwitchBot-init’ init related messages
‘TwitchBot-basic’ the basic function of the module
‘TwitchBot-error’ error messages
‘API-init’  
‘API-basic’  
‘API-error’  
‘API-request_get’ exactly what the bot sends via requests
‘API-request_response’ the response from the twitch API endpointin its rawest form
‘Websocket-init’  
‘Websocket-basic’  
‘Websocket-error’  
‘Websocket-incoming’ incoming messages from twitch chat
‘Websocket-outgoing’ outgoing messages to twitch chat
‘Websocket-send’ exactly what the bot sends via websocket
‘Websocket-recv’ what twitch IRC sends to us
‘Events-init’  
‘Commands-error’  

You can filter out log messages by their log type by using TwitchPy.Logger.Logger.console_filter() and TwitchPy.Logger.Logger.file_filter(), both of which take one argument: a list of of strings with each string being a log type that you do not want to show up. For example, you may want all log types except for ‘API-request_get’ and ‘API_request_response’ to show up in your console loger.

from TwitchPy import Logger

MyLoggers = Logger.Logger()
MyLoggers.create_console_logger()
MyLoggers.console_filter(['API-request_get', 'API-request_response'])

Each log type follows the same structure: {module}-{type name}. So ‘API-request_get’ comes from the API module and the log type’s name is request_get. This is especially important to note because TwitchPy doesn’t do any input sanitization. If you misstype, TwitchPy won’t throw any errors or let you know that what you’ve typed might be wrong. This is because we wanted to let you set up your own log types for your program which you can then use the filters on. More on this at Implementing Loggers in Your Program


A much simpler but less customizable way to control what your logger logs is with logging levels. Each message sent to be logged has a logging level associated with it. When you create a logger, you can use the kwarg level which takes an int and serves as a minimum value for your logger to pay attention to.

from TwitchPy import Logger

MyLoggers = Logger.Logger()
MyLoggers.create_console_logger(level=20)

This creates a logger that will only log messages that have a level of 20 or above. The logging module has some predefined levels which you can find at https://docs.python.org/3/library/logging.html#logrecord-attributes , but TwitchPy also has some predefined levels. Here’s a quick reference for all the levels.

level value
logging.CRITICAL 50
logging.ERROR 40
logging.WARNING 30
TwitchPy.Logger.MSG 21
logging.INFO 20
TwitchPy.Logger.BASIC 19
TwitchPy.Logger.INIT 11
logging.DEBUG 10
TwitchPy.Logger.LOWLVL 9
logging.NOTSET 0

Presets

If you’re feeling lazy and don’t really want to spend the time customizing a logger, you can use one of our presets. Just use the kwarg preset when intializing TwitchPy.Logger.Logger . We have the following presets:

'default' - This is what TwitchPy will default to, so you don’t even need to specify this as your preset. But this only uses a console logger to print TwitchPy.Logger.BASIC levels and above with fmt='[%(levelname)-8s] [%(module)-10s] [%(asctime)s] %(message)s' and datefmt='%H:%M:%S'

'recommended' - This is our own personal preference that creates a console logger that prints TwitchPy.Logger.INIT levels and above with fmt='[%(levelname)-8s] [%(module)-10s] [%(asctime)s] %(message)s' and datefmt='%H:%M:%S' . This also creates a file logger that appends TwitchPy.Logger.BASIC and above messages to a file ‘TwitchBot.log’ with fmt='[%(levelname)-8s] [%(module)-10s] [%(asctime)s] %(message)s' and datefmt='%Y/%m/%d - %H:%M:%S'

As an example, if you wanted to create a logger using the preset ‘recommended’, you would do:

from TwitchPy import TwitchBot, Logger

MyLoggers = Logger.Logger(preset='recommended')
bot = TwitchBot.Client(logger=MyLoggers)

Set Functions

While TwitchPy provides functions to create your own loggers, you may find that it lacks some of the depth and features that the logging library provides. So we have TwitchPy.Logger.Logger.set_console_logger() and TwitchPy.Logger.Logger.set_file_logger() that both take one argument, a logger created by the logging library. In this way you can customize your logger(s) just like you would for other programs.

As long as we’re talking about the limitations of TwitchPy’s loggers, you may find yourself wanting some functionality that would need more than 2 loggers. If you wanted to work within the confines of TwitchPy’s logger, you might be able to find some crafty solutions here https://docs.python.org/3/howto/logging-cookbook.html . If you’re unable to find a solution, you can always catch the on_log event (see Catching Events).

Note

The names console and file loggers are purely cosmetic. We make no checks to ensure that they’re purely console / file handlers. So you could create a logger that writes to a file and send it to TwitchPy.Logger.Logger.set_console_logger() and that would work without any problems.

Implementing Loggers in Your Program

So far we’ve taught you how to set up loggers and change their behavior which is good if the only things you wanted to log are the parts coded into TwitchPy, but chances are you want to be able to send your own log messages. To do that, you should use TwitchPy.Logger.Logger.log() which takes 3 required arguments and 1 optional argument.

argument data type description
level int the logging level (see Filters)
type_ str the type of log message (see Filters)
msg str the message you want logged
exc sys.exc_info() optional: if there was an exception thrown

Let’s take a look at a quick example:

from TwitchPy import TwitchBot, Commands, Logger

class MyCommands(Commands.Cog)
    def __init__(self, logger):
        super().__init__(prefix='!')
        self.logger = logger

    @Commands.create()
    async def ping(self, ctx):
        self.logger.log(20, 'connection_test', 'ping command executed.')

MyLoggers = Logger.Logger()
MyLoggers.create_console_logger(level=0)

mycog = MyCommands(MyLoggers)

bot = TwitchBot.Client(**login, logger=MyLoggers)
bot.add_cogs(mycog)
bot.run()

With this program, the message ‘ping command executed.’ will be logged with level 20 and type ‘connection_test’ whenever a viewer says ‘!ping’ in twitch chat. Notice here that log type ‘connection_test’ is a custom log type and not something TwitchPy sets up. By creating your own system of log types, you can use TwitchPy’s filters to filter out your own logs if you’d like. Just follow the format: {module}-{type name}

In this example, if we saved the file as ‘mybot.py’ and we didn’t want any messages with type ‘connection_test’, we would add the line

MyLoggers.console_filter(['mybot-connection_test'])

right after creating the console logger and then nothing would show up in your console when a viewer says ‘!ping’ in twitch chat.

Catching Events

TwitchPy has certain events that it’ll ‘throw’ during its runtime that you can ‘catch’ if you’d like to run a function when something in specific happens. For example, you might want to count how many times commands were used. So instead of having every single command function have the line use_count += 1, we can catch the on_cmd event. To do this we would need to create a class that inherits from TwitchPy.Events.Handler, call super().__init__(), overwrite the on_cmd() function, and pass it to TwitchPy.TwitchBot.Client using the kwarg eventhandler

from TwitchPy import TwitchBot, Events

class MyEventHandler(Events.Handler):
    def __init__(self):
        super().__init__()
        self.use_count = 0

    async def on_cmd(self, ctx):
        self.use_count += 1

bot = TwitchBot.Client(**login, eventhandler=MyEventHandler())

So whenever TwitchPy executes a command successfully, it will call MyEventHandler.on_cmd(). For the different events you can catch and what arguments they take, you can reference this quick chart or take a look at the references for more detailed explanations.

event arguments async? when it’s called
on_ready none no after the bot has finished intializing
on_run none no when TwitchPy.TwitchBot.Client.run() is called
on_connect none yes when the bot connects to a twitch channel
on_log str, logging.LogRecord yes whenever the bot tries to log something
on_msg TwitchPy.ChatInfo.Chat yes whenever a message is sent via IRC
on_cmd TwitchPy.ChatInfo.Chat yes whenever a command executes successfully
on_bad_cmd TwitchPy.ChatInfo.Chat yes whenever the bot failes to find a command to execute
on_no_cmd TwitchPy.ChatInfo.Chat yes whenever a message is sent that is not meant for the bot
on_death none yes when the bot dies
on_expected_death none yes when we mean kill the bot
on_unexpected_death exception, sys.exc_info() yes when the bot dies for some unknown reason

Need More Examples?

If you’re looking to see more examples, you can check out the examples section of the github page: https://github.com/rexosorous/TwitchPy . Each of the examples requires you to have a file ‘login.json’ that’s structured like so:

login = {   "token": "your auth token",
            "user": "your bot name",
            "client_id": "the bot's client ID",
            "channel": "the channel to connect to"
}

Assuming your login credentials are correct, they should all work. So you can have it connect to your own channel and tinker with the code to help you better understand how everything works.

Read the References!

Hopefully these guides are all you need to understand and use the bot. But that doesn’t mean we went over every function. I’m sure you’re tired of hearing us say it, but if you’re looking for more information on something, then take a peak at the references for a break down of the modules and all their classes, attributes, and functions.