Skip to content

Устройство модуля ​

Каждый модуль реализует goroku.Module. Встраивание goroku.Base даёт значение по умолчанию для всего, кроме Name и Commands, — только эти два метода писать обязательно.

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
}

Обязательные ​

Name ​

Идентичность модуля в .help, .unloadmod и интерфейсе настроек. Это же имя типа Go и ключ, под которым хранятся ваши данные.

go
func (m *Weather) Name() string { return "Weather" }

Commands ​

Сопоставляет слово команды обработчику. Пользователь набирает слово после префикса, поэтому "weather" превращается в .weather.

go
func (m *Weather) Commands() map[string]goroku.CommandHandler {
	return map[string]goroku.CommandHandler{
		"weather":  m.WeatherCmd,
		"forecast": m.ForecastCmd,
	}
}

CommandHandler — это func(msg *goroku.Message) error. Возврат ошибки покажет её пользователю; диспетчер к тому же перехватывает паники, так что падение обработчика не уронит бота.

Необязательные, со значениями из Base ​

Strings ​

Текст для пользователя и источник для m.T. Два префикса ключей особые:

КлючСмысл
nameОтображаемое имя в .help
_cls_docЧто делает модуль
_cmd_doc_<команда>Что делает эта команда

Все остальные ключи — ваши, доставайте их через m.T.

go
func (m *Weather) Strings() map[string]string {
	return map[string]string{
		"name":             "Weather",
		"_cls_doc":         "Погода в городе",
		"_cmd_doc_weather": "[город] — показать погоду",
		"no_city":          "❌ <b>Какой город?</b>",
	}
}

Init ​

Выполняется один раз при регистрации, до того как сработает любая команда. Base к этому моменту уже заполнил m.Client, m.DB и m.Translator, так что Init нужен только для вашей собственной настройки.

go
func (m *Weather) Init(client *goroku.CustomTelegramClient, db *goroku.Database) error {
	if err := m.Base.Init(client, db); err != nil {
		return err
	}
	m.cache = make(map[string]string)
	return nil
}

Вызывайте m.Base.Init первым

Загрузчик заполняет поля до вызова Init, поэтому в обычной работе этот вызов избыточен. Всё равно оставьте его: так модуль будет работать и когда его создают напрямую в тесте, минуя загрузчик.

ClientReady ​

Выполняется, когда соединение с Telegram установлено. Сюда — всё, чему нужен API при старте; Init может отработать раньше, чем клиент подключится.

go
func (m *Weather) ClientReady() error {
	me := m.Client.Me()
	_ = me
	return nil
}

OnUnload ​

Выполняется при удалении модуля. Здесь освобождайте горутины, таймеры и файловые дескрипторы.

go
func (m *Weather) OnUnload() error {
	close(m.stop)
	return nil
}

WARNING

Паника в OnUnload перехватывается и логируется, но модуль всё равно удаляется. Не полагайтесь на OnUnload там, где очистка критична для корректности.

OnDlmod ​

Выполняется сразу после установки через .dlmod. Удобно для одноразового приветствия или начальной настройки.

Watchers ​

Обработчики, которые видят каждое сообщение, а не только команды. См. Вотчеры.

За пределами интерфейса ​

Часть возможностей подключается отдельными интерфейсами — просто объявите метод, и Goroku его подхватит:

ИнтерфейсМетодНазначение
ModuleWithMetaCommandMetas()Алиасы и ограничения
ModuleWithConfigSchemaConfigSchema()Типизированные настройки
ModuleWithConfigReadyConfigReady(map[string]any)Реакция на смену настроек
ModuleWithTranslationAliasesTranslationAliases()Дополнительные имена файлов перевода

Полный список — в Опциональных интерфейсах.

Released under the GNU AGPL v3 License.