Skip to content

Конфигурация

Плагины определяют типизированную схему конфигурации. Хост использует её для валидации значений, а админ-панель генерирует форму на её основе.

Не путать с конфигурацией платформы

Эта страница описывает конфигурацию WASM-плагинов.

Конфигурация самого SuperBotGo host (config.yaml, BOT_*, PostgreSQL, Redis, каналы, S3, TSU, SMTP) вынесена отдельно: Конфигурация платформы.

Описание схемы

Схема задаётся в поле Config структуры Plugin с помощью ConfigFields:

go
import wasmplugin "github.com/SuperBotForge/sdk/go-sdk"

wasmplugin.Plugin{
    // ...
    Config: wasmplugin.ConfigFields(
        wasmplugin.String("api_key", "API-ключ внешнего сервиса").Required().Sensitive(),
        wasmplugin.String("greeting", "Приветственное сообщение").Default("Привет!"),
        wasmplugin.Integer("timeout", "Таймаут в секундах").Default(30).Min(1).Max(300),
        wasmplugin.Number("rate", "Множитель скорости").Default(1.0).Min(0.1).Max(10.0),
        wasmplugin.Bool("verbose", "Подробное логирование"),
        wasmplugin.Enum("theme", "Цветовая тема", "light", "dark", "auto"),
    ),
}

Типы полей

КонструкторJSON Schema типОписание
String(key, desc)"string"Строковое значение
StringArray(key, desc)"array" of "string"Массив строк
Integer(key, desc)"integer"Целое число
Number(key, desc)"number"Число с плавающей точкой
Bool(key, desc)"boolean"Булево значение
Enum(key, desc, values...)"string" + enumОдно из перечисленных значений

Каждый конструктор принимает key (ключ для доступа из кода) и desc (описание, отображаемое в UI). Enum дополнительно принимает список допустимых значений.

Зарезервированные ключи

Ключи "databases" и "requirements" зарезервированы SDK:

  • databases автоматически формируется из Database() requirements
  • requirements используется для requirement-driven config, например requirements.http.<name>

Попытка использовать их в ConfigFields вызовет panic при инициализации плагина.

Модификаторы

Модификаторы вызываются цепочкой (chaining) и уточняют правила валидации:

МетодПрименимостьОписание
.Default(v)Все типыЗначение по умолчанию
.Required()Все типыОбязательное поле
.Min(n)Integer, NumberМинимальное значение
.Max(n)Integer, NumberМаксимальное значение
.MinLen(n)StringМинимальная длина строки
.MaxLen(n)StringМаксимальная длина строки
.Pattern(re)StringВалидация по регулярному выражению
.Sensitive()StringОтображать как пароль в UI, не логировать значение

Примеры

go
// Обязательная строка длиной от 3 до 100 символов
wasmplugin.String("name", "Название проекта").Required().MinLen(3).MaxLen(100)

// Целое число от 1 до 60 со значением по умолчанию
wasmplugin.Integer("interval", "Интервал в минутах").Default(5).Min(1).Max(60)

// Строка, валидируемая по regex
wasmplugin.String("email", "Email администратора").
    Pattern(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`).
    Required()

// Секретный ключ - скрыт в UI и логах
wasmplugin.String("token", "OAuth-токен").Required().Sensitive()

Чтение конфигурации в обработчиках

Используйте ctx.Config(key, fallback) в любом обработчике триггера:

go
Handler: func(ctx *wasmplugin.EventContext) error {
    greeting := ctx.Config("greeting", "Привет!")
    timeout := ctx.Config("timeout", "30")
    verbose := ctx.Config("verbose", "false")

    ctx.Reply(greeting)
    return nil
}

Значения возвращаются как строки

ctx.Config() всегда возвращает string. При необходимости парсите в нужный тип:

go
timeout, _ := strconv.Atoi(ctx.Config("timeout", "30"))

Второй аргумент fallback - значение, возвращаемое если ключ не задан в конфигурации.

Чтение конфигурации в CallbackContext

Конфигурация также доступна в callback-функциях шагов (валидация, динамические опции, пагинация, условия):

go
wasmplugin.NewStep("mode").
    DynamicOptions("Режим:", func(ctx *wasmplugin.CallbackContext) []wasmplugin.Option {
        theme := ctx.Config("theme", "light")
        opts := []wasmplugin.Option{
            wasmplugin.Opt("Стандартный", "standard"),
        }
        if theme == "dark" {
            opts = append(opts, wasmplugin.Opt("Ночной", "night"))
        }
        return opts
    })

Сигнатура та же: ctx.Config(key, fallback) string.

Requirement-driven config

Для некоторых requirement types конфигурация живёт не в корне plugin config, а в reserved namespace requirements.

Сейчас хост реально применяет это для http requirement.

HTTP policy schema

go
Requirements: []wasmplugin.Requirement{
    wasmplugin.HTTP("Запросы к GitHub API").
        Name("github").
        WithConfig(wasmplugin.HTTPPolicyConfig()).
        Build(),
}

В admin UI это сохранится как часть обычного plugin config:

json
{
  "requirements": {
    "http": {
      "github": {
        "allowed_hosts": ["api.github.com"],
        "allowed_methods": ["GET"],
        "max_request_body_bytes": 0,
        "max_response_body_bytes": 1048576
      }
    }
  }
}

Если имя requirement не задано, используется default.

Host-конфигурация user session

Для frontend login через TSU host использует отдельную cookie-сессию. Для неё нужно задать secret в конфигурации приложения:

yaml
user_auth:
  session_secret: "change-me"

Env-переменная:

  • BOT_USER__AUTH_SESSION__SECRET

Если secret не задан, host сгенерирует случайный ключ при старте. Это подходит для локальной разработки, но сессии будут сбрасываться после рестарта.

Callback при конфигурации (OnConfigure)

OnConfigure вызывается при первичной загрузке/активации плагина. Используйте для дополнительной валидации или подготовки данных:

go
import "encoding/json"

wasmplugin.Plugin{
    // ...
    OnConfigure: func(config []byte) error {
        var cfg struct {
            APIKey  string `json:"api_key"`
            Timeout int    `json:"timeout"`
        }
        if err := json.Unmarshal(config, &cfg); err != nil {
            return err
        }
        if cfg.APIKey != "" && len(cfg.APIKey) < 10 {
            return fmt.Errorf("api_key слишком короткий")
        }
        return nil
    },
}
  • Аргумент config - сырой JSON с полями конфигурации.
  • Если функция возвращает ошибку, конфигурация отклоняется и не сохраняется.
  • Если OnConfigure не задан, конфигурация сохраняется без дополнительных проверок (только валидация по схеме).

Обновление конфигурации без reload

Если плагин реализует OnReconfigure и в host включён wasm.reconfigure_enabled, host использует отдельный action reconfigure вместо полного reload:

go
OnReconfigure: func(previousConfig, nextConfig []byte) error {
    // Сравнить старое и новое состояние, обновить внешние подключения,
    // прогреть кеш, проверить инварианты.
    return nil
},

Семантика такая:

  1. Host валидирует новый config по schema.
  2. Вызывает OnReconfigure(previous, next).
  3. Только после успешного apply сохраняет новый config.

Поведение по умолчанию

wasm.reconfigure_enabled по умолчанию включён. Если ключ не задан, используется значение true.

Если OnReconfigure не реализован или wasm.reconfigure_enabled=false, host применяет новый config через controlled reload того же wasm-бинаря.