From 74819586483c99366139d4e0e9b1ebf13a3bfbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9A=AE=E7=9A=AE=E8=90=8C=E5=AE=9D?= Date: Mon, 28 Sep 2026 19:56:18 +0800 Subject: [PATCH] fix(group): make set-group-info callback field replacement nil-safe webhookBeforeSetGroupInfo and webhookBeforeSetGroupInfoEx called datautil.NotNilReplace(&req.X, &resp.X). NotNilReplace only checks the outer pointer, which is never nil for a field address, so a successful callback that did not return these fields unconditionally overwrote the pending request values with zero values. For SetGroupInfoExReq the wrapped fields were set to nil, UpdateGroupInfoExMap then returned an empty map and the update silently no-op'd (e.g. renaming a group failed while changing its avatar still worked, because the callback returns faceURL). Only overwrite request fields when the callback explicitly provided a value: plain strings check != "", wrapper-pointer fields check != nil. --- internal/rpc/group/callback.go | 50 ++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/internal/rpc/group/callback.go b/internal/rpc/group/callback.go index 0898da0f5..15094a4b6 100644 --- a/internal/rpc/group/callback.go +++ b/internal/rpc/group/callback.go @@ -341,10 +341,19 @@ func (g *groupServer) webhookBeforeSetGroupInfo(ctx context.Context, before *con if resp.ApplyMemberFriend != nil { req.GroupInfoForSet.ApplyMemberFriend = wrapperspb.Int32(*resp.ApplyMemberFriend) } - datautil.NotNilReplace(&req.GroupInfoForSet.GroupID, &resp.GroupID) - datautil.NotNilReplace(&req.GroupInfoForSet.GroupName, &resp.GroupName) - datautil.NotNilReplace(&req.GroupInfoForSet.FaceURL, &resp.FaceURL) - datautil.NotNilReplace(&req.GroupInfoForSet.Introduction, &resp.Introduction) + // resp 中的字符串为零值时表示回调未提供,保留请求原值,避免空串覆盖待更新字段 + if resp.GroupID != "" { + req.GroupInfoForSet.GroupID = resp.GroupID + } + if resp.GroupName != "" { + req.GroupInfoForSet.GroupName = resp.GroupName + } + if resp.FaceURL != "" { + req.GroupInfoForSet.FaceURL = resp.FaceURL + } + if resp.Introduction != "" { + req.GroupInfoForSet.Introduction = resp.Introduction + } return nil }) } @@ -405,14 +414,31 @@ func (g *groupServer) webhookBeforeSetGroupInfoEx(ctx context.Context, before *c return err } - datautil.NotNilReplace(&req.GroupID, &resp.GroupID) - datautil.NotNilReplace(&req.GroupName, &resp.GroupName) - datautil.NotNilReplace(&req.FaceURL, &resp.FaceURL) - datautil.NotNilReplace(&req.Introduction, &resp.Introduction) - datautil.NotNilReplace(&req.Ex, &resp.Ex) - datautil.NotNilReplace(&req.NeedVerification, &resp.NeedVerification) - datautil.NotNilReplace(&req.LookMemberInfo, &resp.LookMemberInfo) - datautil.NotNilReplace(&req.ApplyMemberFriend, &resp.ApplyMemberFriend) + // 仅当回调显式提供字段时才覆盖,避免把请求中的增量字段抹成 nil + if resp.GroupID != "" { + req.GroupID = resp.GroupID + } + if resp.GroupName != nil { + req.GroupName = resp.GroupName + } + if resp.FaceURL != nil { + req.FaceURL = resp.FaceURL + } + if resp.Introduction != nil { + req.Introduction = resp.Introduction + } + if resp.Ex != nil { + req.Ex = resp.Ex + } + if resp.NeedVerification != nil { + req.NeedVerification = resp.NeedVerification + } + if resp.LookMemberInfo != nil { + req.LookMemberInfo = resp.LookMemberInfo + } + if resp.ApplyMemberFriend != nil { + req.ApplyMemberFriend = resp.ApplyMemberFriend + } return nil })