fix im forwarding and message list regressions

This commit is contained in:
richjohnrambo
2026-09-11 09:00:38 +08:00
parent 75d1aabcb0
commit 926b4bbd81
9 changed files with 331 additions and 20 deletions
+95 -9
View File
@@ -3745,9 +3745,17 @@ func serveIMFavoriteForward(wrt http.ResponseWriter, req *http.Request) {
}
saved, err := saveMessageMaybeKafka(req.Context(), principal.TenantID, msg, nil, true)
if err != nil {
if saved != nil && saved.Pending {
results = append(results, map[string]any{"target_topic": target, "favorite_id": favoriteID, "status": "pending", "seq": saved.SeqId, "reason": "MESSAGE_PERSIST_PENDING"})
continue
}
results = append(results, map[string]any{"target_topic": target, "favorite_id": favoriteID, "status": "failed", "reason": relationErrorReason(err)})
continue
}
if saved != nil && saved.Pending {
results = append(results, map[string]any{"target_topic": target, "favorite_id": favoriteID, "status": "pending", "seq": saved.SeqId, "reason": "MESSAGE_PERSIST_PENDING"})
continue
}
results = append(results, map[string]any{"target_topic": target, "favorite_id": favoriteID, "status": "sent", "seq": saved.SeqId})
}
}
@@ -3814,7 +3822,7 @@ func serveIMMessageForward(wrt http.ResponseWriter, req *http.Request) {
failed = append(failed, sourceFailures...)
continue
}
clientMid := "fwd_" + store.Store.GetUidString()
clientMid := forwardClientMid(req.Header.Get("Idempotency-Key"), "bundle", target, len(body.Sources), body.Comment)
forwarded := &types.Message{
TenantID: principal.TenantID,
Topic: target,
@@ -3828,9 +3836,36 @@ func serveIMMessageForward(wrt http.ResponseWriter, req *http.Request) {
}
saved, err := saveMessageMaybeKafka(req.Context(), principal.TenantID, forwarded, nil, true)
if err != nil {
if saved != nil && saved.Pending {
forwarded.SeqId = saved.SeqId
items = append(items, map[string]any{
"sources": bundle["source_refs"],
"target_topic": target,
"client_mid": clientMid,
"seq": saved.SeqId,
"status": "pending",
"reason": "MESSAGE_PERSIST_PENDING",
"mode": "bundle",
"bundle_id": bundle["bundle_id"],
})
continue
}
failed = append(failed, forwardFailurePayload("", 0, target, relationErrorReason(err)))
continue
}
if saved != nil && saved.Pending {
items = append(items, map[string]any{
"sources": bundle["source_refs"],
"target_topic": target,
"client_mid": clientMid,
"seq": saved.SeqId,
"status": "pending",
"reason": "MESSAGE_PERSIST_PENDING",
"mode": "bundle",
"bundle_id": bundle["bundle_id"],
})
continue
}
forwarded.SeqId = saved.SeqId
broadcastHTTPForwardMessage(principal.TenantID, forwarded)
items = append(items, map[string]any{
@@ -3872,7 +3907,7 @@ func serveIMMessageForward(wrt http.ResponseWriter, req *http.Request) {
failed = append(failed, forwardFailurePayload(sourceTopic, int64(source.Seq), target, "MESSAGE_UNAVAILABLE"))
continue
}
clientMid := "fwd_" + store.Store.GetUidString()
clientMid := forwardClientMid(req.Header.Get("Idempotency-Key"), "separate", target, sourceTopic, int64(source.Seq))
forwarded := &types.Message{
TenantID: principal.TenantID,
Topic: target,
@@ -3886,9 +3921,32 @@ func serveIMMessageForward(wrt http.ResponseWriter, req *http.Request) {
}
saved, err := saveMessageMaybeKafka(req.Context(), principal.TenantID, forwarded, nil, true)
if err != nil {
if saved != nil && saved.Pending {
forwarded.SeqId = saved.SeqId
items = append(items, map[string]any{
"source": map[string]any{"topic": sourceTopic, "seq": int64(source.Seq)},
"target_topic": target,
"client_mid": clientMid,
"seq": saved.SeqId,
"status": "pending",
"reason": "MESSAGE_PERSIST_PENDING",
})
continue
}
failed = append(failed, forwardFailurePayload(sourceTopic, int64(source.Seq), target, relationErrorReason(err)))
continue
}
if saved != nil && saved.Pending {
items = append(items, map[string]any{
"source": map[string]any{"topic": sourceTopic, "seq": int64(source.Seq)},
"target_topic": target,
"client_mid": clientMid,
"seq": saved.SeqId,
"status": "pending",
"reason": "MESSAGE_PERSIST_PENDING",
})
continue
}
forwarded.SeqId = saved.SeqId
broadcastHTTPForwardMessage(principal.TenantID, forwarded)
items = append(items, map[string]any{
@@ -8042,7 +8100,7 @@ func messageSearchPayload(msg types.Message, query string) map[string]any {
snippet := textSnippet(text, query)
return map[string]any{
"seq": msg.SeqId,
"from": msg.From,
"from": messageFromUserID(msg.From),
"ts": msg.CreatedAt.UTC().Format(time.RFC3339Nano),
"type": imMessageType(&msg),
"version": msg.Version,
@@ -8056,7 +8114,7 @@ func messageSearchPayload(msg types.Message, query string) map[string]any {
func messageContextPayload(msg types.Message) map[string]any {
return map[string]any{
"seq": msg.SeqId,
"from": msg.From,
"from": messageFromUserID(msg.From),
"ts": msg.CreatedAt.UTC().Format(time.RFC3339Nano),
"type": imMessageType(&msg),
"version": msg.Version,
@@ -8070,7 +8128,7 @@ func mediaMessagePayload(msg types.Message) map[string]any {
snapshot := favoriteSnapshot(&msg)
data := map[string]any{
"seq": msg.SeqId,
"from": msg.From,
"from": messageFromUserID(msg.From),
"ts": msg.CreatedAt.UTC().Format(time.RFC3339Nano),
"availability": messageAvailability(msg),
}
@@ -8082,6 +8140,23 @@ func mediaMessagePayload(msg types.Message) map[string]any {
return data
}
func messageFromUserID(from string) string {
from = strings.TrimSpace(from)
if from == "" {
return ""
}
if strings.HasPrefix(from, "usr") {
if uid := types.ParseUserId(from); !uid.IsZero() {
return uid.UserId()
}
return from
}
if uid := types.ParseUid(from); !uid.IsZero() {
return uid.UserId()
}
return from
}
func callRecordPayloads(records []types.CallRecord, viewer types.Uid) []map[string]any {
items := make([]map[string]any, 0, len(records))
for _, record := range records {
@@ -9379,7 +9454,7 @@ func userProfilePayload(user *types.User, ctx *types.RelationshipContext) map[st
}
func copyOptionalProfileFields(data map[string]any, public map[string]any) {
for _, key := range []string{"gender", "region", "public_account", "signature"} {
for _, key := range []string{"nickname", "gender", "region", "public_account", "signature"} {
if value, ok := public[key]; ok {
data[key] = value
}
@@ -9436,7 +9511,7 @@ func displayInitial(value any) string {
func writeIMRelationError(wrt http.ResponseWriter, req *http.Request, err error) {
switch {
case errors.Is(err, types.ErrNotFound):
writeIMError(wrt, req, http.StatusNotFound, 20004, imReasonMalformedRequest, "resource not found", nil)
writeIMError(wrt, req, http.StatusNotFound, 20004, imReasonResourceNotFound, "resource not found", nil)
case errors.Is(err, types.ErrPermissionDenied):
writeIMError(wrt, req, http.StatusForbidden, 20005, imReasonPermissionDenied, "permission denied", nil)
case errors.Is(err, types.ErrInvalidResponse):
@@ -9625,7 +9700,7 @@ func favoriteSnapshot(msg *types.Message) map[string]any {
return map[string]any{
"topic": msg.Topic,
"seq": msg.SeqId,
"from": msg.From,
"from": messageFromUserID(msg.From),
"ts": msg.CreatedAt.UTC().Format(time.RFC3339Nano),
"type": imMessageType(msg),
"version": msg.Version,
@@ -9677,6 +9752,17 @@ func forwardFailurePayload(topic string, seq int64, target, reason string) map[s
}
}
func forwardClientMid(requestKey string, parts ...any) string {
requestKey = strings.TrimSpace(requestKey)
if requestKey == "" {
return "fwd_" + store.Store.GetUidString()
}
args := make([]any, 0, len(parts)+2)
args = append(args, "forward", requestKey)
args = append(args, parts...)
return "fwd_" + stableIMEventID(args...)
}
func normalizeIMForwardTopic(viewer types.Uid, topic string) (string, bool) {
return normalizeIMUserVisibleTopic(viewer, topic)
}
@@ -10624,7 +10710,7 @@ func normalizeIMAbuseTarget(tenantID types.TenantID, reporter types.Uid, target
}
snapshot["topic"] = topic
snapshot["seq"] = seq
snapshot["from"] = msg.From
snapshot["from"] = messageFromUserID(msg.From)
snapshot["ts"] = msg.CreatedAt.UTC().Format(time.RFC3339Nano)
return targetType, 0, topic, seq, snapshot, nil
default: