fix: sync support private chat content protection

This commit is contained in:
iamxvbaba 2026-07-28 16:22:33 +08:00
parent 74c9249091
commit 037ce017d4
25 changed files with 1395 additions and 36 deletions

View file

@ -558,6 +558,10 @@ const (
// MessageServiceActionSetChatTheme 映射 messageActionSetChatTheme
// 私聊双方共享的 chat theme token 变更。
MessageServiceActionSetChatTheme MessageServiceActionKind = "set_chat_theme"
// MessageServiceActionNoForwardsToggle / Request 映射私聊内容保护的
// 状态切换与关闭请求。会话级保护不能写入普通消息的 NoForwards 字段。
MessageServiceActionNoForwardsToggle MessageServiceActionKind = "no_forwards_toggle"
MessageServiceActionNoForwardsRequest MessageServiceActionKind = "no_forwards_request"
// MessageServiceActionStarGift 映射 messageActionStarGift收到一份 Star 礼物。
// 礼物快照(贴纸/星价)内嵌在 action 里,收礼人无需额外拉取即可渲染气泡。
MessageServiceActionStarGift MessageServiceActionKind = "star_gift"
@ -629,6 +633,15 @@ type MessageRequestedPeerDetails struct {
Photo *Photo `json:"photo,omitempty"`
}
// MessageNoForwardsAction 是私聊内容保护 service action 的协议中立载荷。
// ExpiresAt 只用于 request 的读取时绝对过期投影toggle 保持为 0。
type MessageNoForwardsAction struct {
PrevValue bool `json:"prev_value"`
NewValue bool `json:"new_value"`
Expired bool `json:"expired,omitempty"`
ExpiresAt int `json:"expires_at,omitempty"`
}
// MessageServiceAction 是私聊服务消息动作的协议中立表示。
type MessageServiceAction struct {
Kind MessageServiceActionKind `json:"kind"`
@ -639,6 +652,7 @@ type MessageServiceAction struct {
WebViewData *MessageWebViewDataAction `json:"web_view_data,omitempty"`
RequestedPeer *MessageRequestedPeerAction `json:"requested_peer,omitempty"`
ChatThemeEmoticon string `json:"chat_theme_emoticon,omitempty"`
NoForwards *MessageNoForwardsAction `json:"no_forwards,omitempty"`
StarGift *MessageStarGiftAction `json:"star_gift,omitempty"`
StarGiftUnique *MessageStarGiftUniqueAction `json:"star_gift_unique,omitempty"`
StarGiftOffer *MessageStarGiftOfferAction `json:"star_gift_offer,omitempty"`

View file

@ -407,6 +407,47 @@ type ForwardPrivateMessagesResult struct {
ReplayDeleteEvents []*UpdateEvent
}
const PrivateNoForwardsRequestExpirePeriod = 24 * 60 * 60
// PrivateNoForwardsState 是一对普通用户唯一的内容保护权威。
// EnabledByUserID 为 0 或参与者之一;非零时双方共享的会话均受保护。
type PrivateNoForwardsState struct {
UserLowID int64
UserHighID int64
EnabledByUserID int64
}
func (s PrivateNoForwardsState) Enabled() bool {
return s.EnabledByUserID != 0
}
func (s PrivateNoForwardsState) ForViewer(viewerUserID int64) (myEnabled, peerEnabled bool) {
if s.EnabledByUserID == 0 {
return false, false
}
return s.EnabledByUserID == viewerUserID, s.EnabledByUserID != viewerUserID
}
// TogglePrivateNoForwardsRequest 是私聊内容保护的原子状态+服务消息命令。
type TogglePrivateNoForwardsRequest struct {
ActorUserID int64
PeerUserID int64
Enabled bool
RequestMsgID int
RandomID int64
Date int
OriginAuthKeyID [8]byte
OriginSessionID int64
}
// TogglePrivateNoForwardsResult 同时返回提交后的权威状态与本次真实服务消息。
// Changed=false 且 Send 为空表示官方定义的 no-op。
type TogglePrivateNoForwardsResult struct {
State PrivateNoForwardsState
Changed bool
Send SendPrivateTextResult
}
// ReadHistoryRequest 是账号视角的 messages.readHistory 命令。
type ReadHistoryRequest struct {
OwnerUserID int64

View file

@ -27,6 +27,7 @@ var (
ErrLoginCodeDeliveryCommitAmbiguous = errors.New("login code delivery commit ambiguous")
ErrReplyMessageIDInvalid = errors.New("reply message id invalid")
ErrChatForwardsRestricted = errors.New("chat forwards restricted")
ErrNoForwardsRequestExpired = errors.New("no forwards request expired")
// ErrPinnedSavedDialogsTooMuch 映射 PINNED_TOO_MUCH收藏夹子会话置顶
// 数量达到 MaxPinnedSavedDialogs 上限。
ErrPinnedSavedDialogsTooMuch = errors.New("pinned saved dialogs too much")