feat: extract groups from message logs
This commit is contained in:
81
internal/isphere/groups.go
Normal file
81
internal/isphere/groups.go
Normal file
@@ -0,0 +1,81 @@
|
||||
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")
|
||||
}
|
||||
22
internal/isphere/groups_test.go
Normal file
22
internal/isphere/groups_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package isphere
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSearchGroupsFromMessagesMatchesGroupchatJIDs(t *testing.T) {
|
||||
messages := []Message{
|
||||
{ID: "msg-1", ConversationType: "groupchat", SenderID: "project-room@conference.imopenfire1-lanzhou", ReceiverID: "user@imopenfire1-lanzhou"},
|
||||
{ID: "msg-2", ConversationType: "chat", SenderID: "alice@imopenfire1-lanzhou", ReceiverID: "bob@imopenfire1-lanzhou"},
|
||||
{ID: "msg-3", ConversationType: "groupchat", SenderID: "project-room@conference.imopenfire1-lanzhou", ReceiverID: "other@imopenfire1-lanzhou"},
|
||||
}
|
||||
|
||||
got := SearchGroupsFromMessages(messages, SearchGroupsQuery{Query: "project", Limit: 10})
|
||||
want := SearchGroupsResult{Groups: []Group{
|
||||
{GroupID: "project-room@conference.imopenfire1-lanzhou", DisplayName: "project-room@conference.imopenfire1-lanzhou", Source: "local_readonly", Confidence: 0.6, RawRef: "groupchat_jid"},
|
||||
}}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("SearchGroupsFromMessages() = %#v, want %#v", got, want)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user