Twitch Chat Bot#

A simple twitch chat bot.

Chat bots can join channels, listen to chat and reply to messages, commands, subscriptions and many more.

Warning

Please note that the Chat Bot is currently in a early alpha stage!

Bugs and oddities are to be expected.

Please report all feature requests and bug requests to the github page.

Commands#

Chat commands are specific messages user can send in chat in order to trigger some action of your bot.

Example:

<User123>: !say Hello world
<MyBot>: User123 asked me to say "Hello world"

You can register listeners to chat commands using register_command().

The bot prefix can be set by using set_prefix(), the default is !

Your command listener function needs to be async and take in one parameter of type ChatCommand.

Example:

async def say_command_handler(cmd: ChatCommand):
    await cmd.reply(f'{cmd.user.name} asked me to say "{cmd.parameter}")

chat.register_command('say', say_command_handler)

Events#

You can listen to different events happening in the chat rooms you joined.

Generally you register a event listener using register_event(). The first parameter has to be of type ChatEvent and the second one is your listener function.

Those Listeners always have to be async functions taking in one parameter (the payload). The Payload type is described below.

Example:

async def on_ready(cmd: EventData):
    await cmd.chat.join_room('teekeks42')

chat.register_event(ChatEvent.READY, on_ready)

Bot Ready#

This Event is triggered when the bot is stared up and ready to join channels.

Message send#

This Event is triggered when someone wrote a message in a channel we joined

Channel Subscription#

This Event is triggered when someone subscribed to a channel we joined.

Raid#

  • ChatEvent: RAID

  • Payload: dict

Triggered when a channel gets raided

Channel config changed#

Triggered when a channel is changed (e.g. sub only mode was enabled)

User channel join#

Triggered when someone other than the bot joins a channel.

Note

this will not always trigger, depending on channel size

User channel leave#

Note

this will not always trigger, depending on channel size

Bot channel join#

Triggered when the bot joins a channel

Bot channel leave#

Triggered when the bot left a channel

Message delete#

Triggered when a single message in a channel got deleted

User messages cleared#

Triggered when a user was banned, timed out and/or all messaged from a user where deleted

Bot recieves whisper message#

Triggered when someone whispers to your bot.

Note

You need the WHISPERS_READ Auth Scope to receive this Event.

Code example#

from twitchAPI import Twitch
from twitchAPI.oauth import UserAuthenticator
from twitchAPI.types 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())

Class Documentation#

class twitchAPI.chat.ChatUser#

Bases: object

Represents a user in a chat channel

__init__(chat, parsed, name_override=None)#
chat: Chat#

The twitchAPI.chat.Chat instance

name: str#

The name of the user

badge_info#

All infos related to the badges of the user

badges#

The badges of the user

color: str#

The color of the chat user if set

display_name: str#

The display name, should usually be the same as name

mod: bool#

if the user is a mod in chat channel

subscriber: bool#

if the user is a subscriber to the channel

turbo: bool#

Indicates whether the user has site-wide commercial free mode enabled

id: str#

The ID of the user

user_type: str#

The type of user

vip: bool#

if the chatter is a channel VIP

class twitchAPI.chat.EventData#

Bases: object

Represents a basic chat event

__init__(chat)#
chat: Chat#

The twitchAPI.chat.Chat instance

class twitchAPI.chat.ChatMessage#

Bases: EventData

Represents a chat message

__init__(chat, parsed)#
text: str#

The message

bits: int#

The amount of Bits the user cheered

sent_timestamp: int#

the unix timestamp of when the message was sent

reply_parent_msg_id: Optional[str]#

An ID that uniquely identifies the parent message that this message is replying to.

reply_parent_user_id: Optional[str]#

An ID that identifies the sender of the parent message.

reply_parent_user_login: Optional[str]#

The login name of the sender of the parent message.

reply_parent_display_name: Optional[str]#

The display name of the sender of the parent message.

reply_parent_msg_body: Optional[str]#

The text of the parent message

emotes#

The emotes used in the message

id: str#

the ID of the message

property room: Optional[ChatRoom]#

