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.