173 lines
4.8 KiB
Go
173 lines
4.8 KiB
Go
package placement
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
|
||
"haixun-backend/internal/library/websearch"
|
||
)
|
||
|
||
// ConnectionPrefsInput mirrors persisted account connection prefs without importing threads_account.
|
||
type ConnectionPrefsInput struct {
|
||
DevMode bool
|
||
SearchSourceMode string
|
||
}
|
||
|
||
// MemberContext is resolved per login member (email account) + active Threads operating account.
|
||
type MemberContext struct {
|
||
TenantID string
|
||
OwnerUID string
|
||
ActiveAccountID string
|
||
DevMode bool
|
||
SearchSourceMode SearchSourceMode
|
||
AllowsThreadsAPI bool
|
||
AllowsBrave bool
|
||
AllowsCrawler bool
|
||
WebSearchProvider string
|
||
BraveAPIKey string
|
||
ExaAPIKey string
|
||
BraveCountry string
|
||
BraveSearchLang string
|
||
ExaUserLocation string
|
||
ApiConnected bool
|
||
BrowserConnected bool
|
||
ThreadsAPIAccessToken string
|
||
ScrapeReplies bool
|
||
RepliesPerPost int
|
||
}
|
||
|
||
type ResearchSettings struct {
|
||
WebSearchProvider string
|
||
BraveAPIKey string
|
||
ExaAPIKey string
|
||
BraveCountry string
|
||
BraveSearchLang string
|
||
ExaUserLocation string
|
||
ExpandStrategy string
|
||
}
|
||
|
||
func BuildMemberContext(
|
||
tenantID, ownerUID, activeAccountID string,
|
||
prefs ConnectionPrefsInput,
|
||
apiConnected, browserConnected bool,
|
||
research ResearchSettings,
|
||
scrapeReplies bool,
|
||
repliesPerPost int,
|
||
) MemberContext {
|
||
mode := ParseSearchSourceMode(prefs.SearchSourceMode)
|
||
if prefs.DevMode && strings.TrimSpace(prefs.SearchSourceMode) == "" {
|
||
mode = SearchSourceCrawler
|
||
}
|
||
allowsCrawler := ModeAllowsCrawler(mode)
|
||
allowsThreads := ModeAllowsThreadsAPI(mode)
|
||
allowsBrave := ModeAllowsBrave(mode)
|
||
|
||
country := strings.TrimSpace(research.BraveCountry)
|
||
if country == "" {
|
||
country = "tw"
|
||
}
|
||
lang := strings.TrimSpace(research.BraveSearchLang)
|
||
if lang == "" {
|
||
lang = "zh-hant"
|
||
}
|
||
userLocation := strings.TrimSpace(research.ExaUserLocation)
|
||
if userLocation == "" {
|
||
userLocation = "TW"
|
||
}
|
||
|
||
if repliesPerPost <= 0 {
|
||
repliesPerPost = 10
|
||
}
|
||
|
||
return MemberContext{
|
||
TenantID: tenantID,
|
||
OwnerUID: ownerUID,
|
||
ActiveAccountID: activeAccountID,
|
||
DevMode: prefs.DevMode,
|
||
SearchSourceMode: mode,
|
||
AllowsThreadsAPI: allowsThreads,
|
||
AllowsBrave: allowsBrave,
|
||
AllowsCrawler: allowsCrawler,
|
||
WebSearchProvider: string(websearch.ParseProvider(research.WebSearchProvider)),
|
||
BraveAPIKey: strings.TrimSpace(research.BraveAPIKey),
|
||
ExaAPIKey: strings.TrimSpace(research.ExaAPIKey),
|
||
BraveCountry: country,
|
||
BraveSearchLang: lang,
|
||
ExaUserLocation: userLocation,
|
||
ApiConnected: apiConnected,
|
||
BrowserConnected: browserConnected,
|
||
ScrapeReplies: scrapeReplies,
|
||
RepliesPerPost: repliesPerPost,
|
||
}
|
||
}
|
||
|
||
func (c MemberContext) PayloadFields() map[string]any {
|
||
return map[string]any{
|
||
"tenant_id": c.TenantID,
|
||
"owner_uid": c.OwnerUID,
|
||
"threads_account_id": c.ActiveAccountID,
|
||
"dev_mode": c.DevMode,
|
||
"search_source_mode": string(c.SearchSourceMode),
|
||
"allows_threads_api": c.AllowsThreadsAPI,
|
||
"allows_brave": c.AllowsBrave,
|
||
"allows_crawler": c.AllowsCrawler,
|
||
"web_search_provider": c.WebSearchProvider,
|
||
"brave_country": c.BraveCountry,
|
||
"brave_search_lang": c.BraveSearchLang,
|
||
"exa_user_location": c.ExaUserLocation,
|
||
"api_connected": c.ApiConnected,
|
||
"browser_connected": c.BrowserConnected,
|
||
"scrape_replies": c.ScrapeReplies,
|
||
"replies_per_post": c.RepliesPerPost,
|
||
}
|
||
}
|
||
|
||
func (c MemberContext) WebSearchProviderEnum() websearch.Provider {
|
||
return websearch.ParseProvider(c.WebSearchProvider)
|
||
}
|
||
|
||
func (c MemberContext) WebSearchAPIKey() string {
|
||
if c.WebSearchProviderEnum() == websearch.ProviderExa {
|
||
return strings.TrimSpace(c.ExaAPIKey)
|
||
}
|
||
return strings.TrimSpace(c.BraveAPIKey)
|
||
}
|
||
|
||
func (c MemberContext) WebSearchConfig() websearch.Config {
|
||
return websearch.ConfigFromMember(
|
||
c.BraveAPIKey,
|
||
c.ExaAPIKey,
|
||
c.WebSearchProvider,
|
||
c.BraveCountry,
|
||
c.BraveSearchLang,
|
||
c.ExaUserLocation,
|
||
)
|
||
}
|
||
|
||
func (c MemberContext) WebSearchProviderLabel() string {
|
||
return websearch.ProviderLabel(c.WebSearchProviderEnum())
|
||
}
|
||
|
||
func (c MemberContext) WebSearchDiscoverChannel() DiscoverChannel {
|
||
if c.WebSearchProviderEnum() == websearch.ProviderExa {
|
||
return DiscoverExa
|
||
}
|
||
return DiscoverBrave
|
||
}
|
||
|
||
func MissingWebSearchKey(research ResearchSettings) bool {
|
||
return strings.TrimSpace(websearch.ActiveAPIKey(websearch.ConfigFromMember(
|
||
research.BraveAPIKey,
|
||
research.ExaAPIKey,
|
||
research.WebSearchProvider,
|
||
research.BraveCountry,
|
||
research.BraveSearchLang,
|
||
research.ExaUserLocation,
|
||
))) == ""
|
||
}
|
||
|
||
func WebSearchKeyRequiredMessage(research ResearchSettings) string {
|
||
provider := websearch.ParseProvider(research.WebSearchProvider)
|
||
return fmt.Sprintf("請在設定頁設定 %s Search API key(跟隨此登入帳號)", websearch.ProviderLabel(provider))
|
||
}
|