The channel the message was issued in

property user: ChatUser#

The user that issued the message

async reply(text)#

Reply to this message

chat: Chat#

The twitchAPI.chat.Chat instance

class twitchAPI.chat.ChatCommand#

Bases: ChatMessage

Represents a command

__init__(chat, parsed)#
name: str#

the name of the command

parameter: str#

the parameter given to the command

async send(message)#

Sends a message to the channel the command was issued in

Parameters:

message (str) – the message you want to send

async reply(text)#

Reply to this message

property room: Optional[ChatRoom]#

The channel the message was issued in

property user: ChatUser#

The user that issued the message

chat: Chat#

The twitchAPI.chat.Chat instance

text: str#

The message

bits: int#

The amount of Bits the user cheered

sent_timestamp: int#

the unix timestamp of when the message was sent

reply_parent_msg_id: Optional[str]#

An ID that uniquely identifies the parent message that this message is replying to.

reply_parent_user_id: Optional[str]#

An ID that identifies the sender of the parent message.

reply_parent_user_login: Optional[str]#

The login name of the sender of the parent message.

reply_parent_display_name: Optional[str]#

The display name of the sender of the parent message.

reply_parent_msg_body: Optional[str]#

The text of the parent message

id: str#

the ID of the message

emotes#

The emotes used in the message

class twitchAPI.chat.ChatSub#

Bases: object

Represents a sub to a channel

__init__(chat, parsed)#
chat: Chat#

The twitchAPI.chat.Chat instance

sub_type: str#

The type of sub given

sub_message: str#

The message that was sent together with the sub

sub_plan: str#

the ID of the subscription plan that was used

sub_plan_name: str#

the name of the subscription plan that was used

system_message: str#

the system message that was generated for this sub

property room: Optional[ChatRoom]#

The room this sub was issued in

class twitchAPI.chat.Chat#

Bases: object

The chat bot instance

__init__(twitch, connection_url=None)#
logger: Logger#

The logger used for Chat related log messages

join_timeout: int#

Time in seconds till a channel join attempt times out

set_prefix(prefix)#

Sets a command prefix.

The default prefix is !, the prefix can not start with / or .

Parameters:

prefix (str) – the new prefix to use for command parsing

Raises:

ValueError – when the given prefix is None or starts with / or .

start()#

Start the Chat Client

Raises:

RuntimeError – if already started

Return type:

None

stop()#

Stop the Chat Client

Raises:

RuntimeError – if the client is not running

Return type:

None

register_command(name, handler)#

Register a command

Parameters:
Raises:

ValueError – if handler is not a coroutine

Return type:

bool

unregister_command(name)#

Unregister a already registered command.

Parameters:

name (str) – the name of the command to unregister

Return type:

bool

Returns:

True if the command was unregistered, otherwise false

register_event(event, handler)#

Register a event handler

Parameters:
Raises:

ValueError – if handler is not a coroutine

unregister_event(event, handler)#

Unregister a handler from a event

Parameters:
  • event (ChatEvent) – The Event you want to unregister your handler from

  • handler (Callable[[Any], Awaitable[None]]) – The handler you want to unregister

Return type:

bool

Returns:

Returns true when the handler was removed from the event, otherwise false

async join_room(chat_rooms)#

join one or more chat rooms

Will only exit once all given chat rooms where successfully joined or twitchAPI.chat.Chat.join_timeout run out.

Parameters:

chat_rooms (Union[List[str], str]) – the Room or rooms you want to leave

Returns:

list of channels that could not be joined

async send_raw_irc_message(message)#

Send a raw IRC message

Parameters:

message (str) – the message to send

async send_message(room, text)#

Send a message to the given channel

Please note that you first need to join a channel before you can send a message to it.

