87 lines
3.0 KiB
Go
87 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/channels/dingtalk"
|
|
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/secretstore"
|
|
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/settings"
|
|
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/store/postgres"
|
|
)
|
|
|
|
type dingTalkSettingsRouter struct{ controller *settings.Controller }
|
|
|
|
func (r *dingTalkSettingsRouter) Handle(ctx context.Context, m dingtalk.SettingsMessage) (bool, string, error) {
|
|
if r == nil || r.controller == nil {
|
|
return false, "", nil
|
|
}
|
|
if !r.controller.ShouldHandle(ctx, m.TenantKey, m.StaffID, m.Text) {
|
|
return false, "", nil
|
|
}
|
|
out, err := r.controller.Handle(ctx, settings.SettingInput{TenantKey: m.TenantKey, Channel: m.Channel, StaffID: m.StaffID, UnionID: m.UnionID, DisplayName: m.DisplayName, Department: m.Department, Text: m.Text, ConversationType: m.ConversationType, ConversationID: m.ConversationID, ConversationTitle: m.ConversationTitle})
|
|
return true, strings.TrimSpace(out), err
|
|
}
|
|
|
|
type settingsRuntime struct {
|
|
repository *postgres.SettingsRepository
|
|
bindings *validatedSettingsRepository
|
|
controller *settings.Controller
|
|
clientID string
|
|
secret string
|
|
secretRef string
|
|
}
|
|
|
|
func buildSettingsRuntime(ctx context.Context, store *postgres.Store, tenantKey string) (*settingsRuntime, error) {
|
|
tenantKey = strings.TrimSpace(tenantKey)
|
|
if tenantKey == "" {
|
|
return nil, errors.New("DOBOTAI_TENANT_KEY is required")
|
|
}
|
|
repo, err := postgres.NewSettingsRepository(store)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
root := strings.TrimSpace(os.Getenv("DOBOTAI_SECRET_DIR"))
|
|
if root == "" {
|
|
home, homeErr := os.UserHomeDir()
|
|
if homeErr != nil {
|
|
return nil, homeErr
|
|
}
|
|
root = filepath.Join(home, ".config", "dobotai", "secrets")
|
|
}
|
|
secrets, err := secretstore.New(root)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, err := repo.PrepareDingTalkRuntimeStart(ctx, tenantKey); err != nil {
|
|
return nil, err
|
|
}
|
|
clientID, secretRef, _, err := repo.ActiveDingTalkConfig(ctx, tenantKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var secret string
|
|
if secretRef != "" {
|
|
secret, err = secrets.Get(secretRef)
|
|
if err != nil {
|
|
return nil, errors.New("active DingTalk secret is unavailable")
|
|
}
|
|
}
|
|
if clientID == "" && strings.TrimSpace(os.Getenv("DINGTALK_CLIENT_ID")) != "" && strings.TrimSpace(os.Getenv("DINGTALK_CLIENT_SECRET")) != "" {
|
|
clientID, secret = strings.TrimSpace(os.Getenv("DINGTALK_CLIENT_ID")), strings.TrimSpace(os.Getenv("DINGTALK_CLIENT_SECRET"))
|
|
secretRef, err = secrets.Put("dingtalk", secret)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err = repo.SaveDingTalkConfig(ctx, tenantKey, clientID, secretRef, true); err != nil {
|
|
_ = secrets.Delete(secretRef)
|
|
return nil, err
|
|
}
|
|
}
|
|
validatedRepo := &validatedSettingsRepository{SettingsRepository: repo, clientID: clientID, secret: secret}
|
|
return &settingsRuntime{repository: repo, bindings: validatedRepo, controller: settings.NewController(validatedRepo), clientID: clientID, secret: secret, secretRef: secretRef}, nil
|
|
}
|