fix: persist group join system notices
This commit is contained in:
@@ -5619,6 +5619,11 @@ func serveIMGroupInvitations(wrt http.ResponseWriter, req *http.Request, topic s
|
||||
}
|
||||
if joined {
|
||||
item["status"] = types.GroupInvitationStatusJoined
|
||||
if imReliableHTTPEventsEnabled(req) {
|
||||
publishIMGroupMemberJoinedSystemNotice(principal.TenantID, topic, principal.Uid, uid,
|
||||
"有成员通过邀请加入了群聊。",
|
||||
map[string]any{"source": "direct_invitation"})
|
||||
}
|
||||
} else {
|
||||
item["status"] = "already_member"
|
||||
}
|
||||
@@ -5863,6 +5868,11 @@ func serveIMGroupJoinRequests(wrt http.ResponseWriter, req *http.Request, topic
|
||||
}
|
||||
publishIMGroupRealtimeEvent(principal.TenantID, topic, principal.Uid, "group.member.joined",
|
||||
map[string]any{"user_id": principal.Uid.UserId(), "joined": joined, "source": "open_group"})
|
||||
if joined && imReliableHTTPEventsEnabled(req) {
|
||||
publishIMGroupMemberJoinedSystemNotice(principal.TenantID, topic, principal.Uid, principal.Uid,
|
||||
"有成员加入了群聊。",
|
||||
map[string]any{"source": "open_group"})
|
||||
}
|
||||
writeIMSuccess(wrt, req, map[string]any{"topic": topic, "status": "joined", "joined": joined, "source": "open_group"})
|
||||
return
|
||||
}
|
||||
@@ -11652,6 +11662,28 @@ func publishIMGroupInvitationNotification(tenantID types.TenantID, inv *types.Gr
|
||||
}
|
||||
}
|
||||
|
||||
func publishIMGroupMemberJoinedSystemNotice(tenantID types.TenantID, topic string, inviter, target types.Uid, text string, extra map[string]any) {
|
||||
if target.IsZero() {
|
||||
return
|
||||
}
|
||||
actors := make([]imSystemMessageActor, 0, 2)
|
||||
if !inviter.IsZero() && inviter != target {
|
||||
actors = append(actors, imSystemMessageActor{
|
||||
UserID: inviter.UserId(),
|
||||
Click: map[string]any{"type": "user_profile", "target_id": inviter.UserId()},
|
||||
})
|
||||
}
|
||||
actors = append(actors, imSystemMessageActor{
|
||||
UserID: target.UserId(),
|
||||
Click: map[string]any{"type": "user_profile", "target_id": target.UserId()},
|
||||
})
|
||||
publishIMConversationSystemNotice(tenantID, topic,
|
||||
"system_action", "group_member_joined", text,
|
||||
actors,
|
||||
[]imSystemMessageAction{{Type: "group_profile", Label: "查看群聊", TargetID: topic}},
|
||||
extra)
|
||||
}
|
||||
|
||||
func deliverIMConversationSystemMessageToP2PSessions(tenantID types.TenantID, msg *types.Message, out *ServerComMessage) {
|
||||
if globals.sessionStore == nil || msg == nil || out == nil || out.Data == nil {
|
||||
return
|
||||
|
||||
@@ -5379,6 +5379,74 @@ func TestServeIMGroupQRCodesAndResolve(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeIMGroupInvitationDirectJoinWritesSystemNotice(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
mockStore := expectIMBearer(t, ctrl, "token-1", 7, 42)
|
||||
mockStore.EXPECT().IsOpen().Return(true).AnyTimes()
|
||||
|
||||
oldSubs := store.Subs
|
||||
oldTopics := store.Topics
|
||||
oldMessages := store.Messages
|
||||
oldProfiles := store.Profiles
|
||||
oldGroupBusiness := store.GroupBusiness
|
||||
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
||||
topics := mock_store.NewMockTopicsPersistenceInterface(ctrl)
|
||||
messages := mock_store.NewMockMessagesPersistenceInterface(ctrl)
|
||||
store.Subs = subs
|
||||
store.Topics = topics
|
||||
store.Messages = messages
|
||||
store.Profiles = nil
|
||||
store.GroupBusiness = &testGroupBusinessStore{}
|
||||
t.Cleanup(func() {
|
||||
store.Subs = oldSubs
|
||||
store.Topics = oldTopics
|
||||
store.Messages = oldMessages
|
||||
store.Profiles = oldProfiles
|
||||
store.GroupBusiness = oldGroupBusiness
|
||||
})
|
||||
|
||||
subs.EXPECT().Get(types.TenantID(7), "grpAlpha", types.Uid(42), false).Return(&types.Subscription{
|
||||
TenantID: 7, User: types.Uid(42).String(), Topic: "grpAlpha", ModeWant: types.ModeCFull, ModeGiven: types.ModeCFull,
|
||||
}, nil)
|
||||
subs.EXPECT().Get(types.TenantID(7), "grpAlpha", types.Uid(43), false).Return(nil, types.ErrNotFound)
|
||||
topics.EXPECT().Get(types.TenantID(7), "grpAlpha").Return(&types.Topic{TenantID: 7, SeqId: 7}, nil)
|
||||
messages.EXPECT().Save(types.TenantID(7), gomock.Any(), nil, false).DoAndReturn(
|
||||
func(_ types.TenantID, msg *types.Message, _ []string, _ bool) (*types.MessageSaveResult, error) {
|
||||
if msg.Topic != "grpAlpha" || msg.SeqId != 8 {
|
||||
t.Fatalf("unexpected system notice message: %#v", msg)
|
||||
}
|
||||
if msg.Head["x-im-template"] != "group_member_joined" || msg.Head["x-im-type"] != "system_action" {
|
||||
t.Fatalf("unexpected system notice head: %#v", msg.Head)
|
||||
}
|
||||
content := msg.Content.(map[string]any)
|
||||
if content["text"] != "有成员通过邀请加入了群聊。" || content["template"] != "group_member_joined" {
|
||||
t.Fatalf("unexpected system notice content: %#v", content)
|
||||
}
|
||||
extra := content["extra"].(map[string]any)
|
||||
if extra["source"] != "direct_invitation" {
|
||||
t.Fatalf("unexpected system notice extra: %#v", extra)
|
||||
}
|
||||
return &types.MessageSaveResult{SeqId: msg.SeqId}, nil
|
||||
})
|
||||
|
||||
body := fmt.Sprintf(`{"user_ids":["%s"],"message":"欢迎"}`, types.Uid(43).UserId())
|
||||
req := httptest.NewRequest(http.MethodPost, "/v1/im/groups/grpAlpha/invitations", strings.NewReader(body))
|
||||
req.Header.Set("Authorization", "Bearer token-1")
|
||||
req.Header.Set("Idempotency-Key", "invite-1")
|
||||
req = req.WithContext(context.WithValue(req.Context(), imHTTPProtocolValidated, true))
|
||||
rec := httptest.NewRecorder()
|
||||
serveIMGroupResource(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("invite status: got %d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
data := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
|
||||
items := data["items"].([]any)
|
||||
if len(items) != 1 || items[0].(map[string]any)["status"] != types.GroupInvitationStatusJoined {
|
||||
t.Fatalf("unexpected invitation response: %#v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeIMGroupAnnouncementGovernanceJoinRequest(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
Reference in New Issue
Block a user