thread-master/backend/internal/library/threadspost/limits.go

101 lines
2.5 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 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 (
BandEmpty LengthBand = "empty"
BandTooShort LengthBand = "too_short"
BandSweet LengthBand = "sweet"
BandLong LengthBand = "long"
BandOverSoft LengthBand = "over_soft"
BandOverHard LengthBand = "over_hard"
)
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 ""
}
}