thread-master/internal/library/placement/context.go

173 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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))
}