82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
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)
|
||
}
|