No description
  • Go 97.9%
  • Makefile 1.1%
  • Dockerfile 1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Andreas Neue 05307acbae
Some checks failed
Build and push docker image / docker (push) Successful in 2m38s
Perform image scan with trivy / trivy-image-scan (push) Failing after 52s
Perform repo scan with trivy / trivy-sast-scan (push) Failing after 23s
fix: harden webhook, weather, and IRC auth handling
2026-09-04 17:49:55 +02:00
.forgejo/workflows checkout@v6 2026-04-29 14:59:38 +02:00
cmd/flokati fix: harden webhook, weather, and IRC auth handling 2026-09-04 17:49:55 +02:00
modules fix: harden webhook, weather, and IRC auth handling 2026-09-04 17:49:55 +02:00
util fix 2019-07-31 15:27:01 +02:00
.gitignore forgejo actions, gitignore 2026-03-18 11:53:00 +01:00
Dockerfile go mod fuckup 2026-04-30 11:00:33 +02:00
go.mod go mod fuckup 2026-04-30 11:02:29 +02:00
go.sum go mod fuckup 2026-04-30 11:00:33 +02:00
LICENSE Changed copyright holders 2016-03-15 18:35:49 +01:00
Makefile things ... 2026-03-18 11:03:33 +01:00
README.md docs: add installation, running, and plugin structure details 2026-09-04 11:34:22 +02:00

Build Status

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:

  1. Stores the shared output channel in SayCh.
  2. Filters MsgFuncs and RunFuncs to only include modules listed in the comma-separated mods string.
  3. Launches all registered RunFuncs as 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

  1. Create a new file in modules/ (e.g. modules/mymod.go).
  2. Register your handler(s) in an init() function:
    func init() {
        MsgFuncs["mymod"] = mymodHandleMessage
        // Optionally for background tasks:
        // RunFuncs["mymod"] = mymodRun
    }
    
  3. Implement your handler:
    func mymodHandleMessage(m *Message) {
        if strings.HasPrefix(m.Text, "!mymod") {
            SayCh <- m.Channel + "\nHello from mymod!"
        }
    }
    
  4. Add mymod to the -mods flag when running flokati.

Installation

Prerequisites

  • Go 1.21 or later
  • git
  • make
  • 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:

  1. Build stage (golang:1.26.2): compiles the binary with CGO enabled.
  2. 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).