merged from gramsrv upstream
This commit is contained in:
parent
79c64ee916
commit
21a0856587
651 changed files with 54774 additions and 4590 deletions
|
|
@ -39,13 +39,33 @@ func (r *Router) onChannelsCreateChannel(ctx context.Context, req *tg.ChannelsCr
|
|||
return nil, channelInvalidErr(err)
|
||||
}
|
||||
r.addOnlineChannelMemberships(res.Channel.ID, channelMemberUserIDs(res.Members)...)
|
||||
updates := r.channelOperationUpdates(ctx, userID, res)
|
||||
updates, err := r.channelCreationResponseUpdates(ctx, userID, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.pushChannelUpdates(ctx, userID, res.Channel.ID, res.Recipients, func(viewerUserID int64) *tg.Updates {
|
||||
return r.channelOperationUpdates(ctx, viewerUserID, res)
|
||||
})
|
||||
return updates, nil
|
||||
}
|
||||
|
||||
// channelCreationResponseUpdates adds the response-only message mapping TDLib
|
||||
// requires to recognize a channels.createChannel result. The mapping is never
|
||||
// reused by fan-out or difference; the create service message remains the sole
|
||||
// durable, PTS-bearing fact.
|
||||
func (r *Router) channelCreationResponseUpdates(ctx context.Context, viewerUserID int64, res domain.CreateChannelResult) (*tg.Updates, error) {
|
||||
if res.Message.ID <= 0 || res.Message.Action == nil || res.Message.Action.Type != domain.ChannelActionCreate {
|
||||
return nil, internalErr()
|
||||
}
|
||||
updates := r.channelOperationUpdates(ctx, viewerUserID, res)
|
||||
if updates == nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
mapping := &tg.UpdateMessageID{ID: res.Message.ID, RandomID: randomNonZeroInt64()}
|
||||
updates.Updates = append([]tg.UpdateClass{mapping}, updates.Updates...)
|
||||
return updates, nil
|
||||
}
|
||||
|
||||
func validateChannelsCreateChannelOptions(req *tg.ChannelsCreateChannelRequest) error {
|
||||
if req == nil {
|
||||
return inputRequestInvalidErr()
|
||||
|
|
@ -168,6 +188,9 @@ func (r *Router) onChannelsGetFullChannel(ctx context.Context, input tg.InputCha
|
|||
return nil, channelInvalidErr(domain.ErrChannelPrivate)
|
||||
}
|
||||
full := cached.full
|
||||
if err := r.applyWelcomeMessagesToFullChat(ctx, ref.ID, &full); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.applyTranslationDisabledToChannelFull(ctx, userID, ref.ID, &full); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -191,6 +214,7 @@ func (r *Router) onChannelsGetFullChannel(ctx context.Context, input tg.InputCha
|
|||
return nil, err
|
||||
}
|
||||
full := tgChannelFull(view, r.cfg.PublicBaseURL)
|
||||
r.applyChannelStatsCapability(full)
|
||||
userIDs := []int64{view.Channel.CreatorUserID, view.Self.UserID}
|
||||
// 注:Bots 过滤实际会返回群内 bot(TestGroupBotRPCShape 覆盖),这里据此富化 full.BotInfo。
|
||||
// (此前审计误判为死代码,已由单测纠正——勿删。)
|
||||
|
|
@ -217,6 +241,9 @@ func (r *Router) onChannelsGetFullChannel(ctx context.Context, input tg.InputCha
|
|||
chats: append([]tg.ChatClass(nil), chats...),
|
||||
userIDs: userIDs,
|
||||
}, loadEpoch)
|
||||
if err := r.applyWelcomeMessagesToFullChat(ctx, view.Channel.ID, full); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.applyTranslationDisabledToChannelFull(ctx, userID, view.Channel.ID, full); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -235,6 +262,23 @@ func (r *Router) onChannelsGetFullChannel(ctx context.Context, input tg.InputCha
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (r *Router) applyWelcomeMessagesToFullChat(ctx context.Context, channelID int64, full tg.ChatFullClass) error {
|
||||
if r.deps.WelcomeMessages == nil || channelID <= 0 || full == nil {
|
||||
return nil
|
||||
}
|
||||
hasAny, err := r.deps.WelcomeMessages.HasAny(ctx, domain.Peer{Type: domain.PeerTypeChannel, ID: channelID})
|
||||
if err != nil {
|
||||
return internalErr()
|
||||
}
|
||||
switch value := full.(type) {
|
||||
case *tg.ChannelFull:
|
||||
value.HasWelcomeMessages = hasAny
|
||||
case *tg.ChatFull:
|
||||
value.HasWelcomeMessages = hasAny
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type channelReadModelResolver interface {
|
||||
GetChannelReadModel(ctx context.Context, userID, channelID int64) (domain.ChannelView, error)
|
||||
}
|
||||
|
|
@ -290,27 +334,48 @@ func (r *Router) onChannelsGetSendAs(ctx context.Context, req *tg.ChannelsGetSen
|
|||
}
|
||||
}
|
||||
chats = []tg.ChatClass{tgChannelChatForView(userID, view)}
|
||||
// 以「当前频道/群本身」发言:广播频道自帖、匿名管理员等(canCurrentChannelSendAs 判定)。
|
||||
if canCurrentChannelSendAs(view) {
|
||||
peers = append(peers, tg.SendAsPeer{Peer: &tg.PeerChannel{ChannelID: view.Channel.ID}})
|
||||
}
|
||||
// 以「用户自己拥有的其它广播频道」身份在本群发言。非本群关联频道的个人频道需会员
|
||||
// (premium_required,对齐官方:仅本群的 linked 讨论频道免会员),客户端据此置灰/引导开会员,
|
||||
// 服务端在发送侧用 PremiumActiveAt 兜底门控。
|
||||
if owned, err := r.deps.Channels.ListSendAsChannels(ctx, userID); err == nil && len(owned) > 0 {
|
||||
extras := make([]domain.Channel, 0, len(owned))
|
||||
owned, ownedErr := r.deps.Channels.ListSendAsChannels(ctx, userID)
|
||||
if req.ForPaidReactions {
|
||||
// Paid reaction identities are self plus currently owned/postable
|
||||
// broadcast channels. They are not message send-as candidates and do
|
||||
// not carry the unrelated premium_required gate.
|
||||
seen := make(map[int64]struct{}, len(owned))
|
||||
for _, ch := range owned {
|
||||
if ch.ID == 0 || ch.ID == view.Channel.ID {
|
||||
if ch.ID == 0 || ch.Deleted || !ch.Broadcast || ch.CreatorUserID != userID {
|
||||
continue
|
||||
}
|
||||
sendAs := tg.SendAsPeer{Peer: &tg.PeerChannel{ChannelID: ch.ID}}
|
||||
if ch.ID != view.Channel.LinkedChatID {
|
||||
sendAs.PremiumRequired = true
|
||||
if _, ok := seen[ch.ID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[ch.ID] = struct{}{}
|
||||
peers = append(peers, tg.SendAsPeer{Peer: &tg.PeerChannel{ChannelID: ch.ID}})
|
||||
if ch.ID != view.Channel.ID {
|
||||
chats = append(chats, tgChannels(userID, []domain.Channel{ch})...)
|
||||
}
|
||||
peers = append(peers, sendAs)
|
||||
extras = append(extras, ch)
|
||||
}
|
||||
chats = append(chats, tgChannels(userID, extras)...)
|
||||
} else {
|
||||
// 以「当前频道/群本身」发言:广播频道自帖、匿名管理员等(canCurrentChannelSendAs 判定)。
|
||||
if canCurrentChannelSendAs(view) {
|
||||
peers = append(peers, tg.SendAsPeer{Peer: &tg.PeerChannel{ChannelID: view.Channel.ID}})
|
||||
}
|
||||
// 以「用户自己拥有的其它广播频道」身份在本群发言。非本群关联频道的个人频道需会员
|
||||
// (premium_required,对齐官方:仅本群的 linked 讨论频道免会员),客户端据此置灰/引导开会员,
|
||||
// 服务端在发送侧用 PremiumActiveAt 兜底门控。
|
||||
if ownedErr == nil && len(owned) > 0 {
|
||||
extras := make([]domain.Channel, 0, len(owned))
|
||||
for _, ch := range owned {
|
||||
if ch.ID == 0 || ch.ID == view.Channel.ID {
|
||||
continue
|
||||
}
|
||||
sendAs := tg.SendAsPeer{Peer: &tg.PeerChannel{ChannelID: ch.ID}}
|
||||
if ch.ID != view.Channel.LinkedChatID {
|
||||
sendAs.PremiumRequired = true
|
||||
}
|
||||
peers = append(peers, sendAs)
|
||||
extras = append(extras, ch)
|
||||
}
|
||||
chats = append(chats, tgChannels(userID, extras)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
out := &tg.ChannelsSendAsPeers{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue