@@ -1 +1,2 @@ | |||||
config.json | config.json | ||||
docker-compose.yml |
@@ -0,0 +1,22 @@ | |||||
FROM python:3.9-slim | |||||
RUN useradd --create-home --shell /bin/bash bot | |||||
WORKDIR /home/bot | |||||
ENV PATH="/home/bot:${PATH}" | |||||
# Prepare environment | |||||
RUN python -m pip install --upgrade pip | |||||
RUN pip install pipenv | |||||
COPY Pipfile.lock . | |||||
RUN pipenv sync && pipenv run pip freeze > requirements.txt | |||||
# Add files | |||||
RUN pip install -r requirements.txt && mkdir config | |||||
COPY _twitchbot/ _twitchbot/ | |||||
COPY bot.py . | |||||
USER bot | |||||
CMD ["python", "bot.py", "--config=config/config.json"] |
@@ -0,0 +1,68 @@ | |||||
# Twason - The KISS Twitch bot | |||||
Twason is an opinionated Twitch chatbot created with the [KISS principle](https://en.wikipedia.org/wiki/KISS_principle) in mind. | |||||
It is based on the [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) protocol and is configurable in just one JSON file. | |||||
## What the hell is that name!? | |||||
Twason is an umbrella name based on two words: _Twitch_ (the platform the bot is designed for) and _Jason_ (as the JSON file that you use to wonfigure it). | |||||
## What features does it provide? | |||||
Currently, Twason has the following features: | |||||
- **Commands:** automatically answer to messages that start with a given command | |||||
- Customizable commands prefix (useful if you're using multiple bots) | |||||
- Mention the user who invoked the command in the answer | |||||
- Help command auto-generation | |||||
- **Timer:** automatically send pre-defined messages | |||||
- Only one timer to keep the bot from spamming in the chat | |||||
- Configurable time and number of messages between each automatic message | |||||
- Two strategies available: | |||||
- _round-robin_: send the messages in the same order they have been set in the configuration file | |||||
- _shuffle_: send the messages in a random order | |||||
More features will be available in the future. | |||||
## How do I use it? | |||||
Twason is currently in development and may contain bugs, but it is globally usable. Actually, I'm using it on [my Twitch channel](https://twitch.tv/jdeuchnord). | |||||
The simplest (and safest) way to use it is to use the Docker image: `deuchnord/twason`. | |||||
A Docker-Compose file is also available for facility. | |||||
### About the Twitch token | |||||
To enable the bot to connect to Twitch chat, you will need to generate a token. Head to the [Twitch Chat OAuth Password Generator](https://twitchapps.com/tmi/) and follow the instructions to generate it. | |||||
Then, you will need to give it to the bot through the `TWITCH_TOKEN` environment variable. | |||||
### The JSON configuration file | |||||
To configure the bot, you will need to create a JSON file in `config/config.json` as defined in the `docker-compose.yml` file. | |||||
You can find a minimal configuration in the `config.json.dist` file in this repository. | |||||
Below is the complete configuration reference: | |||||
```json5 | |||||
{ | |||||
"nickname": "yourbot", // the Twitch name of your bot | |||||
"channel": "yourchannel", // the channel the bot must follow | |||||
"command_prefix": "!", // the prefix the commands will have (defaults to '!') | |||||
"help": true, // if true, a help command will be automatically generated (defaults to true) | |||||
"commands": [ // a list of commands that your bot will recognize and respond to (empty by default) | |||||
{ | |||||
"name": "ping", // the command name - spaces are not recommended here (even though they are technically accepted) | |||||
"message": "Pong @{author} Kappa" // the message the bot must send when someone invokes this command ('{author}' will be replaced with the user who invoked the command) | |||||
} | |||||
], | |||||
"timer": { // the configuration of the automatically sent messages | |||||
"between": { | |||||
"time": 10, // the minimum time that must have passed between two messages (defaults to 10) | |||||
"messages": 10 // the minimum number of messages that the chat members must have sent between two messages (defaults to 10) | |||||
}, | |||||
"strategy": "round-robin", // the strategy used to send the messages: "round-robin" or "shuffle" (defaults to "round-robin") | |||||
"messages": [ // the list of messages to send (empty by default) | |||||
"Hello World! HeyGuys", | |||||
] | |||||
} | |||||
} | |||||
``` |
@@ -33,12 +33,12 @@ class Timer: | |||||
time_between: int = 10, | time_between: int = 10, | ||||
msgs_between: int = 10, | msgs_between: int = 10, | ||||
strategy: TimerStrategy = TimerStrategy.ROUND_ROBIN, | strategy: TimerStrategy = TimerStrategy.ROUND_ROBIN, | ||||
messages: [str] = [] | |||||
messages: [str] = None | |||||
): | ): | ||||
self.time_between = time_between | self.time_between = time_between | ||||
self.msgs_between = msgs_between | self.msgs_between = msgs_between | ||||
self.strategy = strategy | self.strategy = strategy | ||||
self.messages = messages | |||||
self.messages = messages if messages else [] | |||||
@classmethod | @classmethod | ||||
def from_dict(cls, param: dict): | def from_dict(cls, param: dict): | ||||
@@ -98,7 +98,7 @@ class Config: | |||||
) | ) | ||||
def get_config(): | |||||
with open('config.json', 'r') as config_file: | |||||
def get_config(file_path: str): | |||||
with open(file_path, 'r') as config_file: | |||||
token = environ['TWITCH_TOKEN'] | token = environ['TWITCH_TOKEN'] | ||||
return Config.from_dict(json.loads(config_file.read()), token) | |||||
return Config.from_dict(json.loads(config_file.read()), token) |
@@ -4,11 +4,13 @@ from .config import get_config, TimerStrategy | |||||
from random import shuffle | from random import shuffle | ||||
from datetime import datetime, timedelta | from datetime import datetime, timedelta | ||||
config = None | |||||
@irc3.plugin | @irc3.plugin | ||||
class TwitchBot: | class TwitchBot: | ||||
def __init__(self, bot): | def __init__(self, bot): | ||||
self.config = get_config() | |||||
self.config = config | |||||
self.messages_stack = [] | self.messages_stack = [] | ||||
self.bot = bot | self.bot = bot | ||||
self.log = self.bot.log | self.log = self.bot.log | ||||
@@ -1,5 +1,6 @@ | |||||
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
import argparse | |||||
import irc3 | import irc3 | ||||
from _twitchbot.config import get_config | from _twitchbot.config import get_config | ||||
@@ -11,12 +12,14 @@ TWITCH_IRC_PORT = 6697 | |||||
def main() -> int: | def main() -> int: | ||||
config = get_config() | |||||
print(config.timer.messages) | |||||
args = get_arguments() | |||||
twitchbot.config = get_config(args.config) | |||||
print(twitchbot.config.timer.messages) | |||||
bot = irc3.IrcBot.from_config({ | bot = irc3.IrcBot.from_config({ | ||||
'nick': config.nickname, | |||||
'password': config.token, | |||||
'autojoins': [config.channel], | |||||
'nick': twitchbot.config.nickname, | |||||
'password': twitchbot.config.token, | |||||
'autojoins': [twitchbot.config.channel], | |||||
'host': TWITCH_IRC_SERVER, | 'host': TWITCH_IRC_SERVER, | ||||
'port': TWITCH_IRC_PORT, | 'port': TWITCH_IRC_PORT, | ||||
'ssl': True, | 'ssl': True, | ||||
@@ -28,5 +31,12 @@ def main() -> int: | |||||
return 0 | return 0 | ||||
def get_arguments(): | |||||
parser = argparse.ArgumentParser() | |||||
parser.add_argument('--config', '-c', type=str, default='config.json') | |||||
return parser.parse_args() | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
exit(main()) | exit(main()) |
@@ -0,0 +1,22 @@ | |||||
{ | |||||
"nickname": "yourbot", | |||||
"channel": "yourchannel", | |||||
"command_prefix": "!", | |||||
"help": true, | |||||
"commands": [ | |||||
{ | |||||
"name": "ping", | |||||
"message": "Pong @{author} Kappa" | |||||
} | |||||
], | |||||
"timer": { | |||||
"between": { | |||||
"time": 10, | |||||
"messages": 10 | |||||
}, | |||||
"strategy": "round-robin", | |||||
"messages": [ | |||||
"Hello World! HeyGuys", | |||||
] | |||||
} | |||||
} |
@@ -0,0 +1,11 @@ | |||||
version: '3.8' | |||||
services: | |||||
bot: | |||||
build: | |||||
dockerfile: Dockerfile | |||||
context: . | |||||
env: | |||||
TWITCH_TOKEN: 'SET_THIS_TOKEN' | |||||
volumes: | |||||
- './config:/home/bot/config' |