Git Product home page Git Product logo

yukibot's Introduction

yukibot Build Status

Yukibot is ostensibly the IRC bot for the ##compsoc-uk-anime channel on Freenode, but is basically my pet project to play with IRC in Haskell.

Usage

There are cabal files, so you can build this with cabal if you want, but I use nix.

The Scripted Way

$ run-yukibot /path/to/configuration/file

This will build everything with nix and start a tmux session called "yukibot", running yukibot with the given configuration file.

Calling the script a second time will build the new yukibot, kill the old one, and start the new one. As the build is done first, there should be minimal downtime during the switch.

$ kill-yukibot

This will send a C-c to a tmux session called "yukibot".

The Manual Way

$ ./gen-package-list.sh
$ nix-shell

This will build everything and drop you in a shell with it all available. Now you're good to go:

$ yukibot configuration.toml

Configuration

Configuration files are in Tom's Obvious, Minimal Language (TOML). See the example-configuration.toml file.

Organisation

There are four components in a bot:

  • The core, which contains all the logic and is provided by the yukibot-core package.

  • The backends, which provide a uniform interface to the actual backend in use, such as a connection to an IRC server. These are provided by the yukibot-backend-* packages.

  • The plugins, which provide monitors, run on every message from the backend; and commands, activated by a prefix key followed by a "verb". These are provided by the yukibot-plugin-* packages.

  • The executable, which loads the backends and plugins, and passes this initial state off to the core along with the configuration. An example bot is provided by the yukibot package.

yukibot's People

Contributors

barrucadu avatar rski avatar taneb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

taneb rski

yukibot's Issues

bind doesn't check the command is valid, leading to a crash in help.

IRC <ssl://[email protected]:7000> Sat Mar 18 15:34:02 UTC 2017  <---  :barrucadu!~barrucadu@fsf/member/barrucadu PRIVMSG yukibot :bind seen:quote quote
IRC <ssl://[email protected]:7000> Sat Mar 18 15:34:06 UTC 2017  <---  :barrucadu!~barrucadu@fsf/member/barrucadu PRIVMSG yukibot :quote foo bar
IRC <ssl://[email protected]:7000> Sat Mar 18 15:34:10 UTC 2017  <---  :barrucadu!~barrucadu@fsf/member/barrucadu PRIVMSG yukibot :help                                                             IRC <ssl://[email protected]:7000> Sat Mar 18 15:34:10 UTC 2017  --->  NOTICE barrucadu :add trigger, bind, clear quotes, clear triggers, degrade, deify, delete trigger, disable plugin, enable plugin, eval, help, join, kind, leave, list quotes, list triggers, quote, seen, set channel prefix, set default prefix, start monitor, stop monitor, type, unbind, unbind!, unset channel prefix (see also 'plugin', 'command', and 'monitor')
IRC <ssl://[email protected]:7000> Sat Mar 18 15:34:15 UTC 2017  <---  :barrucadu!~barrucadu@fsf/member/barrucadu PRIVMSG yukibot :help quote
yukibot: Help references missing command: seen:quote
CallStack (from HasCallStack):
  error, called at ./Yukibot/Plugin/Builtin.hs:432:33 in yukibot-core-2.1.0.0-ACyVMB4rHyPI2ZIZKjWytC:Yukibot.Plugin.Builtin

Configuration

JSON isn't so great, but configuration is necessary. TOML looks nice, and the htoml library implements it.

Furthermore, configuration should be read-only, unlike the current yukibot, where configuration is rewritten on quit. This is bad because unexpected termination can mess up the config.

The actual configuration may change during execution, due to (eg) #39. There should be a way to dump the actual configuration to a new file, so allow for hand-merging if desired.

Logging

yukibot currently just dumps everything to stdout, which is sort of fine if you only have a single backend. But with multiple backends, multiple logs are really needed.

The logging has to be done at the backend level, as the bot gets a higher-level view, so bot-level logging would be useless for debugging.

Key-value store plugin

Would be nice to be able to store keys/values on a per-channel basis, print out all the stored keys, and retrieve a value by key.

Dice rolling

Both simple (eg, !roll XdY) and complex (eg, !roll (UdV)dW + XdY + Z)

Plugins

What yukibot has currently, but backend-agnostic.

Plugins should be able to be enabled or disabled on a per-channel bases: both the plugin as a whole, and on an individual event-handler level.

Database

Currently mutable state is serialised in the configuration file on termination, this has a couple of issues:

  • The configuration file blows up, especially when keeping track of things for the seen command
  • If serialisation fails for some reason, everything is lost as the file gets completely rewritten.

Both issues could be solved by having a small database. Just a key-value store namespaced by plugin would suffice. Furthermore, by separating configuration from state, much of the serialisation stuff can be dropped, and the configuration file can be read-only. If more rich serialisation is required than key-value, the existing Aeson instances for everything can be re-used when reading/writing to the database.

