feat: improve group member events and push delivery

This commit is contained in:
richjohnrambo
2026-09-18 01:00:41 +08:00
parent 0e2f4e73d1
commit c6e7f6b923
13 changed files with 521 additions and 19 deletions
+63
View File
@@ -3967,6 +3967,15 @@ func serveIMGroupResource(wrt http.ResponseWriter, req *http.Request) {
serveIMGroupMembers(wrt, req, topic)
return
}
if strings.HasPrefix(tail, "members/") && !strings.HasSuffix(tail, "/profile") {
memberID := types.ParseUserId(strings.TrimSpace(strings.TrimPrefix(tail, "members/")))
if memberID.IsZero() {
writeIMError(wrt, req, http.StatusNotFound, 30004, imReasonMalformedRequest, "group route not found", nil)
return
}
serveIMGroupMember(wrt, req, topic, memberID)
return
}
if strings.HasPrefix(tail, "members/") && strings.HasSuffix(tail, "/profile") {
memberID, ok := groupMemberProfilePath(tail)
if !ok {
@@ -4066,11 +4075,60 @@ func serveIMGroupMembers(wrt http.ResponseWriter, req *http.Request, topic strin
"topic": topic,
"items": items,
"next_cursor": nextCursor,
"sync_mode": "full",
"permissions": permissions,
}
writeIMSuccess(wrt, req, payload)
}
func serveIMGroupMember(wrt http.ResponseWriter, req *http.Request, topic string, memberID types.Uid) {
if req.Method != http.MethodGet {
writeIMError(wrt, req, http.StatusMethodNotAllowed, 30002, imReasonMethodNotAllowed, "method not allowed", nil)
return
}
principal, selfSub, ok := requireIMGroupMember(wrt, req, topic, true)
if !ok {
return
}
if !(selfSub.ModeGiven & selfSub.ModeWant).IsReader() {
writeIMError(wrt, req, http.StatusForbidden, 30005, imReasonPermissionDenied, "topic read permission required", nil)
return
}
member, err := store.GroupBusiness.GetMember(principal.TenantID, topic, memberID)
if err != nil {
if errors.Is(err, types.ErrNotFound) {
writeIMError(wrt, req, http.StatusNotFound, 30004, imReasonMalformedRequest, "member not found", nil)
return
}
writeIMRelationError(wrt, req, err)
return
}
if member == nil || member.MemberStatus != types.GroupMemberStatusActive {
writeIMError(wrt, req, http.StatusNotFound, 30004, imReasonMalformedRequest, "member not found", nil)
return
}
memberSub, err := store.Subs.Get(principal.TenantID, topic, memberID, false)
if err != nil {
writeIMRelationError(wrt, req, err)
return
}
if memberSub == nil || !(memberSub.ModeGiven & memberSub.ModeWant).IsJoiner() {
writeIMError(wrt, req, http.StatusNotFound, 30004, imReasonMalformedRequest, "member not found", nil)
return
}
member.ModeWant = memberSub.ModeWant
member.ModeGiven = memberSub.ModeGiven
if user, userErr := store.Users.Get(principal.TenantID, memberID); userErr == nil && user != nil {
member.Public = user.Public
member.Trusted = user.Trusted
}
remarks := groupMemberRemarkMap(principal.TenantID, principal.Uid, []types.GroupMember{*member})
payload := groupBusinessMemberPayload(*member, remarks[member.UserID])
payload["topic"] = topic
payload["sync_mode"] = "single"
writeIMSuccess(wrt, req, payload)
}
func serveIMGroupDetail(wrt http.ResponseWriter, req *http.Request, topic string) {
principal, selfSub, ok := requireIMGroupMember(wrt, req, topic, true)
if !ok {
@@ -6861,6 +6919,10 @@ func groupBusinessMemberPayload(member types.GroupMember, remark string) map[str
data["group_nickname"] = nickname
}
data["role"] = groupMemberRole(access)
data["member_status"] = member.MemberStatus
data["version"] = member.Version
data["joined_at"] = member.JoinedAt.UTC().Format(time.RFC3339Nano)
data["updated_at"] = member.UpdatedAt.UTC().Format(time.RFC3339Nano)
data["mentionable"] = access.IsJoiner() && access.IsReader()
data["acs"] = map[string]any{
"mode": access.String(),
@@ -9941,6 +10003,7 @@ func publishIMConversationSystemNotice(tenantID types.TenantID, topic, msgType,
return
}
broadcastIMConversationSystemMessage(tenantID, msg, now)
sendPushForStoredGroupMessage(tenantID, msg)
}
func broadcastIMConversationSystemMessage(tenantID types.TenantID, msg *types.Message, timestamp time.Time) {