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.

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())

Available Events#

  • READY: Triggered when the bot is stared up and ready to join channels

  • MESSAGE: Triggered when someone wrote a message in a channel we joined

  • SUB: Triggered when someone subscribed to a channel we joined

  • RAID: Triggered when a channel gets raided

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

  • JOIN: Triggered when someone other than the bot joins a channel. Note: this will not always trigger, depending on channel size

  • JOINED: Triggered when the bot joins a channel

  • LEFT: triggered when the bot left a channel

Class Documentation#

class twitchAPI.chat.ChatUser#

Bases: object

Represents a user in a chat channel

__init__(chat, parsed)#
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

Parameters:

chat (Chat) – represents the Chat Instance

__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

Return type:

Optional[ChatRoom]

property user: ChatUser#

The user that issued the message

Return type:

ChatUser

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

Return type:

Optional[ChatRoom]

property user: ChatUser#

The user that issued the message

Return type:

ChatUser

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)#
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#

The room this sub was issued in

class twitchAPI.chat.Chat#

Bases: object

The chat bot instance

__init__(twitch, connection_url=None)#
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:
  • name (str) – the name of the command

  • handler (Callable) – The event handler

Return type:

bool

register_event(event, handler)#

Register a event handler

Parameters:
  • event (ChatEvent) – The Event you want to register the handler to

  • handler (Callable) – The handler you want to register.

async join_room(chat_rooms)#

join one or more chat rooms

Will only exit once all given chat rooms where successfully joined

Parameters:

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

async send_message(room, text)#
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

An enumeration.

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'>#
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#

Returns the Room from cache

chat: Chat#

The twitchAPI.chat.Chat instance