Better Youtube LinkInfo

LinkInfo allows for arbitrary extensions. In particular, the ImgurLinks plugin uses this to provide titles for image URLs. It'd be nice for Youtube links to include things like title, length, up/down votes.

Yukibot should have a vote feature

Upon parsing a command, example "!make vote", and giving comma(?) seperated parameters:
!make vote 1,2,3,4,5
Yukibot then accepts votes in the form of "!vote 1" or !vote 3" etc.
After a period (60s?) Yukibot prints the results.

Initial plugins

These should be considered high-priority as they actually get used:

  • link info
  • mueval (with type/kind)
  • seen
  • trigger

State

While configuration should be read-only, there is a use for read-write state. Currently mongodb is used, which is very convenient as it doesn't require a schema. Only the other hand, the actual data format used in a few places is pretty rigid: tagged and timestamped strings. Furthermore, mongodb requires a separate database server.

It would be nice to not need a separate database server and, given the in-practice rigidity of the schema, perhaps something like sqlite would be good enough.

Backend abstraction

Really, there's very little that's actually IRC-specific in an IRC bot. There's the backend, and that's it. The rest of the bot (can be) almost totally oblivious to what the backend actually is, as long as it's kind of IRC-like.

Come up with an abstraction for backends which:

  • Are message-oriented
  • Have a notion of channels
  • Are read/write

The job of a concrete backend implementation would be:

  • To transform incoming messages into a form the bot can deal with, and pass them along.
  • To transform outgoing messages into a form the backend can deal with, and pass them along.
  • To automatically handle control messages (pings, etc).
  • To detect and resolve failures (disconnects).
  • To facilitate joining and leaving channels.

To most easily support different types of backend, the only configuration should be some sort of connection dictionary.

Furthermore, it should be possible for multiple backends to be executing simultaneously.

Download/decode utilities for common formats

There is currently a download function for things-as-ByteStrings, and a wrapper around that for things-as-Strings. It'd be kinda nice if helpers for:

  • JSON (Aeson Value type)
  • RSS / Atom (some appropriate feed library type)
  • XML (HXT)

existed.

Better SoundCloud LinkInfo

Similar to Youtube LinkInfo really: title, uploader, length, 'likes' (or whatever soundcloud calls them)

Logging plugin

Now that yukibot is lurking in #hacksoc-committee, optional logging would be really useful.

Yukibot should respond to 'hype' embedded within sentaces

Currently Yukibot returns "HYPE HYPE HYPE" when the single word "hype" is parsed.
It would be an improvement if Yukibot responded to mention of the word 'hype' within a sentence.

If time permits it may be worth sanity checking for negatives preceding 'hype' e.g. "not", "not very", "anti" ...

Extra plugins

These would be used if present:

  • topic
  • debt tracker -- use hledger for this?

Evaluation plugin

This is kinda cheating as I already have it mostly-written anyway, but... there should be something like lambdabot's evaluation!

8-bit brainffuck implementation

Some brainfuck programs were written with an implementation that uses 8-bit cells specifically in mind, and no not work with one that has unbounded cells, as is the case with yukibot's.

A common prefix for this in bots is "bf8"

Wrong decoding of youtube video lengths

09:46:59 < kline> https://www.youtube.com/watch?v=QHXgdtiFRNY
09:47:00 -yukibot:##compsoc-uk-anime- "Clown.wmv- 1 hour version" [1:45] (by Grant Poquiz at 2013-05-30) | Views: 59416 [+608 -10]

Better triggers

Currently, triggers work by exact message matching (modulo case). Furthermore, there is no way to modify the trigger list during runtime, or to respond with anything other than a fixed string.

Suggestions:

  • Tags which get replaced with metadata, eg %nick, %channel
  • Respond with an ACTION.
  • Regex triggers.
  • Command to add triggers.
  • Command to remove triggers.

This subsumes issue #1.

RSS plugin

Should watch RSS/Atom feeds and announce new entries to the channel.

Ignore plugin

irc-client has the ability to ignore events based on nick of sender, but this functionality isn't exposed anywhere.

There could be an ignore plugin, providing a helper function to connect to a network and load the ignore list, and a command to modify the list.

Backend administration

Privileged users should be able to tell yukibot to:

  • join a channel,
  • leave a channel,
  • send a message to a specified (backend,channel) pair,
  • disconnect from a backend
  • connect to a new backend.

This requires some way of assigning privilege to users. Given that the current permission system is overkill for its actual use-case, perhaps just specifying the username of the administrator in the backend configuration dictionary is sufficient.

BF Joust plugin

A plugin providing access to a BF Joust hill would be nice, similar to zemhill.

I believe we can use gearlanced https://github.com/fis/chainlance quite nicely, although if it existed as a library that'd also be good.

We'll also want to have some sort of web leaderboard display, too. Not quite sure how to go about that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.