Konfiguration
Deklariere ConfigSchema, und dein Modul bekommt eine Einstellungsoberfläche in .config, typisierte Validierung und Persistenz — ohne dass du davon etwas schreibst.
Einstellungen deklarieren
var _ goroku.ModuleWithConfigSchema = (*Weather)(nil)
func (m *Weather) ConfigSchema() []goroku.ConfigField {
return []goroku.ConfigField{
{
Key: "units",
Type: "choice",
Default: "metric",
Validator: &goroku.ChoiceValidator{PossibleValues: []string{"metric", "imperial"}},
},
{
Key: "api_key",
Type: "string",
Default: "",
Validator: &goroku.StringValidator{MaxLen: 128},
Secret: true,
},
{
Key: "cache_minutes",
Type: "int",
Default: 10,
Validator: &goroku.IntegerValidator{},
},
}
}Die Zeile var _ = lohnt sich: Sie lässt den Compiler bestätigen, dass du das Interface triffst, statt die Methode stillschweigend ignorieren zu lassen.
Einstellungen lesen
Die Werte liegen in der Datenbank unter deinem Modulnamen:
units := m.DB.GetString(m.Name(), "units", "metric")
minutes := m.DB.GetInt(m.Name(), "cache_minutes", 10)Auf Änderungen reagieren
ConfigReady wird beim Start und erneut bei jeder Änderung aufgerufen. Gib einen Fehler zurück, um die Änderung abzulehnen — der Nutzer sieht ihn, und der alte Wert bleibt.
func (m *Weather) ConfigReady(config map[string]any) error {
units, ok := config["units"].(string)
if !ok {
return fmt.Errorf("units muss ein String sein, ist aber %T", config["units"])
}
m.mu.Lock()
m.units = units
m.mu.Unlock()
return nil
}Laut validieren
Ist ein Wert unbrauchbar, gib einen Fehler zurück, der benennt was fehlt. Ihn anzunehmen und still nichts zu tun lässt den Nutzer mit einer Einstellung zurück, die angewendet aussieht, es aber nicht ist.
Feldtypen und Validatoren
Type | Validator | Anmerkungen |
|---|---|---|
bool | &BooleanValidator{} | |
int | &IntegerValidator{} | Grenzen über Minimum/HasMin, Maximum/HasMax |
float | &FloatValidator{} | |
string | &StringValidator{MaxLen: n} | Auch MinLen |
choice | &ChoiceValidator{PossibleValues: ...} | Feste Menge |
series | &SeriesValidator{} | Werteliste |
url | &URLValidator{} | |
link | &LinkValidator{} | Telegram-Links |
hidden | &HiddenValidator{} | Wird nicht angezeigt |
Weiter verfügbar: RegExpValidator, TelegramIDValidator, EmojiValidator, EntityLikeValidator, UnionValidator, NoneTypeValidator.
Geheimnisse
Secret: true markiert einen Wert als in Logs geschwärzt und im Backup durch einen Platzhalter ersetzt. Beim Wiederherstellen bleibt der laufende Wert erhalten, statt vom Marker überschrieben zu werden.
Nutze es für API-Schlüssel, Tokens und Passwörter. Es kostet ein Feld und beseitigt eine ganze Klasse von Unfällen.
Einstellungen dokumentieren
Ein Strings-Schlüssel mit dem Präfix _cfg_ wird zur Beschreibung in der Einstellungsoberfläche:
func (m *Weather) Strings() map[string]string {
return map[string]string{
"name": "Weather",
"_cfg_units": "Temperatureinheiten: metric oder imperial",
"_cfg_api_key": "API-Schlüssel des Wetteranbieters",
"_cfg_cache_minutes": "Wie lange die Vorhersage einer Stadt zwischengespeichert wird",
}
}