2026-06-26 08:37:04 +00:00
|
|
|
package placement
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"regexp"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var threadsPostURLRe = regexp.MustCompile(`(?i)threads\.(?:com|net)/@([^/]+)/post/([^/?#]+)`)
|
|
|
|
|
|
|
|
|
|
type ParsedThreadsPost struct {
|
|
|
|
|
Permalink string
|
|
|
|
|
ExternalID string
|
|
|
|
|
Author string
|
|
|
|
|
Text string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ParseThreadsPostFromWebResult(title, snippet, url string) (ParsedThreadsPost, bool) {
|
|
|
|
|
permalink := normalizeThreadsPermalink(url)
|
|
|
|
|
if permalink == "" {
|
|
|
|
|
return ParsedThreadsPost{}, false
|
|
|
|
|
}
|
|
|
|
|
match := threadsPostURLRe.FindStringSubmatch(permalink)
|
|
|
|
|
if len(match) < 3 {
|
|
|
|
|
return ParsedThreadsPost{}, false
|
|
|
|
|
}
|
2026-07-01 08:42:51 +00:00
|
|
|
text := strings.TrimSpace(strings.Join(filterNonEmpty([]string{strings.TrimSpace(title), strings.TrimSpace(snippet)}), " — "))
|
|
|
|
|
if text == "" {
|
|
|
|
|
text = strings.TrimSpace(title)
|
|
|
|
|
}
|
|
|
|
|
if text == "" {
|
|
|
|
|
text = strings.TrimSpace(snippet)
|
|
|
|
|
}
|
|
|
|
|
if len([]rune(text)) < 6 {
|
2026-06-26 08:37:04 +00:00
|
|
|
return ParsedThreadsPost{}, false
|
|
|
|
|
}
|
|
|
|
|
return ParsedThreadsPost{
|
|
|
|
|
Permalink: permalink,
|
|
|
|
|
ExternalID: match[2],
|
|
|
|
|
Author: match[1],
|
|
|
|
|
Text: text,
|
|
|
|
|
}, true
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-01 08:42:51 +00:00
|
|
|
func filterNonEmpty(items []string) []string {
|
|
|
|
|
out := make([]string, 0, len(items))
|
|
|
|
|
for _, item := range items {
|
|
|
|
|
if strings.TrimSpace(item) != "" {
|
|
|
|
|
out = append(out, item)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return out
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-26 08:37:04 +00:00
|
|
|
func normalizeThreadsPermalink(raw string) string {
|
|
|
|
|
raw = strings.TrimSpace(raw)
|
|
|
|
|
if raw == "" {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
raw = strings.Split(raw, "?")[0]
|
|
|
|
|
raw = strings.Split(raw, "#")[0]
|
|
|
|
|
if threadsPostURLRe.MatchString(raw) {
|
|
|
|
|
return raw
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|