This is a high performance Twitch Bot written in Rust.
You'll need Rust and a working compiler: https://rustup.rs/
Building requires setting the necessary environment variables to point out libraries. You can set them in PowerShell by running:
. ./tools/env.ps1
After this, build using cargo:
cargo build --release
Two configuration files are neccessary.
First, config.toml
:
streamer = "setbac"
# Optional bad words list.
# See "Bad Words" below.
bad_words = "bad_words.yml"
# Path to database (technicaly an connection URL, but only sqlite supported right now).
database_url = "database.sql"
# Whitelisted hosts (if the `url-whitelist` feature is enabled).
whitelisted_hosts = [
"youtube.com",
"www.youtube.com",
"youtu.be",
"clips.twitch.tv",
]
# Features enabled for the channel.
# Removing features will remove their corresponding commands.
features = [
"admin",
"command",
"counter",
"song",
"afterstream",
"bad-words",
"url-whitelist",
"clip",
"8ball",
]
# API to use for remotely showing playlist information.
api_url = "https://setbac.tv"
[irc]
channel = "#setbac"
bot = "setmod"
moderator_cooldown = "5s"
# whether to notify when viewers are rewarded with loyalty currency.
notify_rewards = false
startup_message = "HeyGuys"
# cooldown required between each `!clip` invocation.
# Default: 15s
clip_cooldown = "15s"
# Loyalty currency in use.
#[currency]
# name = "ether"
[player]
# Optional: if you don't want to use the default device. All devices are listed in the Admin UI.
# device = "MyDevice"
volume = 50
# Set to false and the current song will not be echoed in chat.
echo_current_song = true
[player.current_song]
# Optional: Write information on the current song to the given path for use with e.g. OBS.
path = "E:\\temp\\current_song.txt"
not_playing = "No Song Playing"
template = [
"Song: {{name}}{{#if artists}} by {{artists}}{{/if}}{{#if paused}} (Paused){{/if}} - {{elapsed}} / {{duration}}",
"{{#if user~}}Request by: @{{user~}}{{/if}}",
]
update_interval = "5s"
[themes]
# Theme songs, that can be invoked with `!song theme <name>`.
# This will be played instead of the current song.
# The current song will be paused and start playing after this
# song has been skipped.
blimp = {track = "spotify:track:7JczDg05i29N5C3VMZKIVA"}
setup = {track = "spotify:track:2fZpKgrcAlWzWYwQeFG43O", offset = "00:14"}
[[aliases]]
match = "!sr"
replace = "!song request {{rest}}"
[[aliases]]
match = "!sl"
replace = "!song list {{rest}}"
[[aliases]]
match = "!volume"
replace = "!song volume {{rest}}"
Second, secrets.yml
:
spotify::native:
username: USERNAME
password: PASSWORD
spotify::oauth2:
client_id: SPOTIFY_CLIENT_ID
client_secret: SPOTIFY_CLIENT_SECRET
twitch::oauth2:
client_id: TWITCH_CLIENT_ID
client_secret: TWITCH_CLIENT_SECRET
The client ids and secrets above must be registered on Twitch and Spotify respectively:
For both of these, you must add the following redirect URL:
http://localhost:12345/redirect
This is where the bot will be running while it is receiving tokens.
Bad words filter looks at all words in a channel, converts them to singular and matches them phonetically against a word list.
The word list can be stored in the database with the !badword edit <why>
command.
But you can also use a bad_words.yml
file that looks like this:
words:
- word: cat
why: Please don't talk about cats here {{name}} -___-
- word: trump
If a word matches, the message will be deleted.
why
is optional, but will be communicated to the user in case their message is deleted.
It supports the following template variables:
{{name}}
- the user who said the word.{{target}}
- the channel where the word was sent.
Features are enabled per-channel like this:
irc:
channels:
- name: "#mychannel"
features:
- name-of-feature
Where name-of-feature
is one of the features listed below.
Enabled commands:
!uptime
- Get the current uptime.!title
- Get the current title.!title <title>
- Update the title to be<title>
.!game
- Get the current game.!game <game>
- Update the game to be<game>
.
Allows setting and requesting custom commands.
The command named foo
would be invoked !foo
.
A command is the bot responding with a pre-defined message based on a template.
Enabled commands:
!command edit <name> <what>
- Set the command!<name>
to respond with<what>
(moderator)..!command delete <name>
- Delete the command named<name>
(moderator)..
Template variables that can be used in <what>
:
{{name}}
- the user who said the word.{{target}}
- the channel where the word was sent.
Identical to command
but keeps track of a counter of how many times it has been invoked.
The counter named foo
would be invoked !foo
.
A command is the bot responding with a pre-defined message based on a template.
Enabled commands:
!counter edit <name> <what>
- Set the command!<name>
to respond with<what>
(moderator)..!counter delete <name>
- Delete the command named<name>
(moderator)..
Template variables that can be used in <what>
:
{{count}}
- The number of times the counter has been invoked.{{name}}
- The user who said the word.{{target}}
- The channel where the word was sent.
Add an afterstream message.
Afterstream messages keeps track of who added them and when.
Enabled commands:
!afterstream <message>
- Leaves the<message>
in the afterstream queue.
Note: the only way to list afterstream messages right now is to read the database:
sqlite3.exe database.sql
sqlite> select * from after_streams;
...
All admin commands are restricted to moderators.
!admin refresh-mods
- Refresh the set of moderators in the bot. This is required if someone is modded or unmodded while the bot is running.!admin shutdown
- Cause the mod to cleanly shut down, and hopefully being restarted by the management process.
Enables song playback through Spotify.
Enabled commands:
!song request spotify:track:<id>
- Request a song through a Spotify URI.!song request https://open.spotify.com/track/<id>
- Request a song by spotify URL.!song request <search>
- Request a song by searching for it. The first hit will be used.!song skip
- Skip the current song (moderator).!song play
- Play the current song (moderator).!song pause
- Pause the current song (moderator).!song toggle
- Toggle the current song (Pause/Play) (moderator).!song volume
- Get the current volume.!song volume <volume>
- Set the current volume to<volume>
(moderator).!song length
- Get the current length of the queue.!song current
- Get information on the current song.!song delete last
- Delete the last song in the queue (moderator).!song delete last <user>
- Delete the last song in the queue added by the given<user>
(moderator).!song delete mine
- A user is allowed to delete the last song that they added.!song delete <position>
- Delete a song at the given position (moderator).!song list
- Get the next three songs.!song list <n>
- Get the next<n>
songs (moderator).!song theme <name>
- Play the specified theme song (moderator).!song close [reason]
- Close the song queue with an optional[reason]
(moderator).!song open
- Open the song queue (moderator).!song promote <number>
- Promote the song at the given position<number>
in the queue (moderator).!song when
- Find out when your song will play.!song when <user>
- Find out when the song for a specific user will play (moderator).
The clip
feature enables the !clip
command.
This command has a cooldown determined by the [irc] clip_cooldown
configuration key (see above).
Enables the Magic !8ball
command. Cause it's MAGIC.
You enable the swearjar
module by adding the following to your configuration:
[[modules]]
type = "swearjar"
# The amount of currency to reward all watchers with.
reward = 10
# Cooldown between invocations, default: 1m
# cooldown = "1m"
This also requires the currency
feature to be enabled.
Enabled commands:
!swearjar
- Anyone can invoke the swearjar to reward all viewers with some currency from the streamer when they swear.
You enable the countdown
module by adding the following to your configuration:
[[modules]]
type = "countdown"
path = "E:\\temp\\countdown.txt"
Enabled commands:
!countdown set <duration> <template>
- Set a countdown, available template variables are{{remaining}}
,{{duration}}
, and{{elapsed}}
.!countdown clear
- Clear the current countdown.
Aliases are enabled per-channel like this:
irc:
channels:
- name: "#mychannel"
aliases:
- match: "!sr"
replace: "!song request {{rest}}"
- match: "!sl"
replace: "!song list {{rest}}"
- match: "!volume"
replace: "!song volume {{rest}}"
Aliases are applied as a pre-processing step for each incoming command.