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.
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)
Command Middleware#
Command Middleware is a way to control when a command should be executed.
See Chat Command Middleware and Chat - Introduction to Middleware for more information.
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)
Available Events#
Event Name |
Event Data |
Description |
---|---|---|
Bot Ready |
This Event is triggered when the bot is started up and ready to join channels. |
|
Message Send |
ChatEvent: |
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: |
Triggered when a channel gets raided |
Channel Config Changed |
ChatEvent: |
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. |
|
User Channel Leave |
Triggered when someone other than the bot leaves a channel. |
|
Bot Channel Join |
ChatEvent: |
Triggered when the bot joins a channel |
Bot Channel Leave |
Triggered when the bot left a channel |
|
Message Delete |
ChatEvent: |
Triggered when a single message in a channel got deleted |
User Messages Cleared |
ChatEvent: |
Triggered when a user was banned, timed out and/or all messaged from a user where deleted |
Bot Receives Whisper Message |
ChatEvent: |
Triggered when someone whispers to your bot. |
Server Notice |
ChatEvent: |
Triggered when server sends a notice message. |
Code example#
from twitchAPI.twitch import Twitch
from twitchAPI.oauth import UserAuthenticator
from twitchAPI.type 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.Chat#
Bases:
object
The chat bot instance
- __init__(twitch, connection_url=None, is_verified_bot=False, initial_channel=None, callback_loop=None, no_message_reset_time=10, no_shared_chat_messages=True)#
- Parameters:
connection_url¶ (
Optional
[str
]) – alternative connection urlDefault:None
is_verified_bot¶ (
bool
) – set to true if your bot is verified by twitchDefault:False
initial_channel¶ (
Optional
[List
[str
]]) – List of channel which should be automatically joined on startupDefault:None
callback_loop¶ (
Optional
[AbstractEventLoop
]) –The asyncio eventloop to be used for callbacks.
Set this if you or a library you use cares about which asyncio event loop is running the callbacks. Defaults to the one used by Chat.
no_message_reset_time¶ (
Optional
[float
]) – How many minutes of mo messages from Twitch before the connection is considered dead. Twitch sends a PING just under every 5 minutes and the bot must respond to them for Twitch to keep the connection active. At 10 minutes we’ve definitely missed at least one PINGDefault:10
no_shared_chat_messages¶ (
bool
) – Filter out Twitch shared chat messages from other channels. This will only listen for messages that were sent in the chat room that the bot is listening in.-
connection_url:
str
# Alternative connection url
Default:None
-
ping_frequency:
int
# Frequency in seconds for sending ping messages. This should usually not be changed.
-
listen_confirm_timeout:
int
# Time in second that any
listen_
should wait for its subscription to be completed.
-
log_no_registered_command_handler:
bool
# Controls if instances of commands being issued in chat where no handler exists should be logged.
Default:True
-
default_command_execution_blocked_handler:
Optional
[Callable
[[ChatCommand
],Awaitable
[None
]]]# The default handler to be called should a command execution be blocked by a middleware that has no specific handler set.
- start()#
Start the Chat Client
- Raises:
RuntimeError – if already started
- Return type:
- stop()#
Stop the Chat Client
- Raises:
RuntimeError – if the client is not running
- Return type:
- set_prefix(prefix)#
Sets a command prefix.
The default prefix is !, the prefix can not start with / or .
- Parameters:
- Raises:
ValueError – when the given prefix is None or starts with / or .
- set_channel_prefix(prefix, channel)#
Sets a command prefix for the given channel or channels
The default channel prefix is either ! or the one set by
set_prefix()
, the prefix can not start with / or .
- reset_channel_prefix(channel)#
Resets the custom command prefix set by
set_channel_prefix()
back to the global one.
- register_command(name, handler, command_middleware=None)#
Register a command
- Parameters:
- Raises:
ValueError – if handler is not a coroutine
- Return type:
- unregister_command(name)#
Unregister a already registered command.
- register_event(event, handler)#
Register a event handler
- unregister_event(event, handler)#
Unregister a handler from a event
- is_ready()#
Returns True if the chat bot is ready to join channels and/or receive events
- Return type:
- is_mod(room)#
Check if chat bot is a mod in a channel
- is_subscriber(room)#
Check if chat bot is a subscriber in a channel
- is_in_room(room)#
Check if the bot is currently in the given chat room
- 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.
- async send_raw_irc_message(message)#
Send a raw IRC message
- Parameters:
- Raises:
ValueError – if bot is not ready
- 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:
- Raises:
ValueError – if message is empty or room is not given
ValueError – if bot is not ready
- async leave_room(chat_rooms)#
leave one or more chat rooms
Will only exit once all given chat rooms where successfully left
- register_command_middleware(mid)#
Adds the given command middleware as a general middleware
- unregister_command_middleware(mid)#
Removes the given command middleware from the general list
- 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
- badge_info#
All infos related to the badges of the user
- badges#
The badges of the user
- source_badges#
The badges for the chatter in the room the message was sent from. This uses the same format as the badges tag.
- source_badge_info#
Contains metadata related to the chat badges in the source-badges tag.
- 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)#
-
reply_parent_msg_id:
Optional
[str
]# An ID that uniquely identifies the parent message that this message is replying to.
-
reply_thread_parent_msg_id:
Optional
[str
]# An ID that uniquely identifies the top-level parent message of the reply thread that this message is replying to. Is
None
if this message is not a reply.
-
reply_thread_parent_user_login:
Optional
[str
]# The login name of the sender of the top-level parent message. Is
None
if this message is not a reply.
- emotes#
The emotes used in the message
-
source_id:
Optional
[str
]# A UUID that identifies the source message from the channel the message was sent from.
-
source_room_id:
Optional
[str
]# An ID that identifies the chat room (channel) the message was sent from.
- 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)#
- async send(message)#
Sends a message to the channel the command was issued in
- async reply(text)#
Reply to this message
-
reply_parent_msg_id:
Optional
[str
]# An ID that uniquely identifies the parent message that this message is replying to.
-
reply_thread_parent_msg_id:
Optional
[str
]# An ID that uniquely identifies the top-level parent message of the reply thread that this message is replying to. Is
None
if this message is not a reply.
-
reply_thread_parent_user_login:
Optional
[str
]# The login name of the sender of the top-level parent message. Is
None
if this message is not a reply.
-
source_id:
Optional
[str
]# A UUID that identifies the source message from the channel the message was sent from.
-
source_room_id:
Optional
[str
]# An ID that identifies the chat room (channel) the message was sent from.
-
chat:
Chat
# The
twitchAPI.chat.Chat
instance
- 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
- 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)
- __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'>#
Triggered when the bot is started up and ready
- MESSAGE = <ChatEvent.MESSAGE: 'message'>#
Triggered when someone wrote a message in a chat channel
- SUB = <ChatEvent.SUB: 'sub'>#
Triggered when someone subscribed to a channel
- RAID = <ChatEvent.RAID: 'raid'>#
Triggered when a channel gets raided
- ROOM_STATE_CHANGE = <ChatEvent.ROOM_STATE_CHANGE: 'room_state_change'>#
Triggered when a chat channel is changed (e.g. sub only mode was enabled)
- JOIN = <ChatEvent.JOIN: 'join'>#
Triggered when someone other than the bot joins a chat channel
- JOINED = <ChatEvent.JOINED: 'joined'>#
Triggered when the bot joins a chat channel
- LEFT = <ChatEvent.LEFT: 'left'>#
Triggered when the bot leaves a chat channel
- USER_LEFT = <ChatEvent.USER_LEFT: 'user_left'>#
Triggered when a user leaves a chat channel
- MESSAGE_DELETE = <ChatEvent.MESSAGE_DELETE: 'message_delete'>#
Triggered when a message gets deleted from a channel
- CHAT_CLEARED = <ChatEvent.CHAT_CLEARED: 'chat_cleared'>#
Triggered when a user was banned, timed out or all messaged from a user where deleted
- WHISPER = <ChatEvent.WHISPER: 'whisper'>#
Triggered when someone whispers to your bot. NOTE: You need the
WHISPERS_READ
Auth Scope to get this Event.
- NOTICE = <ChatEvent.NOTICE: 'notice'>#
Triggered on server notice
- 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
-
chat:
Chat
# The
twitchAPI.chat.Chat
instance
- class twitchAPI.chat.JoinEvent#
Bases:
EventData
- __init__(chat, channel_name, user_name)#
-
chat:
Chat
# The
twitchAPI.chat.Chat
instance
- class twitchAPI.chat.JoinedEvent#
Bases:
EventData
- __init__(chat, channel_name, user_name)#
-
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)#
-
chat:
Chat
# The
twitchAPI.chat.Chat
instance
- class twitchAPI.chat.ClearChatEvent#
Bases:
EventData
- __init__(chat, parsed)#
-
banned_user_id:
Optional
[str
]# The ID of the user who got banned or timed out. if
duration
is None, the user was banned. Will be None when the user was not banned nor timed out.
-
chat:
Chat
# The
twitchAPI.chat.Chat
instance
- class twitchAPI.chat.WhisperEvent#
Bases:
EventData
- __init__(chat, parsed)#
-
chat:
Chat
# The
twitchAPI.chat.Chat
instance
- class twitchAPI.chat.MessageDeletedEvent#
Bases:
EventData
- __init__(chat, parsed)#
-
chat:
Chat
# The
twitchAPI.chat.Chat
instance
- class twitchAPI.chat.NoticeEvent#
Bases:
EventData
Represents a server notice
- __init__(chat, parsed)#
-
msg_id:
str
# Message ID of the notice, Msg-id reference
-
chat:
Chat
# The
twitchAPI.chat.Chat
instance
- class twitchAPI.chat.HypeChat#
Bases:
object
- __init__(parsed)#
-
exponent:
int
# Indicates how many decimal points this currency represents partial amounts in. Decimal points start from the right side of the value defined in
amount
-
default_command_execution_blocked_handler:
-
ping_frequency: