haixunMaster/haixun-backend/internal/library/threadspost/limits.go

101 lines
2.5 KiB
Go
Raw Permalink Normal View History

2026-06-25 08:20:03 +00:00
package threadspost
import (
"fmt"
"strings"
)
// Threads Graph API text post hard limit (main post body).
const MaxPublishRunes = 500
// Threads reply/comment limit (outreach, not main post).
const MaxReplyRunes = 1000
// ViralSweetMin/Max: engagement sweet spot on Threads feed (Buffer / creator data, 20242026).
const ViralSweetMin = 80
const ViralSweetMax = 220
// ViralSoftWarn: engagement tends to drop beyond this length in the main visible post.
const ViralSoftWarn = 300
type LengthBand string
const (
2026-06-25 09:34:28 +00:00
BandEmpty LengthBand = "empty"
BandTooShort LengthBand = "too_short"
BandSweet LengthBand = "sweet"
BandLong LengthBand = "long"
BandOverSoft LengthBand = "over_soft"
BandOverHard LengthBand = "over_hard"
2026-06-25 08:20:03 +00:00
)
func RuneLen(text string) int {
return len([]rune(strings.TrimSpace(text)))
}
func ClampPublish(text string) string {
text = strings.TrimSpace(text)
runes := []rune(text)
if len(runes) > MaxPublishRunes {
return string(runes[:MaxPublishRunes])
}
return text
}
func PublishBand(text string) LengthBand {
n := RuneLen(text)
switch {
case n == 0:
return BandEmpty
case n < ViralSweetMin:
return BandTooShort
case n <= ViralSweetMax:
return BandSweet
case n <= ViralSoftWarn:
return BandLong
case n <= MaxPublishRunes:
return BandOverSoft
default:
return BandOverHard
}
}
func ValidatePublish(text string) error {
if strings.TrimSpace(text) == "" {
return fmt.Errorf("貼文內文不可為空")
}
n := RuneLen(text)
if n > MaxPublishRunes {
return fmt.Errorf("貼文超過 Threads 上限 %d 字(目前 %d 字)", MaxPublishRunes, n)
}
return nil
}
func ValidateReply(text string) error {
if strings.TrimSpace(text) == "" {
return fmt.Errorf("留言內文不可為空")
}
n := RuneLen(text)
if n > MaxReplyRunes {
return fmt.Errorf("留言超過 Threads 上限 %d 字(目前 %d 字)", MaxReplyRunes, n)
}
return nil
}
func PublishHint(text string) string {
switch PublishBand(text) {
case BandTooShort:
return fmt.Sprintf("偏短(爆款常見 %d%d 字)", ViralSweetMin, ViralSweetMax)
case BandSweet:
return fmt.Sprintf("長度適中(爆款常見 %d%d 字)", ViralSweetMin, ViralSweetMax)
case BandLong:
return fmt.Sprintf("略長(超過 %d 字互動可能下降)", ViralSoftWarn)
case BandOverSoft:
return fmt.Sprintf("接近 Threads 主文上限 %d 字", MaxPublishRunes)
case BandOverHard:
return fmt.Sprintf("超過 Threads 上限 %d 字,請縮短", MaxPublishRunes)
default:
return ""
}
2026-06-25 09:34:28 +00:00
}