Skip to content

Module

go
type Module interface {
	Name() string
	Strings() map[string]string
	Init(client *CustomTelegramClient, db *Database) error
	ClientReady() error
	OnUnload() error
	OnDlmod() error
	Commands() map[string]CommandHandler
	Watchers() []WatcherHandler
}

Embedding goroku.Base supplies every method except Name and Commands.

Methods

Name() string

The module's identity — in .help, .unloadmod, the config UI, and as the storage owner key. Must be unique across loaded modules.

Strings() map[string]string

Translatable text. See Translations for the special key prefixes. Base returns nil, which is valid.

Init(client, db) error

Called once at registration, before any handler can run. Base has already populated Client, DB and Translator.

Returning an error aborts registration and the module is not loaded.

ClientReady() error

Called once the Telegram client is connected. Use for work that needs the API; Init can run before the connection exists.

OnUnload() error

Called when the module is being removed. Release goroutines and handles.

A panic here is recovered and logged, and removal continues.

OnDlmod() error

Called right after installation via .dlmod.

Commands() map[string]CommandHandler

Command word to handler. The key is what users type after the prefix, matched case-insensitively. Returning nil is valid for a watcher-only module.

Watchers() []WatcherHandler

Handlers invoked for every message. Base returns nil.

Handler types

go
type CommandHandler func(msg *Message) error
type WatcherHandler func(msg *Message) error

Lifecycle order

construct → bind Base → Init → [registered] → ClientReady

                             commands / watchers

                                 OnUnload

A minimal module

go
package modules

import "goroku/goroku"

type Ping struct{ goroku.Base }

func (m *Ping) Name() string { return "Ping" }

func (m *Ping) Commands() map[string]goroku.CommandHandler {
	return map[string]goroku.CommandHandler{
		"ping": func(msg *goroku.Message) error { return msg.Answer("🏓 pong") },
	}
}

Implementing without Base

Base is optional. A module that implements all eight methods itself works exactly the same, and modules written before Base existed continue to load unchanged.

Released under the GNU AGPL v3 License.