fix: align group management APIs

This commit is contained in:
richjohnrambo
2026-09-13 16:03:55 +08:00
parent f1279ac607
commit a9afc6ff6a
34 changed files with 1381 additions and 639 deletions
+101 -9
View File
@@ -1177,11 +1177,7 @@ func (t *Topic) saveAndBroadcastMessage(msg *ClientComMessage, asUid types.Uid,
pluginMessage(t.tenantID, data.Data, plgActCreate)
t.broadcastToSessions(data)
if t.cat == types.TopicCatGrp {
if err := store.PublishGroupFanout(currentNodeID(), data); err != nil {
logs.Warn.Printf("topic[%s]: failed to publish redis group fanout: %v", t.name, err)
}
}
publishRealtimeTopicMessage(t.name, data)
// sendPush will update unread message count and send push notification.
if pushRcpt := t.pushForData(asUid, data.Data, markedReadBySender); pushRcpt != nil {
@@ -1260,10 +1256,7 @@ func (t *Topic) handlePubBroadcast(msg *ClientComMessage) {
}
// Save to DB at master topic.
var attachments []string
if msg.Extra != nil && len(msg.Extra.Attachments) > 0 {
attachments = msg.Extra.Attachments
}
attachments := messageAttachmentURLs(msg)
if err := t.saveAndBroadcastMessage(msg, asUid, msg.Pub.NoEcho, attachments, msg.Pub.Head, msg.Pub.Content); err != nil {
logs.Err.Printf("topic[%s]: failed to save messagge - %s", t.name, err)
@@ -1275,6 +1268,105 @@ func (t *Topic) handlePubBroadcast(msg *ClientComMessage) {
}
}
func messageAttachmentURLs(msg *ClientComMessage) []string {
if msg == nil || msg.Pub == nil {
return nil
}
attachments := make([]string, 0)
seen := make(map[string]bool)
add := func(raw string) {
url, key := normalizeAttachmentURL(raw)
if url == "" || seen[key] {
return
}
seen[key] = true
attachments = append(attachments, url)
}
if msg.Extra != nil {
for _, attachment := range msg.Extra.Attachments {
add(attachment)
}
}
for _, attachment := range inferAttachmentURLsFromContent(msg.Pub.Content) {
add(attachment)
}
return attachments
}
func inferAttachmentURLsFromContent(content any) []string {
var attachments []string
seen := make(map[string]bool)
addFileID := func(raw string) {
url, key := normalizeAttachmentURL(raw)
if url != "" && !seen[key] {
seen[key] = true
attachments = append(attachments, url)
}
}
var walk func(any, int)
walk = func(value any, depth int) {
if value == nil || depth <= 0 {
return
}
switch typed := value.(type) {
case map[string]any:
if fileID, ok := typed["file_id"].(string); ok {
addFileID(fileID)
}
if ref, ok := typed["ref"].(string); ok {
addFileID(ref)
}
for _, child := range typed {
walk(child, depth-1)
}
case types.KVMap:
walk(map[string]any(typed), depth)
case []any:
for _, child := range typed {
walk(child, depth-1)
}
}
}
walk(content, 8)
return attachments
}
func normalizeAttachmentURL(raw string) (string, string) {
raw = strings.TrimSpace(raw)
if raw == "" {
return "", ""
}
if fid := parseAttachmentFileID(raw); !fid.IsZero() {
return "/v0/file/s/" + fid.String(), fid.String()
}
return raw, raw
}
func parseAttachmentFileID(raw string) types.Uid {
raw = strings.TrimSpace(raw)
if raw == "" {
return types.ZeroUid
}
if fid := types.ParseUid(raw); !fid.IsZero() {
return fid
}
if idx := strings.LastIndex(raw, "/v0/file/s/"); idx >= 0 {
tail := raw[idx+len("/v0/file/s/"):]
if cut := strings.IndexAny(tail, "?#/"); cut >= 0 {
tail = tail[:cut]
}
if dot := strings.IndexByte(tail, '.'); dot >= 0 {
tail = tail[:dot]
}
return types.ParseUid(tail)
}
if dot := strings.IndexByte(raw, '.'); dot >= 0 {
return types.ParseUid(raw[:dot])
}
return types.ZeroUid
}
func (t *Topic) validateMessageReplacement(asUid types.Uid, head map[string]any, now time.Time) error {
if head == nil || head["replace"] == nil {
return nil