80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
package wecom
|
||
|
||
import "strings"
|
||
|
||
// stripWeComAtMentions removes @<botId> / @<botId> segments so group replies like
|
||
// "允许 @机器人" still match engine permission keywords (#98). Only affects wecom.
|
||
func stripWeComAtMentions(s string, botIDs ...string) string {
|
||
s = strings.TrimSpace(s)
|
||
for _, id := range botIDs {
|
||
id = strings.TrimSpace(id)
|
||
if id == "" {
|
||
continue
|
||
}
|
||
s = stripOneWeComAtMention(s, id)
|
||
s = strings.TrimSpace(s)
|
||
}
|
||
for strings.Contains(s, " ") {
|
||
s = strings.ReplaceAll(s, " ", " ")
|
||
}
|
||
return stripLeadingDisplayMentionCommand(strings.TrimSpace(s))
|
||
}
|
||
|
||
func stripOneWeComAtMention(s, botID string) string {
|
||
if s == "" || botID == "" {
|
||
return s
|
||
}
|
||
// Fullwidth commercial at (common on mobile keyboards)
|
||
s = removeAllEqualFold(s, "@"+botID)
|
||
// ASCII @
|
||
needleLower := "@" + strings.ToLower(botID)
|
||
for {
|
||
lower := strings.ToLower(s)
|
||
idx := strings.Index(lower, needleLower)
|
||
if idx < 0 {
|
||
return s
|
||
}
|
||
end := idx + len(needleLower)
|
||
if end > len(s) {
|
||
return s
|
||
}
|
||
s = s[:idx] + s[end:]
|
||
}
|
||
}
|
||
|
||
// removeAllEqualFold removes every case-insensitive occurrence of literal sub from s.
|
||
// sub must be UTF-8; indices align because case folding does not change byte length
|
||
// for ASCII letters in sub.
|
||
func removeAllEqualFold(s, sub string) string {
|
||
if sub == "" {
|
||
return s
|
||
}
|
||
subLower := strings.ToLower(sub)
|
||
for {
|
||
lower := strings.ToLower(s)
|
||
idx := strings.Index(lower, subLower)
|
||
if idx < 0 {
|
||
return s
|
||
}
|
||
s = s[:idx] + s[idx+len(sub):]
|
||
}
|
||
}
|
||
|
||
func stripLeadingDisplayMentionCommand(s string) string {
|
||
if s == "" {
|
||
return s
|
||
}
|
||
if !strings.HasPrefix(s, "@") && !strings.HasPrefix(s, "@") {
|
||
return s
|
||
}
|
||
fields := strings.Fields(s)
|
||
if len(fields) < 2 {
|
||
return s
|
||
}
|
||
rest := strings.TrimSpace(strings.TrimPrefix(s, fields[0]))
|
||
if strings.HasPrefix(rest, "/") || strings.HasPrefix(rest, "!") {
|
||
return rest
|
||
}
|
||
return s
|
||
}
|