Parameters:
  • room (Union[str, ChatRoom]) – The chat room you want to send the message to. This can either be a instance of ChatRoom or a string with the room name (either with leading # or without)

  • text (str) – The text you want to send

Raises:

ValueError – if message is empty or room is not given

async leave_room(chat_rooms)#

leave one or more chat rooms

Will only exit once all given chat rooms where successfully left

Parameters:

chat_rooms (Union[List[str], str]) – The room or rooms you want to leave

class twitchAPI.chat.ChatRoom#

Bases: object

ChatRoom(name: str, is_emote_only: bool, is_subs_only: bool, is_followers_only: bool, is_unique_only: bool, follower_only_delay: int, room_id: str, slow: int)

name: str#
is_emote_only: bool#
is_subs_only: bool#
is_followers_only: bool#
is_unique_only: bool#
follower_only_delay: int#
room_id: str#
slow: int#
__init__(name, is_emote_only, is_subs_only, is_followers_only, is_unique_only, follower_only_delay, room_id, slow)#
enum twitchAPI.chat.ChatEvent(value)#

Bases: Enum

Represents the possible events to listen for using register_event()

Valid values are as follows:

READY = <ChatEvent.READY: 'ready'>#
MESSAGE = <ChatEvent.MESSAGE: 'message'>#
SUB = <ChatEvent.SUB: 'sub'>#
RAID = <ChatEvent.RAID: 'raid'>#
ROOM_STATE_CHANGE = <ChatEvent.ROOM_STATE_CHANGE: 'room_state_change'>#
JOIN = <ChatEvent.JOIN: 'join'>#
JOINED = <ChatEvent.JOINED: 'joined'>#
LEFT = <ChatEvent.LEFT: 'left'>#
USER_LEFT = <ChatEvent.USER_LEFT: 'user_left'>#
MESSAGE_DELETE = <ChatEvent.MESSAGE_DELETE: 'message_delete'>#
CHAT_CLEARED = <ChatEvent.CHAT_CLEARED: 'chat_cleared'>#
WHISPER = <ChatEvent.WHISPER: 'whisper'>#
class twitchAPI.chat.RoomStateChangeEvent#

Bases: EventData

Triggered when a room state changed

__init__(chat, prev, new)#
old: Optional[ChatRoom]#

The State of the room from before the change, might be Null if not in cache

new: ChatRoom#

The new room state

property room: Optional[ChatRoom]#

Returns the Room from cache

chat: Chat#

The twitchAPI.chat.Chat instance

class twitchAPI.chat.JoinEvent#

Bases: EventData

__init__(chat, channel_name, user_name)#
user_name: str#

The name of the user that joined

property room: Optional[ChatRoom]#

The room the user joined to

chat: Chat#

The twitchAPI.chat.Chat instance

class twitchAPI.chat.JoinedEvent#

Bases: EventData

__init__(chat, channel_name, user_name)#
room_name: str#

the name of the room the bot joined to

user_name: str#

the name of the bot

chat: Chat#

The twitchAPI.chat.Chat instance

class twitchAPI.chat.LeftEvent#

Bases: EventData

When the bot or a user left a room

__init__(chat, channel_name, room, user)#
room_name: str#

the name of the channel the bot left

user_name: str#

The name of the user that left the chat

cached_room: Optional[ChatRoom]#

the cached room state, might bo Null

chat: Chat#

The twitchAPI.chat.Chat instance

class twitchAPI.chat.ClearChatEvent#

Bases: EventData

__init__(chat, parsed)#
room_name: str#

The name of the chat room the event happend in

room_id: str#

The ID of the chat room the event happend in

user_name: str#

The name of the user whos messages got cleared

duration: Optional[int]#

duration of the timeout in seconds. None if user was not timed out

banned_user_id: Optional[str]#

The ID of the user who got banned or timed out. if twitchAPI.chat.ClearChatEvent.duration is None, the user was banned. Will be None when the user was not banned nor timed out.

sent_timestamp: int#

The timestamp the event happend at

property room: Optional[ChatRoom]#

The room this event was issued in. None on cache miss.

chat: Chat#

The twitchAPI.chat.Chat instance

class twitchAPI.chat.WhisperEvent#

Bases: EventData

__init__(chat, parsed)#
message: str#

The message that was send

property user: ChatUser#

The user that DMed your bot

chat: Chat#

The twitchAPI.chat.Chat instance