package wxwork import ( "context" "log/slog" "reflect" "strings" "sync" "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" "github.com/silenceper/wechat/v2/cache" "github.com/silenceper/wechat/v2/work" wxconfig "github.com/silenceper/wechat/v2/work/config" ) type SettingsLoader func(ctx context.Context, prefix string) (map[string]string, error) var runtime = struct { sync.RWMutex loader SettingsLoader client *work.Work config config.WxWorkConfig }{} // SetSettingsLoader enables demand-driven settings reads for embedded mode. // No save hook or hot-reload process is required: each enterprise WeChat // business call observes the latest values in the host settings table. func SetSettingsLoader(loader SettingsLoader) { runtime.Lock() runtime.loader = loader runtime.Unlock() } func Init() { if err := refresh(); err != nil { slog.Error("init enterprise WeChat settings failed", "error", err) } } func refresh() error { runtime.RLock() loader := runtime.loader runtime.RUnlock() wxCfg := config.Current().WxWork if loader != nil { settings, err := loader(context.Background(), config.SettingsPrefix) if err != nil { return err } cfg, err := config.FromSettings(settings) if err != nil { return err } wxCfg = cfg.WxWork } runtime.Lock() defer runtime.Unlock() if reflect.DeepEqual(runtime.config, wxCfg) { return nil } runtime.config = wxCfg runtime.client = nil if !wxCfg.Enabled || strings.TrimSpace(wxCfg.CorpID) == "" || strings.TrimSpace(wxCfg.CorpSecret) == "" { return nil } runtime.client = work.NewWork(&wxconfig.Config{ CorpID: wxCfg.CorpID, CorpSecret: wxCfg.CorpSecret, AgentID: wxCfg.AgentID, RasPrivateKey: wxCfg.RSAPrivateKey, Token: wxCfg.Token, EncodingAESKey: wxCfg.EncodingAESKey, Cache: cache.NewMemory(), }) return nil } func Enabled() bool { if err := refresh(); err != nil { slog.Error("read enterprise WeChat settings failed", "error", err) return false } runtime.RLock() defer runtime.RUnlock() return runtime.client != nil && runtime.config.Enabled } func GetWorkCli() *work.Work { if err := refresh(); err != nil { slog.Error("read enterprise WeChat settings failed", "error", err) return nil } runtime.RLock() defer runtime.RUnlock() return runtime.client } // CurrentConfig returns the latest enterprise WeChat settings from the host. func CurrentConfig() (config.WxWorkConfig, error) { if err := refresh(); err != nil { return config.WxWorkConfig{}, err } runtime.RLock() defer runtime.RUnlock() return runtime.config, nil }