Files
gitea-notification-hub/internal/event/mention.go
T

87 lines
1.9 KiB
Go

package event
import (
"regexp"
"strings"
)
// mentionRegex matches @username patterns
// Supports alphanumeric characters, underscores, and hyphens
var mentionRegex = regexp.MustCompile(`@([a-zA-Z0-9_-]+)`)
// ExtractMentions extracts all @mentioned usernames from text
func ExtractMentions(text string) []string {
if text == "" {
return nil
}
matches := mentionRegex.FindAllStringSubmatch(text, -1)
if len(matches) == 0 {
return nil
}
// Deduplicate mentions
seen := make(map[string]bool)
var usernames []string
for _, match := range matches {
if len(match) < 2 {
continue
}
username := strings.ToLower(match[1])
// Skip common false positives
if isCommonFalsePositive(username) {
continue
}
if !seen[username] {
seen[username] = true
usernames = append(usernames, username)
}
}
return usernames
}
// ReplaceMentionsWithSlackIDs replaces @username with <@SLACK_ID> format
func ReplaceMentionsWithSlackIDs(text string, usernameToSlackID map[string]string) string {
if text == "" || len(usernameToSlackID) == 0 {
return text
}
result := mentionRegex.ReplaceAllStringFunc(text, func(match string) string {
username := strings.ToLower(strings.TrimPrefix(match, "@"))
if slackID, ok := usernameToSlackID[username]; ok {
return "<@" + slackID + ">"
}
return match // Keep original if no mapping found
})
return result
}
// isCommonFalsePositive checks if a mention is likely not a real username
func isCommonFalsePositive(username string) bool {
// Common patterns that look like mentions but aren't
falsePositives := map[string]bool{
"param": true,
"returns": true,
"throws": true,
"deprecated": true,
"see": true,
"link": true,
"code": true,
"example": true,
"todo": true,
"fixme": true,
"note": true,
"warning": true,
"author": true,
"version": true,
"since": true,
}
return falsePositives[username]
}