AnonymerNiklasistanonym / MoonpieBot

A custom twitch bot
https://anonymerniklasistanonym.github.io/MoonpieBot/
MIT License
0 stars 0 forks source link
cross-platform osu spotify twitch typescript

MoonpieBot

github release CI

A custom Twitch chat bot.

MoonpieBot icon

Configuration

To supply configuration information you can either:

Note: Via the command line argument --config-dir or the Windows installer shortcut for a custom configuration directory you can always change the directory which is searched for the .env and other configuration files.

Features

Given the following required information provided via:

the bot will imitate this Twitch account in these Twitch channel(s).

The following subsections contains all supported features of the bot:

Optional: Moonpie

Every day a user can claim a moonpie and the count is saved in a persistent database.

Chat Command Permissions Description
!moonpie about about everyone Get version information of the bot
!moonpie add userName:=('TEXT'/TEXT) countAdd:=NUMBERS add broadcaster Add moonpies to a user
!moonpie claim everyone (If not already claimed) Claim a moonpie once every set hours and return the current count and the leaderboard position
!moonpie commands commands everyone List all enabled commands
!moonpie delete userName:=('TEXT'/TEXT) delete broadcaster Delete moonpies of a user
!moonpie get userName:=('TEXT'/TEXT) get everyone Get moonpies of a user
!moonpie leaderboard[ startingRank:=NUMBERS] leaderboard everyone List the top moonpie holders
!moonpie remove userName:=('TEXT'/TEXT) countRemove:=NUMBERS remove broadcaster Remove moonpies from a user
!moonpie set userName:=('TEXT'/TEXT) countSet:=NUMBERS set broadcaster Set moonpies of a user

Optional: osu!

Given a StreamCompanion connection osu! beatmap information (!np) can be provided or given an osu! OAuth client ID/secret and osu! ID plus an osu! IRC login the bot can enable beatmap requests or fetch other osu! related information.

A osu! StreamCompanion (https://github.com/Piotrekol/StreamCompanion) connection can be enabled for a much better !np command via either a websocket OR file interface.

A osu! API connection can be enabled to enable beatmap requests and other osu! commands.

Optional osu! IRC connection that can be enabled to send beatmap requests to the osu! client.

Chat Command Permissions Description
!osu commands commands everyone List all enabled commands
!osuLastRequest[ lastRequestCount:=NUMBERS] last_request mod Resend the last request (or requests if a custom count is provided) in case of a osu! client restart
!np np everyone Get a link to the currently selected map (if an optional StreamCompanion URL/directory path is provided this information will be used to get the current map information, otherwise the osu! window text will be used and searched for using the given osu! credentials [very slow and only works if the map is being played plus no detailed runtime information like mods and not all map information will be correct especially if it's not a ranked map])
!osuPermitRequest permit_request mod Permit last blocked request
!pp[ (osuUserId:=NUMBERS/osuUserName:=('TEXT'/TEXT))] pp everyone Get general account information (pp, rank, country, ...) of the account or of the given osu! player
osuBeatmapUrl[ comment] requests everyone Request a beatmap requests using an osu! URL and optional comment
!osuRequests[( on/ off)[ message:=('TEXT'/TEXT)]] requests get=everyone on/off=mod Get if beatmap requests are currently enabled and with which demands if there are any, Turn beatmap requests on or off with an optional message
!osuRequests set option:=TEXT optionValue:=('TEXT'/TEXT) requests mod Set beatmap demands/options (arMax, arMin, csMax, csMin, detailed, detailedIrc, enabled, lengthInMinMax, lengthInMinMin, message, redeemId, starMax, starMin)
!osuRequests unset option:=TEXT requests mod Reset beatmap request demands/options (arMax, arMin, csMax, csMin, detailed, detailedIrc, enabled, lengthInMinMax, lengthInMinMin, message, redeemId, starMax, starMin) back to their default value
!rp[ (osuUserId:=NUMBERS/osuUserName:=('TEXT'/TEXT))] rp everyone Get the most recent play of the account or of the given osu! player
!score osuUserName:=('TEXT'/TEXT) score everyone Get the top score of the given osu! player on the most recently mentioned map in chat (from a beatmap request, rp, np)

Everything is currently optimized and written for osu! standard which means you need to open an issue if you want to use it with another game mode!

Optional: Spotify

Optional Spotify commands that can be enabled.

Given a Spotify client ID/secret the bot can fetch some Spotify related information like the currently played song.

Chat Command Permissions Description
!spotify commands commands everyone List all enabled commands
!song song everyone Get the currently playing (and most recently played) song on the connected Spotify account

Default: Custom text/strings/messages

Most messages can be customized to a high degree because this application uses a message parser that can parse a normal text/string and replace certain parts with runtime information like a user name in a message reply (@$(USER) ping becomes at runtime to @john_smith ping).

To achieve this the logic consists of:

To override the default strings and add additional custom ones you can create a .env.strings file. There is an example file .env.strings.example for this where all the default values are listed and can be uncommented/edited which also contains the plugin and macro documentation.

Example:

# .env.strings file content

# Default value (commented and only here for reference)
#MOONPIE_CUSTOM_STRING_MOONPIE_COMMAND_REPLY_ABOUT=@$(USER) %MOONPIEBOT:NAME% %MOONPIEBOT:VERSION%
# Customized value (will override the default MOONPIE_COMMAND_REPLY_ABOUT string)
MOONPIE_CUSTOM_STRING_MOONPIE_COMMAND_REPLY_ABOUT=@$(USER) %MOONPIEBOT:NAME% %MOONPIEBOT:VERSION% (custom string) $[ABC]
# Custom string that can be referenced in any other string
MOONPIE_CUSTOM_STRING_ABC=Custom reference 69

If you now type in chat !moonpie about instead of the default reply the reply will also contain (custom string) Custom reference 69 at the end.


For some macros to work (like Twitch API connections for !so/!followage/!settitle/!setgame, osu! api requests or Spotify api requests) additional API credentials need to be provided (most of them use the same credentials as the optional features with the same name).

Even though to run the bot default Twitch API credentials are already provided these credentials are only configured to read and write chat messages and are unable to change the stream title or fetch information about Twitch accounts.

Everything should be explained in more detail in the .env.example file.

Default: Custom commands/broadcasts

Custom commands and custom broadcasts can be added/edited/deleted via the Twitch chat which are persistently saved in a database. Custom commands will be checked for every new message. Custom broadcasts will be scheduled at start of the bot and rescheduled on any change.

Chat Command Permissions Description
!addcb id:=('TEXT'/TEXT) cronString:=('TEXT'/TEXT) message:=('TEXT'/TEXT) add_broadcast mod Add a broadcast with an ID, a cron expression to determine when the broadcast should be sent (crontab.cronhub.io) and a message
!addcc id:=('TEXT'/TEXT) regex:=('TEXT'/TEXT) message:=('TEXT'/TEXT)[ -ul=userLevel:=(mod/vip/none/broadcaster)][ -cd=cooldownInS:=NUMBERS] add_command mod Add a command with an ID, a RegEx expression to detect it and capture contents of the match (regex101.com) and a message - Optionally a cooldown (in s) and user level (broadcaster, mod, vip, none) are also supported
!(cc[s]/cb[s]/cc[scb][s]) commands commands everyone List all enabled commands
!delcb id:=('TEXT'/TEXT) delete_broadcast mod Delete a broadcast
!delcc id:=('TEXT'/TEXT) delete_command mod Delete a command
!editcb id:=('TEXT'/TEXT) option:=TEXT optionValue:=('TEXT'/TEXT) edit_broadcast mod A single property (cronString, description, id, message) can be edited of an existing broadcast
!editcc id:=('TEXT'/TEXT) option:=TEXT optionValue:=('TEXT'/TEXT) edit_command mod A single property (cooldownInS, count, description, id, message, regex, userLevel) can be edited of an existing command
!listcc[s][( listOffset:=NUMBERS/ id:=('TEXT'/TEXT))] list_broadcasts everyone List all callbacks (an offset number can be provided if multiple were added or an ID can be provided to only list one specific broadcast)
!listcb[s][( listOffset:=NUMBERS/ id:=('TEXT'/TEXT))] list_commands everyone List all commands (an offset number can be provided if multiple were added or an ID can be provided to only list one specific command)

An example file for this is customCommandsBroadcasts.example.txt.

The custom commands/broadcasts messages use a custom message parser so next to normal text they can contain advanced logic. The supported logic is documented in the previous section.

A specific group of plugins that only custom commands/broadcasts support are global custom data plugins. They enable to store persistently a text, number or a list of them in a database and change them or run operations on them (there are useful real life examples of this in the previously mentioned example file).

Optional: Lurk

Lurk command that welcomes chatters back.

Chat Command Permissions Description
!lurk lurk everyone Using this lurk command chatters are welcomed back after they come back

Setup

Build it yourself

ATTENTION: If you build this program yourself you need a node runtime that implements fetch which means you need for example Node.js v18+.

  1. Install a recent version of Node.js so the node and npm command are available

  2. Get the source code of the bot

    Either by cloning this repository via git:

    • Install git
    • Open the console/terminal in the directory where you want to have the source code and run:

      # cd path/to/dir
      git clone "https://github.com/AnonymerNiklasistanonym/MoonpieBot.git"

    Or by manually downloading it:

    • Get the latest version from here or by using the GitHub website by clicking Code and then Download ZIP
  3. Open the directory of the cloned or downloaded source code in the console/terminal

    • Windows: Powershell/WindowsTerminal/...
    • Linux: xfce-terminal/...
  4. Install all dependencies

    npm install
  5. Build the bot (it needs to be compiled from TypeScript to JavaScript so it can be run via node)

    npm run build

    If you want you can now also remove all development dependencies that were installed to the node_modules directory and only necessary to build the program but not for running it:

    # Keep in mind that if you want to update the bot after the source code
    # changes you need to run `npm install` again to reacquire the development
    # dependencies
    npm prune --production
  6. Provide a configuration (more details can be found in the Features section)

    • Either using environment variables

    • Or using a .env file in the directory from which you are starting the bot

      You can copy the .env.example file, rename it to .env and then edit the "variables" in there. The file contains also the information about what variables need to be set.

    • A detailed list of steps to get a Twitch OAuth token:

      1. Log into your twitch account (or better the account of the bot) in the browser
      2. Visit the webpage twitchapps.com/tmi
      3. Follow the instructions and click Connect
      4. After enabling permission you get forwarded to a page where you can get the token
  7. Run the bot

    npm run start
    # or
    node .

    If there are errors you can probably find advanced log messages in the log files in the directory logs that is created while running the bot.

    Per default critical values like for example the Twitch OAuth-token will be censored so screenshots or accidentally screen-sharing can't leak this information. This censoring can be disabled by passing an additional command line argument which can be helpful in case of debugging:

    npm run start -- --no-censoring
    # or
    node . --no-censoring

Binary releases

There is now a way to use the program without needing to install or build anything. You can download a binary for your operating system from the latest release and then just run it.

Linux

Binary standalone file (has no dependencies):

./moonpiebot-linux

Windows

Binary standalone file (has no dependencies):

.\moonpiebot-win.exe

Binary installer (has no dependencies):

For Windows there is also an installer with which the program can be easily installed. The installation contains an uninstaller and a start menu/desktop shortcut so no terminal usage is necessary.

The default location of the configuration/database/etc. files is %APPDATA%\MoonpieBot.

Package managers

Pacman

On Linux systems with pacman as their package manager (like Arch/Manjaro Linux) there is a way to install the program by using a PKGBUILD file. For more information check the installer README.md.

The default location of the configuration/database/etc. files is $HOME/.local/share/moonpiebot.

Migrate to a new version

Migrating to a new version CAN break the database, custom commands, etc. This means you should always backup your old configuration (there are shortcuts and command line arguments to do it). In case of a bug or error this means you can always go back to how it was before and lose nothing. Database migrations should be handled automatically and old tables remain in the database in case something goes wrong.

Examples

In the following there is a list of some possible configurations (.env files):

For more details about the options check the example file .env.example

Example > Basic

################################################################################
# TWITCH
# ------------------------------------------------------------------------------
# REQUIRED variables that need to be set for ANY configuration to connect to
# Twitch chat.
################################################################################
# > A with a space separated list of all the channels the bot should be active.
#   THIS VARIABLE IS REQUIRED!
MOONPIE_CONFIG_TWITCH_CHANNELS=twitch_channel_name1,twitch_channel_name2
# > The name of the twitch account/channel that should be imitated.
#   THIS VARIABLE IS REQUIRED!
MOONPIE_CONFIG_TWITCH_NAME=twitch_account_name
# > A Twitch OAuth token (get it from: https://twitchapps.com/tmi/) of the
#   Twitch account specified in MOONPIE_CONFIG_TWITCH_NAME.
#   THIS VARIABLE IS REQUIRED!
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_TWITCH_OAUTH_TOKEN=oauth:abcdefghijklmnop

Supported features:

Example > Lune (Moonpie)

################################################################################
# TWITCH
# ------------------------------------------------------------------------------
# REQUIRED variables that need to be set for ANY configuration to connect to
# Twitch chat.
################################################################################
# > A with a space separated list of all the channels the bot should be active.
#   THIS VARIABLE IS REQUIRED!
MOONPIE_CONFIG_TWITCH_CHANNELS=twitch_channel_name1,twitch_channel_name2
# > The name of the twitch account/channel that should be imitated.
#   THIS VARIABLE IS REQUIRED!
MOONPIE_CONFIG_TWITCH_NAME=twitch_account_name
# > A Twitch OAuth token (get it from: https://twitchapps.com/tmi/) of the
#   Twitch account specified in MOONPIE_CONFIG_TWITCH_NAME.
#   THIS VARIABLE IS REQUIRED!
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_TWITCH_OAUTH_TOKEN=oauth:abcdefghijklmnop

################################################################################
# MOONPIE
# ------------------------------------------------------------------------------
# Every day a user can claim a moonpie and the count is saved in a persistent
# database.
################################################################################
# > You can provide a list of commands that should be enabled, if this is empty
#   or not set all commands are enabled (set the value to 'none' if no commands
#   should be enabled).
#   Supported list values: 'about', 'add', 'claim', 'commands', 'delete', 'get',
#   'leaderboard', 'remove', 'set'
#   Empty list value: 'none'
#   (Default value: about,commands)
MOONPIE_CONFIG_MOONPIE_ENABLE_COMMANDS=about,add,claim,commands,delete,get,leaderboard,remove,set

################################################################################
# OSU API
# ------------------------------------------------------------------------------
# A osu! API connection can be enabled to enable beatmap requests and other osu!
# commands.
################################################################################
# > The osu! client ID (and client secret) to use the osu! API v2. To get it go
#   to your account settings, Click 'New OAuth application' and add a custom
#   name and URL (https://osu.ppy.sh/home/account/edit#oauth). After doing that
#   you can copy the client ID (and client secret).
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_OSU_API_CLIENT_ID=1234
# > Check the description of MOONPIE_CONFIG_OSU_API_CLIENT_ID.
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_OSU_API_CLIENT_SECRET=dadasfsafsafdsadffasfsafasfa
# > The default osu! account ID used to check for recent play or a top play on a
#   map.
MOONPIE_CONFIG_OSU_API_DEFAULT_ID=1185432

################################################################################
# OSU STREAM COMPANION
# ------------------------------------------------------------------------------
# A osu! StreamCompanion (https://github.com/Piotrekol/StreamCompanion)
# connection can be enabled for a much better !np command via either a websocket
# OR file interface.
################################################################################
# > osu! StreamCompanion directory (file interface) path to use a running
#   StreamCompanion instance to always get the currently being played beatmap,
#   used mods and more (This is ignored if
#   MOONPIE_CONFIG_OSU_STREAM_COMPANION_URL is also provided). To configure the
#   StreamCompanion output and for example update certain values like the
#   download link even when not playing a map you need to open StreamCompanion.
#   Go to the section 'Output Patterns' and then edit the used rows (like
#   'np_all') to change the format. You can also change the 'Save event' of a
#   row like for the current mods or download link so both will be live updated
#   even if no song is played.
MOONPIE_CONFIG_OSU_STREAM_COMPANION_DIR_PATH='C:\Program Files (x86)\StreamCompanion\Files'

################################################################################
# OSU IRC
# ------------------------------------------------------------------------------
# Optional osu! IRC connection that can be enabled to send beatmap requests to
# the osu! client.
################################################################################
# > The osu! irc server password and senderUserName. To get them go to
#   https://osu.ppy.sh/p/irc and login (in case that clicking the 'Begin Email
#   Verification' button does not reveal a text input refresh the page and click
#   the button again -> this also means you get a new code!)
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_OSU_IRC_PASSWORD=senderServerPassword
# > The osu! account name that should receive the requests (can be the same
#   account as the sender!).
MOONPIE_CONFIG_OSU_IRC_REQUEST_TARGET=receiverUserName
# > Check the description of MOONPIE_CONFIG_OSU_IRC_PASSWORD.
MOONPIE_CONFIG_OSU_IRC_USERNAME=senderUserName

Supported features:

Example > Geo (Only osu! beatmap requests and !rp/!pp/!score)

################################################################################
# TWITCH
# ------------------------------------------------------------------------------
# REQUIRED variables that need to be set for ANY configuration to connect to
# Twitch chat.
################################################################################
# > A with a space separated list of all the channels the bot should be active.
#   THIS VARIABLE IS REQUIRED!
MOONPIE_CONFIG_TWITCH_CHANNELS=twitch_channel_name1,twitch_channel_name2
# > The name of the twitch account/channel that should be imitated.
#   THIS VARIABLE IS REQUIRED!
MOONPIE_CONFIG_TWITCH_NAME=twitch_account_name
# > A Twitch OAuth token (get it from: https://twitchapps.com/tmi/) of the
#   Twitch account specified in MOONPIE_CONFIG_TWITCH_NAME.
#   THIS VARIABLE IS REQUIRED!
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_TWITCH_OAUTH_TOKEN=oauth:abcdefghijklmnop

################################################################################
# OSU
# ------------------------------------------------------------------------------
# Given a StreamCompanion connection osu! beatmap information (!np) can be
# provided or given an osu! OAuth client ID/secret and osu! ID plus an osu! IRC
# login the bot can enable beatmap requests or fetch other osu! related
# information.
################################################################################
# > You can provide a list of commands that should be enabled, if this is empty
#   or not set all commands are enabled (set the value to 'none' if no commands
#   should be enabled). If you don't provide osu! API credentials and/or a
#   StreamCompanion connection commands that need that won't be enabled!
#   Supported list values: 'commands', 'last_request', 'np', 'permit_request',
#   'pp', 'requests', 'rp', 'score'
#   Empty list value: 'none'
#   (Default value:
#   commands,last_request,np,permit_request,pp,requests,rp,score)
MOONPIE_CONFIG_OSU_ENABLE_COMMANDS=commands,last_request,permit_request,pp,requests,rp,score

################################################################################
# OSU API
# ------------------------------------------------------------------------------
# A osu! API connection can be enabled to enable beatmap requests and other osu!
# commands.
################################################################################
# > The osu! client ID (and client secret) to use the osu! API v2. To get it go
#   to your account settings, Click 'New OAuth application' and add a custom
#   name and URL (https://osu.ppy.sh/home/account/edit#oauth). After doing that
#   you can copy the client ID (and client secret).
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_OSU_API_CLIENT_ID=1234
# > Check the description of MOONPIE_CONFIG_OSU_API_CLIENT_ID.
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_OSU_API_CLIENT_SECRET=dadasfsafsafdsadffasfsafasfa
# > The default osu! account ID used to check for recent play or a top play on a
#   map.
MOONPIE_CONFIG_OSU_API_DEFAULT_ID=1185432

################################################################################
# OSU IRC
# ------------------------------------------------------------------------------
# Optional osu! IRC connection that can be enabled to send beatmap requests to
# the osu! client.
################################################################################
# > The osu! irc server password and senderUserName. To get them go to
#   https://osu.ppy.sh/p/irc and login (in case that clicking the 'Begin Email
#   Verification' button does not reveal a text input refresh the page and click
#   the button again -> this also means you get a new code!)
#   KEEP THIS VARIABLE PRIVATE!
MOONPIE_CONFIG_OSU_IRC_PASSWORD=senderServerPassword
# > The osu! account name that should receive the requests (can be the same
#   account as the sender!).
MOONPIE_CONFIG_OSU_IRC_REQUEST_TARGET=receiverUserName
# > Check the description of MOONPIE_CONFIG_OSU_IRC_PASSWORD.
MOONPIE_CONFIG_OSU_IRC_USERNAME=senderUserName

################################################################################
# CUSTOM COMMANDS & BROADCASTS
# ------------------------------------------------------------------------------
# Custom commands and custom broadcasts can be added/edited/deleted via the
# Twitch chat which are persistently saved in a database. Custom commands will
# be checked for every new message. Custom broadcasts will be scheduled at start
# of the bot and rescheduled on any change.
################################################################################
# > You can provide a list of commands that should be enabled, if this is empty
#   or not set all commands are enabled (set the value to 'none' if no commands
#   should be enabled).
#   Supported list values: 'add_broadcast', 'add_command', 'commands',
#   'delete_broadcast', 'delete_command', 'edit_broadcast', 'edit_command',
#   'list_broadcasts', 'list_commands'
#   Empty list value: 'none'
#   (Default value:
#   add_broadcast,add_command,commands,delete_broadcast,delete_command,edit_broadcast,edit_command,list_broadcasts,list_commands)
MOONPIE_CONFIG_CUSTOM_COMMANDS_BROADCASTS_ENABLE_COMMANDS=none

Supported features:

Inspect Database

To inspect the SQLite database manually and edit it or run custom queries (for example for development) the program DB Browser for SQLite can be used.

Development

Debugging

The bot can be debugged using Visual Studio Code (there are open source versions with no Microsoft telemetry!):

You can now catch uncaught exceptions or break on any line by setting breakpoints in the TypeScript source files (or the compiled JavaScript files).

Tests

If you only want to run one specific test suite and not all of them you can specify the test suite file:

# This will only run the test suite in the file "test/src/database.test.ts"
cross-env NODE_PATH=. nyc mocha -- "test/src/database.test.ts"

Configuration files

How to handle versions

  1. Prepare version for release

    For releases set the next version in src/version.ts (don't forget to set beta: false). Then you need to run the following command to update most files with that version:

    npm run create

    After all versions are updated commit these changes with the message: Prepare version for release

  2. Create git version tag

    Now you can run npm version patch/minor/major because it will automatically create a commit and tag for you (in case you want a specific version modify the version in package.json before running npm version for ease of use).

    To push the git tag created by npm version run git push origin <tag_name> or use git push --tags.

  3. Bump version for next dev cycle

    To mark the next dev cycle as a not final release change the version in src/version.ts to the version you aim to release next (don't forget to set beta: true).

    Then you need to run the following command to update most files with that version:

    npm run create

    After all versions are updated commit these changes with the message: Bump version for next dev cycle


GitHub Actions will automatically create a GitHub release for you so you only need to edit the title and description after it successfully ran.

Documentation

For documentation purposes several plugins can be used:

Profiling

Credits

The following docs and websites were useful during the creation of this bot.