- Go 97.9%
- Makefile 1.1%
- Dockerfile 1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| cmd/flokati | ||
| modules | ||
| util | ||
| .gitignore | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
flokati
An incredibly friendly, silver-tongued, and elegantly proportioned multi protocol community bot.
flokati connects to chat networks (IRC, Matrix) and provides a modular plugin system for community features such as quizzes, weather, RSS feeds, Markov chains, and more.
Project Structure
flokati/
├── cmd/flokati/ # Application entry point and protocol clients
│ ├── main.go # CLI flags, protocol dispatch, version info
│ ├── irc.go # IRC protocol client (goirc)
│ ├── matrix.go # Matrix protocol client (mautrix)
│ └── version.go # Build version constants
├── modules/ # Plugin modules
│ ├── modules.go # Module registry, message dispatch, initialization
│ ├── announcements.go # Announcement management (stub)
│ ├── coffee.go # Coffee-making module
│ ├── eso.go # Esoteric nonsense generator
│ ├── feeds.go # Generic feed polling (gofeed)
│ ├── fortune.go # Fortune cookie module
│ ├── fuzzytime.go # Fuzzy time display (German)
│ ├── markov.go # Markov chain text generation
│ ├── quiz.go # Interactive quiz game
│ ├── rss.go # RSS feed polling (custom RSS lib)
│ ├── stoll.go # Random quote generator
│ ├── twitch.go # Twitch stream monitoring
│ ├── weather.go # Weather lookup (OpenWeatherMap)
│ └── webhook.go # HTTP webhook receiver
├── util/ # Shared utility functions
│ └── util.go # Type conversion, number formatting, umlaut replacement
├── .forgejo/workflows/ # CI/CD pipeline definitions
├── Makefile # Build targets
├── Dockerfile # Multi-stage Docker image build
├── go.mod # Go module definition
└── LICENSE # MIT License
Plugin Architecture
flokati uses a simple registry-based plugin system defined in modules/modules.go.
Core Types
type Message struct {
From string
Channel string
Text string
}
Registration
Each plugin file registers itself in its init() function by adding entries to two package-level maps:
MsgFuncs map[string]func(*Message)– maps a module name to a message handler. Called for every incoming chat message.RunFuncs map[string]func()– maps a module name to a background function. Launched as a goroutine at startup.
Example:
func init() {
MsgFuncs["coffee"] = coffeeHandleMessage
RunFuncs["twitch"] = pollStreamData
}
Initialization
modules.Init(ch chan string, mods string) is called from main(). It:
- Stores the shared output channel in
SayCh. - Filters
MsgFuncsandRunFuncsto only include modules listed in the comma-separatedmodsstring. - Launches all registered
RunFuncsas goroutines.
Message Dispatch
modules.HandleMessage(m *Message) iterates over all registered MsgFuncs and calls each handler with the incoming Message.
Output
All modules send output by writing to the shared SayCh channel. The format is:
<target>\n<message text>
Where <target> is a channel name, a user name, or * for the default channel(s).
Adding a New Plugin
- Create a new file in
modules/(e.g.modules/mymod.go). - Register your handler(s) in an
init()function:func init() { MsgFuncs["mymod"] = mymodHandleMessage // Optionally for background tasks: // RunFuncs["mymod"] = mymodRun } - Implement your handler:
func mymodHandleMessage(m *Message) { if strings.HasPrefix(m.Text, "!mymod") { SayCh <- m.Channel + "\nHello from mymod!" } } - Add
mymodto the-modsflag when running flokati.
Installation
Prerequisites
- Go 1.21 or later
gitmake- External tools required by specific modules:
/usr/games/fortune(fortune module)libolm-dev(Matrix E2E encryption)
Build from Source
git clone https://dev.dnix.de/dnix/flokati.git
cd flokati
make build
This runs go test, go fmt, and compiles the binary to bin/flokati.
Make Targets
| Target | Description |
|---|---|
make |
Run test, fmt, and build (default) |
make test |
Run go test ./cmd/flokati |
make vet |
Run go vet ./cmd/flokati |
make fmt |
Run go fmt ./... |
make lint |
Run golint on all packages |
make build |
Build the binary to bin/flokati |
make docker |
Generate version info, build & push Docker image |
Docker
make docker
This generates version info into cmd/flokati/version.go, builds the image tagged dr.dnix.de/flokati, and pushes it to the registry.
The Dockerfile uses a multi-stage build:
- Build stage (
golang:1.26.2): compiles the binary with CGO enabled. - Runtime stage (
git.dnix.de/dnix/baseimage): minimal image with runtime dependencies.
Running
Command-Line Flags
| Flag | Default | Description |
|---|---|---|
-protocol |
"" |
Protocol: irc or matrix |
-mods |
"" |
Comma-separated list of modules to load |
-name |
flokati |
Bot account name |
-nick |
flokati |
Bot nickname (IRC) |
-server |
https://matrix.org |
Server host / homeserver URL |
-chan |
"" |
Default channel(s), comma-separated |
-password |
"" |
Login password (IRC) |
-token |
"" |
Login token (Matrix) |
IRC-specific flags
| Flag | Default | Description |
|---|---|---|
-port |
6697 |
IRC server port |
-tls |
true |
Enable TLS for IRC |
-nsname |
NickServ |
NickServ service name |
-nspass |
"" |
NickServ password |
-automsg_to |
"" |
Target for automatic message on connect |
-automsg_text |
"" |
Text of automatic message on connect |
Matrix-specific flags
| Flag | Default | Description |
|---|---|---|
-database |
"" |
Path to crypto database |
IRC Example
./bin/flokati \
-protocol irc \
-server irc.example.org \
-port 6697 \
-tls \
-name flokati \
-nick flokati \
-chan "#general,#random" \
-mods coffee,fortune,fuzzytime,markov,quiz,rss,twitch,weather
Matrix Example
./bin/flokati \
-protocol matrix \
-server https://matrix.example.org \
-name @flokati:example.org \
-token "$MATRIX_TOKEN" \
-database /var/lib/flokati/crypto.db \
-chan "!roomid:example.org" \
-mods coffee,fortune,fuzzytime,markov,quiz,rss,twitch,weather
Available Modules
| Module | Type | Description |
|---|---|---|
coffee |
message | Simulates making coffee for users in a channel |
fortune |
message | Displays fortune cookies via /usr/games/fortune |
fuzzytime |
message | Displays the current time in fuzzy German |
markov |
both | Generates text using a Markov chain trained on chat |
quiz |
both | Interactive quiz game with categories and levels |
rss |
both | Polls RSS feeds and posts new items |
twitch |
both | Monitors Twitch streams and announces when live |
weather |
both | Looks up weather by ZIP code or city |
feeds |
both | Generic feed polling (uses gofeed) |
announcements |
message | Manages channel announcements (stub) |
eso |
message | Generates esoteric nonsense text |
stoll |
message | Generates random quotes |
webhook |
both | Receives HTTP webhooks and posts to channels |
Module Configuration
Modules can be configured via additional command-line flags:
| Flag | Default | Module | Description |
|---|---|---|---|
-weather_api_key |
"" |
weather | OpenWeatherMap API key |
-markov_prefix_len |
3 |
markov | Markov chain prefix length |
-markov_answer_len |
10 |
markov | Max words in generated answer |
-markov_response_chance |
10 |
markov | Chance to respond (percent) |
-markov_state_file |
state.dat |
markov | State file path |
-markov_train_file |
train.txt |
markov | Training file path |
-quiz_questions_file |
questions.txt |
quiz | Questions file path |
-rss_feeds |
feeds.txt |
rss | Feed list file |
-rss_channel |
"" |
rss | Target channel for RSS |
-feeds_feeds |
feeds.txt |
feeds | Feed list file |
-feeds_channel |
"" |
feeds | Target channel for feeds |
-feeds_interval |
15 |
feeds | Poll interval (minutes) |
-webhook_port |
8080 |
webhook | Webhook listener port |
-webhook_token |
token.txt |
webhook | Token file path |
License
See LICENSE file (MIT).