asynchronous twitch-bot framework made in pure python
Project description
if you have any questions concerning the bot, you can contact me in my discord server: https://discord.gg/PXrKVHp OR r/pythontwitchbot on reddit
if you would like to send a few dollars my way you can do so here:
this bot is also on PYPI: https://pypi.org/project/PythonTwitchBotFramework/
install from pip: pip install PythonTwitchBotFramework
PythonTwitchBotFramework
fully async twitchbot framework/library compatible with python 3.6+
how to stop the bot
to stop the bot running, do any of these commands:
!shutdown
!stop
or !s
in the twitch chat of the channel its in, this command
tries to properly shutdown all the tasks the bot is currently running and gives
time to stop/cancel
these commands requires the caller have permission to execute them
Quick Links
- Quick Start
- Overriding Events
- Overriding Events On Mods
- Adding Commands
- SubCommands
- DummyCommands
- Permissions
- Reloading Permissions
- Command Server
- Command Console
- Mysql Support
- Command Whitelist
basic info
This is a fully async twitch bot framework complete with:
- builtin command system using decorators
- overridable events (message received, whisper received, ect)
- full permission system that is individual for each channel
- message timers
- quotes
- custom commands
- builtin economy
there is also mod system builtin to the bot, there is a collection of pre-made mods here: MODS
Quick Start
for a reference for builtin command look at the wiki HERE
the minimum code to get the bot running is this:
from twitchbot.bots import BaseBot
if __name__ == '__main__':
BaseBot().run()
this will start the bot.
if you have a folder with your own custom commands you can load the .py files in it with:
from twitchbot import BaseBot, load_commands_from_directory
if __name__ == '__main__':
load_commands_from_directory('PATH/TO/DIRECTORY')
BaseBot().run()
Overriding Events
the bots events are overridable via the following 2 ways:
using decorators:
from twitchbot import event_handler, Event, Message
@event_handler(Event.on_privmsg_received)
async def on_privmsg_received(msg: Message):
print(f'{msg.author} sent message {msg.content} to channel {msg.channel_name}')
subclassing BaseBot
from twitchbot import BaseBot, Message
class MyCustomTwitchBot(BaseBot):
async def on_privmsg_received(self, msg: Message):
print(f'{msg.author} sent message {msg.content} to channel {msg.channel_name}')
then you would use MyCustomTwitchBot instead of BaseBot:
MyCustomTwitchBot().run()
Overriding Events On Mods
Visit the mods wiki page on this repo's wiki to view how to do it via Mods
- all overridable events are:
when using the decorator event override way, self
is not included, ex: (self, msg: Message)
becomes: (msg: Message)
from twitchbot import Event
Event.on_connected : (self)
Event.on_permission_check : (self, msg: Message, cmd: Command) -> bool # return False to deny permission to execute the cmd
Event.on_after_command_execute : (self, msg: Message, cmd: Command)
Event.on_before_command_execute : (self, msg: Message, cmd: Command) -> bool # return False to cancel command
Event.on_bits_donated : (self, msg: Message, bits: int)
Event.on_channel_raided : (self, channel: Channel, raider: str, viewer_count: int)
Event.on_channel_joined : (self, channel: Channel)
Event.on_channel_subscription : (self, subscriber: str, channel: Channel, msg: Message)
Event.on_privmsg_received : (self, msg: Message)
Event.on_privmsg_sent : (self, msg: str, channel: str, sender: str)
Event.on_whisper_received : (self, msg: Message)
Event.on_whisper_sent : (self, msg: str, receiver: str, sender: str)
Event.on_raw_message : (self, msg: Message)
Event.on_user_join : (self, user: str, channel: Channel)
Event.on_user_part : (self, user: str, channel: Channel)
Event.on_mod_reloaded : (self, mod: Mod)
Event.on_channel_points_redemption : (self, msg: Message, reward: str)
Event.on_bot_timed_out_from_channel : (self, msg: Message, channel: Channel, seconds: int)
Event.on_bot_banned_from_channel : (self, msg: Message, channel: Channel)
Event.on_poll_started : (self, channel: Channel, poll: PollData)
Event.on_poll_ended : (self, channel: Channel, poll: PollData)
Event.on_pubsub_received : (self, raw: 'PubSubData')
Event.on_pubsub_custom_channel_point_reward : (self, raw: 'PubSubData', data: 'PubSubPointRedemption')
if this is the first time running the bot it will generate a folder
named configs
.
inside is config.json
which you put the authentication into
as the bot is used it will also generate channel permission files
in the configs
folder
Adding Commands
to register your own commands use the Command decorator:
- using decorators
from twitchbot import Command
@Command('COMMAND_NAME')
async def cmd_function(msg, *args):
await msg.reply('i was called!')
- you can also limit the commands to be whisper or channel chat only (default is channel chat only)
from twitchbot import Command, CommandContext
# other options are CommandContext.BOTH and CommandContext.WHISPER
@Command('COMMAND_NAME', context=CommandContext.CHANNEL) # this is the default command context
async def cmd_function(msg, *args):
await msg.reply('i was called!')
- you can also specify if a permission is required to be able to call the command (if no permission is specified anyone can call the command):
from twitchbot import Command
@Command('COMMAND_NAME', permission='PERMISSION_NAME')
async def cmd_function(msg, *args):
await msg.reply('i was called!')
- you can also specify a help/syntax for the command for the help chat command to give into on it:
from twitchbot import Command, Message
@Command('COMMAND_NAME', help='this command does a very important thing!', syntax='<name>')
async def cmd_function(msg: Message, *args):
await msg.reply('i was called!')
so when you do !help COMMAND_NAME
it will this in chat:
help for "!command_name",
syntax: "<name>",
help: "this command does a very important thing!"
- you can add aliases for a command (other command names that refer to the same command):
from twitchbot import Command, Message
@Command('COMMAND_NAME',
help='this command does a very important thing!',
syntax='<name>',
aliases=['COMMAND_NAME_2', 'COMMAND_NAME_3'])
async def cmd_function(msg: Message, *args):
await msg.reply('i was called!')
COMMAND_NAME_2
and COMMAND_NAME_2
both refer to COMMAND_NAME
and all three execute the same command
SubCommands
the SubCommand class makes it easier to implement different actions based on a parameters passed to a command.
its the same as normal command except thats its not a global command
example: !say
could be its own command, then it could have the sub-commands !say myname
or !say motd
.
you can implements this using something like this:
from twitchbot import Command
@Command('say')
async def cmd_say(msg, *args):
# args is empty
if not args:
await msg.reply("you didn't give me any arguments :(")
return
arg = args[0].lower()
if arg == 'myname':
await msg.reply(f'hello {msg.mention}!')
elif arg == 'motd':
await msg.reply('the message of the day is: python is awesome')
else:
await msg.reply(' '.join(args))
that works, but i would be done in a nicer way using the SubCommand
class:
from twitchbot import Command, SubCommand
@Command('say')
async def cmd_say(msg, *args):
await msg.reply(' '.join(args))
# we pass the parent command as the first parameter
@SubCommand(cmd_say, 'myname')
async def cmd_say_myname(msg, *args):
await msg.reply(f'hello {msg.mention}!')
@SubCommand(cmd_say, 'motd')
async def cmd_say_motd(msg, *args):
await msg.reply('the message of the day is: python is awesome')
both ways do the same thing, what you proffer to use is up to you, but it does make it easier to manage for larger commands to use SubCommand class
DummyCommands
this class is basically a command that does nothing when executed, its mainly use is to be used as base command for sub-command-only commands
it has all the same options as a regular Command
when a dummy command is executed it looks for sub-commands with a matching name as the first argument passed to it
if no command is found then it will say in chat the available sub-commands
but if a command is found it executes that command
say you want a command to greet someone, but you always want to pass the language, you can do this:
from twitchbot import DummyCommand, SubCommand
# cmd_greet does nothing itself when called
cmd_greet = DummyCommand('greet')
@SubCommand(cmd_greet, 'english')
async def cmd_greet_english(msg, *args):
await msg.reply(f'hello {msg.mention}!')
@SubCommand(cmd_greet, 'spanish')
async def cmd_greet_spanish(msg, *args):
await msg.reply(f'hola {msg.mention}!')
doing just !greet
will make the bot say:
command options: {english, spanish}
doing !greet english
will make the bot say this:
hello @johndoe!
doing !greet spanish
will make the bot say this:
hola @johndoe!
Config
the default config values are:
{
"nick": "nick",
"oauth": "oauth:",
"client_id": "CLIENT_ID",
"prefix": "!",
"default_balance": 200,
"loyalty_interval": 60,
"loyalty_amount": 2,
"owner": "BOT_OWNER_NAME",
"channels": [
"channel"
],
"mods_folder": "mods",
"commands_folder": "commands",
"command_server_enabled": true,
"command_server_port": 1337,
"command_server_host": "localhost",
"disable_whispers": false,
"use_command_whitelist": false,
"send_message_on_command_whitelist_deny": true,
"command_whitelist": [
"help",
"commands",
"reloadcmdwhitelist",
"reloadmod",
"reloadperms",
"disablemod",
"enablemod",
"disablecmdglobal",
"disablecmd",
"enablecmdglobal",
"enablecmd",
"addcmd",
"delcmd",
"updatecmd",
"cmd"
]
}
oauth
is the twitch oauth used to login
client_id
is the client_id used to get info like channel title, ect ( this is not required but twitch API info will not be available without it )
nick
is the twitch accounts nickname
prefix
is the command prefix the bot will use for commands that
dont use custom prefixes
default_balance
is the default balance for new users that dont
already have a economy balance
owner
is the bot's owner
channels
in the twitch channels the bot will join
loyalty_interval
the interval for which the viewers will given currency for watching the stream, gives amount specified by loyalty_amount
loyalty_amount
the amount of currency to give viewers every loyalty_interval
command_server_enabled
specifies if the command server should be enabled (see Command Server for more info)
command_server_port
the port for the command server
command_server_host
the host name (address) for the command server
disable_whispers
is this value is set to true
all whispers will be converted to regular channel messages
use_command_whitelist
enabled or disables the command whitelist (see Command Whitelist)
send_message_on_command_whitelist_deny
should the bot tell users when you try to use a non-whitelisted command?
command_whitelist
json array of commands whitelisted without their prefix (only applicable if Command Whitelist is enabled)
Permissions
the bot comes default with permission support
there are two ways to manage permissions,
- using chat commands
- editing JSON permission files
managing permissions using chat commands
to add a permission group: !addgroup <group>
, ex: !addgroup donators
to add a member to a group: !addmember <group> <user>
, ex:
!addmember donators johndoe
to add a permission to a group: !addperm <group> <permission>
, ex:
!addperm donators slap
to remove a group: !delgroup <group>
, ex: !delgroup donators
to remove a member from a group: !delmember <group> <member>
, ex:
!delmember donators johndoe
to remove a permission from a group: !delperm <group> <permission>
, ex:
!delperm donators slap
managing permission by editing the configs
find the configs
folder the bot generated (will be in same directory as the
script that run the bot)
inside you will find config.json
with the bot config values required for
authentication with twitch and such
if the bot has joined any channels then you will see file names
that look like CHANNELNAME_perms.json
for this example i will use a johndoe
so if you open johndoe_perms.json
you will see this if you
have not changed anything in it:
{
"admin": {
"name": "admin",
"permissions": [
"*"
],
"members": [
"johndoe"
]
}
}
name
is the name of the permission group
permissions
is the list of permissions the group has
("*" is the "god" permission, granting access to all bot commands)
members
is the members of the group
to add more permission groups by editing the config you can just copy/paste the default one (be sure to remove the "god" permission if you dont them having access to all bot commands)
so after copy/pasting the default group it will look like this
(dont forget to separate the groups using ,
):
{
"admin": {
"name": "admin",
"permissions": [
"*"
],
"members": [
"johndoe"
]
},
"donator": {
"name": "donator",
"permissions": [
"slap"
],
"members": [
"johndoe"
]
}
}
Reloading Permissions
if the bot is running be sure to do !reloadperms
to load
the changes to the permission file
Command Server
The command server is a small Socket Server the bot host that lets the Command Console be able to make the bot send messages given to it through a console. (see Command Console)
The server can be enabled or disabled through the config (see Config), the server's port and host are specified by the config file
Command Console
If the Command Server is disabled in the config the Command Console cannot be used
The Command Console is used to make the bot send chat messages and commands
To launch the Command Console make sure the bot is running, and the Command Server is enabled in the Config,
after verifying these are done, simply do python command_console.py
to open the console, upon opening it you will be prompted to select a twitch channel that the bot is currently connected to.
after choose the channel the prompt changes to (CHANNEL_HERE):
and you are now able to send chat messages / commands to the choosen channel by typing your message and pressing enter
Mysql Support
to enabled mysql
- open
configs/mysql.json
(if its missing run the bot and close it, this should generatemysql.json
) - set
enabled
totrue
- fill in
address
,username
,password
, anddatabase
- install the mysql library (if needed)
pip install --upgrade --user mysql-connector-python
- rerun the bot
Command Whitelist
Command whitelist is a optional feature that only allows certain commands to be used (specified in the config)
it is disabled by default, but can be enabled by setting use_command_whitelist
to true
in configs/config.json
Command Whitelist limits what commands are enabled / usable on the bot
if a command that is not whitelisted is ran, it will tell the command caller that it is not whitelisted if send_message_on_command_whitelist_deny
is set to true
, otherwise it will silently NOT RUN the command
whitelisted commands can be edited with the command_whitelist
json-array in configs/config.json
to edit the command whitelist, you can add or remove elements from the command_whitelist
json-array, do not include the command's prefix, AKA !command
becomes command
in command_whitelist
To reload the whitelist, restart the bot, or do !reloadcmdwhitelist
in your the twitch chat (requires having manage_commands
permission)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for PythonTwitchBotFramework-1.13.6.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | d351042b394393cd317c8e52debe20dd192d872d1e474f2341310c84b953639d |
|
MD5 | 941ecfd3076a37320cee8942e0d805c4 |
|
BLAKE2b-256 | 5bd3769e0e0203f0a5ff588d5d6c8b9aaedefd0dee7e86a294ee14c162691f72 |
Hashes for PythonTwitchBotFramework-1.13.6-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | dde35580dd2becd873e207bcc97003ed87cde94eda8d8efb76b8f58f425d229b |
|
MD5 | d5cac6a695275fb69f06455f584a91dc |
|
BLAKE2b-256 | 594706aea05523edd858b72bdf9231dbda0b1032ddedfc38f49263837fa0aacb |