82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
package isphere
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type Group struct {
|
|
GroupID string
|
|
DisplayName string
|
|
Source string
|
|
Confidence float64
|
|
RawRef string
|
|
}
|
|
|
|
type SearchGroupsQuery struct {
|
|
Query string
|
|
Limit int
|
|
}
|
|
|
|
type SearchGroupsResult struct {
|
|
Groups []Group
|
|
}
|
|
|
|
func SearchGroupsFromMessages(messages []Message, query SearchGroupsQuery) SearchGroupsResult {
|
|
unique := map[string]Group{}
|
|
for _, message := range messages {
|
|
if strings.EqualFold(message.ConversationType, "groupchat") {
|
|
addMessageGroup(unique, message.SenderID)
|
|
addMessageGroup(unique, message.ReceiverID)
|
|
continue
|
|
}
|
|
if isLikelyGroupJID(message.SenderID) {
|
|
addMessageGroup(unique, message.SenderID)
|
|
}
|
|
if isLikelyGroupJID(message.ReceiverID) {
|
|
addMessageGroup(unique, message.ReceiverID)
|
|
}
|
|
}
|
|
|
|
queryText := strings.ToLower(strings.TrimSpace(query.Query))
|
|
ids := make([]string, 0, len(unique))
|
|
for id := range unique {
|
|
if queryText == "" || strings.Contains(strings.ToLower(id), queryText) || strings.Contains(strings.ToLower(unique[id].DisplayName), queryText) {
|
|
ids = append(ids, id)
|
|
}
|
|
}
|
|
sort.Strings(ids)
|
|
|
|
limit := query.Limit
|
|
if limit <= 0 || limit > len(ids) {
|
|
limit = len(ids)
|
|
}
|
|
groups := make([]Group, 0, limit)
|
|
for _, id := range ids[:limit] {
|
|
groups = append(groups, unique[id])
|
|
}
|
|
return SearchGroupsResult{Groups: groups}
|
|
}
|
|
|
|
func addMessageGroup(unique map[string]Group, id string) {
|
|
trimmed := strings.TrimSpace(id)
|
|
if trimmed == "" || !isLikelyGroupJID(trimmed) {
|
|
return
|
|
}
|
|
if _, exists := unique[trimmed]; exists {
|
|
return
|
|
}
|
|
unique[trimmed] = Group{
|
|
GroupID: trimmed,
|
|
DisplayName: trimmed,
|
|
Source: "local_readonly",
|
|
Confidence: 0.6,
|
|
RawRef: "groupchat_jid",
|
|
}
|
|
}
|
|
|
|
func isLikelyGroupJID(id string) bool {
|
|
lower := strings.ToLower(strings.TrimSpace(id))
|
|
return strings.Contains(lower, "conference") || strings.Contains(lower, "muc") || strings.Contains(lower, "group")
|
|
}
|