haixunMaster/haixun-backend/internal/library/placement/discover.go

82 lines
2.2 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 (
"context"
"fmt"
)
// DiscoverChannel identifies which backend fulfilled a placement discover query.
type DiscoverChannel string
const (
DiscoverThreadsAPI DiscoverChannel = "threads_api"
DiscoverBrave DiscoverChannel = "brave"
DiscoverCrawler DiscoverChannel = "crawler"
)
// DiscoverRequest is used by scan jobs; expand-graph only uses Brave knowledge_expand.
type DiscoverRequest struct {
Query string
Keyword string // plain tag for crawler; optional
Recency bool
Limit int
Member MemberContext
Crawler CrawlerSearchFn
}
type DiscoverPost struct {
Text string
Permalink string
ExternalID string
Author string
PostedAt string
LikeCount int
ReplyCount int
Source DiscoverChannel
}
// Discover runs keyword discovery respecting the member's connection prefs.
// Formal mode (dev_mode=false) never falls back to crawler.
func Discover(ctx context.Context, req DiscoverRequest) ([]DiscoverPost, DiscoverChannel, error) {
m := req.Member
if m.DevMode {
if !m.BrowserConnected {
return nil, "", fmt.Errorf("開發模式需先同步 Chrome Session")
}
if req.Crawler == nil {
return nil, DiscoverCrawler, fmt.Errorf("crawler search not configured")
}
keyword := CrawlerKeywordFromQuery(req.Query, req.Keyword)
if keyword == "" {
return nil, DiscoverCrawler, fmt.Errorf("crawler keyword is empty")
}
posts, err := req.Crawler(ctx, m, keyword, req.Limit)
if err != nil {
return nil, DiscoverCrawler, err
}
return posts, DiscoverCrawler, nil
}
if m.AllowsThreadsAPI {
if !m.ApiConnected {
return nil, "", fmt.Errorf("正式模式需先完成 Threads API 連線")
}
posts, err := keywordSearchViaThreadsAPI(ctx, req)
if err == nil && len(posts) > 0 {
return posts, DiscoverThreadsAPI, nil
}
if err != nil && !m.AllowsBrave {
return nil, "", err
}
}
if m.AllowsBrave {
if m.BraveAPIKey == "" {
return nil, "", fmt.Errorf("請在設定頁設定 Brave Search API key跟隨此登入帳號")
}
return nil, DiscoverBrave, fmt.Errorf("brave threads discover delegated to worker")
}
return nil, "", fmt.Errorf("目前搜尋來源模式無可用管道:%s", m.SearchSourceMode)
}