Documentation
¶
Overview ¶
Package config handles loading, validating, and merging notification pipeline configurations.
Index ¶
Constants ¶
const ( DefaultVoiceName = "nova" DefaultVoiceModel = "tts-1" DefaultVoiceSpeed = 1.0 )
Voice generation defaults.
const DefaultAFKThreshold = 300
DefaultAFKThreshold is the default idle-time threshold in seconds.
const DefaultMaxDesktops = 4
DefaultMaxDesktops is the default upper bound for the virtual desktop index.
const DefaultVolume = 100
DefaultVolume is the default playback volume (0-100).
Variables ¶
This section is empty.
Functions ¶
func FindPath ¶ added in v0.2.12
FindPath resolves the config file path using the same resolution order as Load. Returns the resolved path or an error if no config file is found.
func MatchProfile ¶ added in v0.2.17
MatchProfile returns the first profile whose match rule is satisfied by the given working directory, or "default" if none match. Profiles are checked alphabetically for deterministic tiebreaking. Profiles without a match rule are skipped.
Types ¶
type Action ¶
type Action struct {
CooldownSeconds int `json:"cooldown_seconds,omitempty"`
Steps []Step `json:"steps"`
}
Action holds an ordered list of steps to execute.
type Config ¶
type Config struct {
Options Options `json:"config"`
Profiles map[string]Profile `json:"profiles"`
Builtin bool `json:"-"` // true when using built-in defaults (no config file)
}
Config holds the top-level configuration: global options and profiles.
func DefaultConfig ¶ added in v0.2.25
func DefaultConfig() Config
DefaultConfig returns a built-in config with a "default" profile containing four basic actions (ready, error, done, attention) using only local audio steps. Used as a fallback when no config file exists so that basic commands work out of the box without any setup.
func Load ¶
Load reads and parses a config file. It tries, in order:
- explicitPath (if non-empty)
- notify-config.json next to the running binary
- ~/.config/notify/notify-config.json
When no config file is found and explicitPath is empty, Load returns DefaultConfig() so that basic commands work without any setup.
func (*Config) UnmarshalJSON ¶
UnmarshalJSON sets defaults then decodes the JSON structure. Go's json.Unmarshal merges into existing struct fields, so only values present in JSON override the defaults.
type Credentials ¶
type Credentials struct {
DiscordWebhook string `json:"discord_webhook,omitempty"`
SlackWebhook string `json:"slack_webhook,omitempty"`
TelegramToken string `json:"telegram_token,omitempty"`
TelegramChatID string `json:"telegram_chat_id,omitempty"`
OpenAIAPIKey string `json:"openai_api_key,omitempty"`
MQTTUsername string `json:"mqtt_username,omitempty"`
MQTTPassword string `json:"mqtt_password,omitempty"`
}
Credentials holds secret values for remote notification actions.
func MergeCredentials ¶ added in v0.2.13
func MergeCredentials(global Credentials, profile *Credentials) Credentials
MergeCredentials returns global credentials with any non-empty profile fields overriding. A nil profile returns global unchanged. The profile parameter is a pointer so callers can pass nil to indicate "no profile-level overrides" without needing a zero-value Credentials.
type MatchRule ¶ added in v0.2.17
MatchRule defines conditions for automatic profile selection. All non-empty fields must match (AND logic). Dir is a substring check against the working directory (forward-slash normalized). Env is a KEY=VALUE check against an environment variable.
type Options ¶
type Options struct {
AFKThresholdSeconds int `json:"afk_threshold_seconds,omitempty"`
DefaultVolume int `json:"default_volume,omitempty"`
Log bool `json:"log,omitempty"`
Echo bool `json:"echo,omitempty"`
Cooldown bool `json:"cooldown,omitempty"`
CooldownSeconds int `json:"cooldown_seconds,omitempty"`
ExitCodes map[string]string `json:"exit_codes,omitempty"`
OutputLines int `json:"output_lines,omitempty"`
HeartbeatSeconds int `json:"heartbeat_seconds,omitempty"`
ShellHookThreshold int `json:"shell_hook_threshold,omitempty"`
Storage string `json:"storage,omitempty"` // "sqlite" (default) or "file"
RetentionDays int `json:"retention_days,omitempty"` // 0 = keep forever, >0 = auto-prune
MaxDesktops int `json:"max_desktops,omitempty"` // 0 = default (4)
Voice VoiceConfig `json:"openai_voice,omitempty"`
Credentials Credentials `json:"credentials,omitempty"`
}
Options holds global settings parsed from the "config" key.
func (*Options) MaxDesktopsLimit ¶ added in v0.2.40
MaxDesktops returns the effective desktop limit from config, falling back to DefaultMaxDesktops.
type Profile ¶
type Profile struct {
Extends string `json:"-"`
Aliases []string `json:"-"`
Desktop *int `json:"-"` // 1-4, virtual desktop to switch to on toast click
Credentials *Credentials `json:"-"`
Match *MatchRule `json:"-"`
Actions map[string]Action `json:"-"`
}
Profile holds a set of actions and an optional parent profile name. When "extends" is set, the profile inherits all actions from the parent, with its own actions taking priority on conflicts. Aliases provide shorthand names for the profile. Credentials override global credentials field-by-field (nil = use global only). Match defines conditions for automatic profile selection (nil = never auto-selected).
func (Profile) MarshalJSON ¶ added in v0.2.20
MarshalJSON serializes a Profile back to the flat JSON format used by UnmarshalJSON. Without this, json.Marshal produces {} because all fields have json:"-" tags.
func (*Profile) UnmarshalJSON ¶ added in v0.2.11
UnmarshalJSON extracts the optional "extends" key and parses all remaining keys as actions. This keeps the JSON format flat:
{ "extends": "default", "ready": { "steps": [...] } }
type Step ¶
type Step struct {
Type string `json:"type"` // "sound" | "say" | "toast" | "discord" | "discord_voice" | "slack" | "telegram" | "telegram_audio" | "telegram_voice" | "webhook" | "plugin" | "mqtt"
Sound string `json:"sound,omitempty"` // type=sound
Text string `json:"text,omitempty"` // type=say, discord, discord_voice, slack, telegram, telegram_audio, webhook, plugin, mqtt
Title string `json:"title,omitempty"` // type=toast
Message string `json:"message,omitempty"` // type=toast
URL string `json:"url,omitempty"` // type=webhook
Headers map[string]string `json:"headers,omitempty"` // type=webhook
Command string `json:"command,omitempty"` // type=plugin
Timeout *int `json:"timeout,omitempty"` // type=plugin (seconds, default 10)
Broker string `json:"broker,omitempty"` // type=mqtt
Topic string `json:"topic,omitempty"` // type=mqtt
Retain bool `json:"retain,omitempty"` // type=mqtt (default false)
QoS *int `json:"qos,omitempty"` // type=mqtt (0, 1, or 2; default 0)
Volume *int `json:"volume,omitempty"` // per-step override, nil = use default
When string `json:"when,omitempty"` // "" | "never" | "afk" | "present" | "run" | "direct" | "hours:X-Y" | "long:DURATION"
}
Step is a single unit of work within an action.
type VoiceConfig ¶ added in v0.2.25
type VoiceConfig struct {
Provider string `json:"provider,omitempty"` // "openai" (default, only option)
Model string `json:"model,omitempty"` // "tts-1" or "tts-1-hd"
Voice string `json:"voice,omitempty"` // alloy|echo|fable|onyx|nova|shimmer
Speed float64 `json:"speed,omitempty"` // 0.25-4.0, default 1.0
MinUses int `json:"min_uses,omitempty"` // minimum event log occurrences before generating (default 3)
}
VoiceConfig holds settings for AI voice generation.