chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
601
internal/rpc/channels_legacy_chat.go
Normal file
601
internal/rpc/channels_legacy_chat.go
Normal file
|
|
@ -0,0 +1,601 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/gotd/td/tg"
|
||||
"github.com/gotd/td/tgerr"
|
||||
"go.uber.org/zap"
|
||||
"telesrv/internal/compat/tdesktop"
|
||||
"telesrv/internal/domain"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func (r *Router) onMessagesCreateChat(ctx context.Context, req *tg.MessagesCreateChatRequest) (*tg.MessagesInvitedUsers, error) {
|
||||
if r.deps.Channels == nil {
|
||||
return nil, notImplementedErr()
|
||||
}
|
||||
if !validChannelTitle(req.Title) || len(req.Users) > domain.MaxChannelInviteUsers {
|
||||
return nil, channelInvalidErr(domain.ErrChannelTitleInvalid)
|
||||
}
|
||||
if req.TTLPeriod < 0 {
|
||||
return nil, ttlPeriodInvalidErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
memberIDs, err := r.userIDsFromInputUsers(ctx, userID, req.Users)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
memberIDs = createChatInviteMemberIDs(memberIDs, userID)
|
||||
date := int(r.clock.Now().Unix())
|
||||
r.log.Debug("messages.createChat resolved users",
|
||||
zap.Int("input_users", len(req.Users)),
|
||||
zap.Int("member_ids", len(memberIDs)),
|
||||
zap.Int64s("member_user_ids", memberIDs),
|
||||
)
|
||||
if len(memberIDs) == 0 {
|
||||
return nil, usersTooFewErr()
|
||||
}
|
||||
createRes, err := r.deps.Channels.CreateMegagroupFromCreateChat(ctx, userID, domain.CreateChannelRequest{
|
||||
CreatorUserID: userID,
|
||||
Title: req.Title,
|
||||
TTLPeriod: req.TTLPeriod,
|
||||
Date: date,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, channelInvalidErr(err)
|
||||
}
|
||||
r.addOnlineChannelMemberships(createRes.Channel.ID, channelMemberUserIDs(createRes.Members)...)
|
||||
|
||||
responseRes := createRes
|
||||
var inviteRes domain.CreateChannelResult
|
||||
if len(memberIDs) > 0 {
|
||||
inviteRes, err = r.deps.Channels.InviteToChannel(ctx, userID, createRes.Channel.ID, memberIDs, date)
|
||||
if err != nil {
|
||||
return nil, channelInviteErr(err)
|
||||
}
|
||||
r.addOnlineChannelMemberships(inviteRes.Channel.ID, channelMemberUserIDs(inviteRes.Members)...)
|
||||
responseRes.Channel = inviteRes.Channel
|
||||
responseRes.Members = mergeChannelMembers(createRes.Members, inviteRes.Members)
|
||||
responseRes.Recipients = uniqueRecipientIDs(append(append([]int64{}, createRes.Recipients...), inviteRes.Recipients...))
|
||||
}
|
||||
|
||||
cache := newViewerPeerCache(r)
|
||||
updates := r.channelOperationUpdatesWithPeerCache(ctx, userID, responseRes, cache)
|
||||
if createChatNeedsLegacyChat(ctx) {
|
||||
updates = r.tdesktopCreateChatUpdatesWithPeerCache(ctx, userID, responseRes, cache)
|
||||
}
|
||||
if inviteRes.Event.Pts != 0 {
|
||||
inviteUpdates := r.channelOperationUpdatesWithPeerCache(ctx, userID, inviteRes, cache)
|
||||
if inviteUpdates != nil {
|
||||
updates.Updates = append(updates.Updates, inviteUpdates.Updates...)
|
||||
}
|
||||
}
|
||||
if inviteRes.Event.Pts != 0 {
|
||||
r.pushChannelExplicitUpdates(ctx, userID, inviteRes.Channel.ID, memberIDs, func(viewerUserID int64) *tg.Updates {
|
||||
return r.channelOperationUpdatesWithPeerCache(ctx, viewerUserID, inviteRes, cache)
|
||||
})
|
||||
}
|
||||
return &tg.MessagesInvitedUsers{Updates: updates, MissingInvitees: []tg.MissingInvitee{}}, nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesMigrateChat(ctx context.Context, chatID int64) (tg.UpdatesClass, error) {
|
||||
if r.deps.Channels == nil {
|
||||
return nil, notImplementedErr()
|
||||
}
|
||||
if chatID <= 0 {
|
||||
return nil, channelInvalidErr(domain.ErrChannelInvalid)
|
||||
}
|
||||
userID, view, err := r.channelChangeInfoView(ctx, &tg.InputChannel{ChannelID: chatID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !view.Channel.Megagroup {
|
||||
return nil, channelInvalidErr(domain.ErrChannelInvalid)
|
||||
}
|
||||
return r.channelStateUpdates(userID, view.Channel), nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetChats(ctx context.Context, ids []int64) (tg.MessagesChatsClass, error) {
|
||||
if len(ids) > maxGetMessagesIDs {
|
||||
return nil, limitInvalidErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
chats := make([]tg.ChatClass, 0, len(ids))
|
||||
if r.deps.Channels != nil {
|
||||
unique := make([]int64, 0, len(ids))
|
||||
seen := make(map[int64]struct{}, len(ids))
|
||||
for _, id := range ids {
|
||||
if id <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
unique = append(unique, id)
|
||||
}
|
||||
views, err := r.deps.Channels.GetChannels(ctx, userID, unique)
|
||||
if err != nil {
|
||||
return nil, channelInvalidErr(err)
|
||||
}
|
||||
byID := make(map[int64]domain.ChannelView, len(views))
|
||||
for _, view := range views {
|
||||
if view.Channel.ID != 0 {
|
||||
byID[view.Channel.ID] = view
|
||||
}
|
||||
}
|
||||
for _, id := range ids {
|
||||
if id <= 0 {
|
||||
continue
|
||||
}
|
||||
if view, ok := byID[id]; ok {
|
||||
chats = append(chats, tgChannelChatForView(userID, view))
|
||||
}
|
||||
}
|
||||
}
|
||||
return &tg.MessagesChats{Chats: chats}, nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetFullChat(ctx context.Context, chatID int64) (*tg.MessagesChatFull, error) {
|
||||
if chatID <= 0 {
|
||||
return nil, channelInvalidErr(domain.ErrChannelInvalid)
|
||||
}
|
||||
return r.onChannelsGetFullChannel(ctx, &tg.InputChannel{ChannelID: chatID})
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesAddChatUser(ctx context.Context, req *tg.MessagesAddChatUserRequest) (*tg.MessagesInvitedUsers, error) {
|
||||
if req.ChatID <= 0 || req.UserID == nil {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
return r.onChannelsInviteToChannel(ctx, &tg.ChannelsInviteToChannelRequest{
|
||||
Channel: &tg.InputChannel{ChannelID: req.ChatID},
|
||||
Users: []tg.InputUserClass{req.UserID},
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesDeleteChatUser(ctx context.Context, req *tg.MessagesDeleteChatUserRequest) (tg.UpdatesClass, error) {
|
||||
if req.ChatID <= 0 || req.UserID == nil {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
target, found, err := r.userFromInput(ctx, userID, req.UserID)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if !found || target.ID == 0 {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
if target.ID == userID {
|
||||
return r.onChannelsLeaveChannel(ctx, &tg.InputChannel{ChannelID: req.ChatID})
|
||||
}
|
||||
return r.onChannelsEditBanned(ctx, &tg.ChannelsEditBannedRequest{
|
||||
Channel: &tg.InputChannel{ChannelID: req.ChatID},
|
||||
Participant: &tg.InputPeerUser{UserID: target.ID, AccessHash: target.AccessHash},
|
||||
BannedRights: tg.ChatBannedRights{
|
||||
ViewMessages: true,
|
||||
UntilDate: 0,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesEditChatTitle(ctx context.Context, req *tg.MessagesEditChatTitleRequest) (tg.UpdatesClass, error) {
|
||||
if req.ChatID <= 0 {
|
||||
return nil, channelInvalidErr(domain.ErrChannelInvalid)
|
||||
}
|
||||
return r.onChannelsEditTitle(ctx, &tg.ChannelsEditTitleRequest{
|
||||
Channel: &tg.InputChannel{ChannelID: req.ChatID},
|
||||
Title: req.Title,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesEditChatPhoto(ctx context.Context, req *tg.MessagesEditChatPhotoRequest) (tg.UpdatesClass, error) {
|
||||
if req.ChatID <= 0 || req.Photo == nil {
|
||||
return nil, channelInvalidErr(domain.ErrChannelInvalid)
|
||||
}
|
||||
return r.onChannelsEditPhoto(ctx, &tg.ChannelsEditPhotoRequest{
|
||||
Channel: &tg.InputChannel{ChannelID: req.ChatID},
|
||||
Photo: req.Photo,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesEditChatAdmin(ctx context.Context, req *tg.MessagesEditChatAdminRequest) (bool, error) {
|
||||
if req.ChatID <= 0 || req.UserID == nil {
|
||||
return false, peerIDInvalidErr()
|
||||
}
|
||||
rights := tg.ChatAdminRights{}
|
||||
if req.IsAdmin {
|
||||
rights = legacyBasicGroupAdminRights()
|
||||
}
|
||||
_, err := r.onChannelsEditAdmin(ctx, &tg.ChannelsEditAdminRequest{
|
||||
Channel: &tg.InputChannel{ChannelID: req.ChatID},
|
||||
UserID: req.UserID,
|
||||
AdminRights: rights,
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesEditChatAbout(ctx context.Context, req *tg.MessagesEditChatAboutRequest) (bool, error) {
|
||||
if r.deps.Channels == nil {
|
||||
return false, notImplementedErr()
|
||||
}
|
||||
if utf8.RuneCountInString(req.About) > maxChannelAboutLength {
|
||||
return false, channelInvalidErr(domain.ErrChannelInvalid)
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return false, internalErr()
|
||||
}
|
||||
channelID, err := r.channelIDFromLegacyInputPeerChecked(ctx, userID, req.Peer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
channel, err := r.deps.Channels.EditAbout(ctx, userID, domain.EditChannelAboutRequest{
|
||||
UserID: userID,
|
||||
ChannelID: channelID,
|
||||
About: req.About,
|
||||
Date: int(r.clock.Now().Unix()),
|
||||
})
|
||||
if err != nil {
|
||||
return false, channelAdminErr(err)
|
||||
}
|
||||
r.pushChannelStateToMembers(ctx, userID, channel)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesEditChatDefaultBannedRights(ctx context.Context, req *tg.MessagesEditChatDefaultBannedRightsRequest) (tg.UpdatesClass, error) {
|
||||
if r.deps.Channels == nil {
|
||||
return nil, notImplementedErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
peer, err := r.checkedDomainPeerFromInputPeer(ctx, userID, req.Peer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if peer.Type != domain.PeerTypeChannel || peer.ID == 0 {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
channel, err := r.deps.Channels.EditDefaultBannedRights(ctx, userID, domain.EditChannelDefaultBannedRightsRequest{
|
||||
UserID: userID,
|
||||
ChannelID: peer.ID,
|
||||
BannedRights: domainChannelBannedRights(req.BannedRights),
|
||||
Date: int(r.clock.Now().Unix()),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, channelAdminErr(err)
|
||||
}
|
||||
return r.channelStateMutationUpdates(ctx, userID, channel), nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesEditChatCreator(ctx context.Context, req *tg.MessagesEditChatCreatorRequest) (tg.UpdatesClass, error) {
|
||||
if req.UserID == nil {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if _, err := r.channelIDFromLegacyInputPeerChecked(ctx, userID, req.Peer); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, found, err := r.userFromInput(ctx, userID, req.UserID); err != nil {
|
||||
return nil, internalErr()
|
||||
} else if !found {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
return nil, tgerr.New(400, "PASSWORD_HASH_INVALID")
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetFutureChatCreatorAfterLeave(ctx context.Context, peer tg.InputPeerClass) (tg.UserClass, error) {
|
||||
if r.deps.Channels == nil {
|
||||
return nil, notImplementedErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
resolved, err := r.checkedDomainPeerFromInputPeer(ctx, userID, peer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resolved.Type != domain.PeerTypeChannel || resolved.ID == 0 {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
member, err := r.deps.Channels.FutureCreatorAfterLeave(ctx, userID, resolved.ID)
|
||||
if err != nil {
|
||||
return nil, channelAdminErr(err)
|
||||
}
|
||||
if r.deps.Users == nil {
|
||||
return nil, userIDInvalidErr()
|
||||
}
|
||||
user, found, err := r.deps.Users.ByID(ctx, userID, member.UserID)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if !found || user.Bot {
|
||||
return nil, tgerr400("USER_NOT_PARTICIPANT")
|
||||
}
|
||||
users := r.tgUsersForViewer(userID, []domain.User{user})
|
||||
if len(users) == 0 {
|
||||
return nil, userIDInvalidErr()
|
||||
}
|
||||
return users[0], nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesEditChatParticipantRank(ctx context.Context, req *tg.MessagesEditChatParticipantRankRequest) (tg.UpdatesClass, error) {
|
||||
if r.deps.Channels == nil {
|
||||
return nil, notImplementedErr()
|
||||
}
|
||||
if len(req.Rank) > domain.MaxChannelAdminRankLength {
|
||||
return nil, channelInvalidErr(domain.ErrChannelInvalid)
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
channelID, err := r.channelIDFromLegacyInputPeerChecked(ctx, userID, req.Peer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
participant, ok := r.domainPeerFromInputPeer(userID, req.Participant)
|
||||
if !ok || participant.Type != domain.PeerTypeUser || participant.ID == 0 {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
res, err := r.deps.Channels.EditMemberRank(ctx, userID, domain.EditChannelMemberRankRequest{
|
||||
UserID: userID,
|
||||
ChannelID: channelID,
|
||||
MemberID: participant.ID,
|
||||
Rank: req.Rank,
|
||||
Date: int(r.clock.Now().Unix()),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, channelAdminErr(err)
|
||||
}
|
||||
cache := newViewerPeerCache(r)
|
||||
updates := r.channelParticipantUpdatesWithPeerCache(ctx, userID, userID, res.Channel, res.Previous, res.Participant, res.Date, cache)
|
||||
r.pushChannelUpdates(ctx, userID, res.Channel.ID, res.Recipients, func(viewerUserID int64) *tg.Updates {
|
||||
return r.channelParticipantUpdatesWithPeerCache(ctx, viewerUserID, userID, res.Channel, res.Previous, res.Participant, res.Date, cache)
|
||||
})
|
||||
return updates, nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesSetChatTheme(ctx context.Context, req *tg.MessagesSetChatThemeRequest) (tg.UpdatesClass, error) {
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if channelID, err := r.channelIDFromLegacyInputPeerChecked(ctx, userID, req.Peer); err == nil {
|
||||
if r.deps.Channels == nil {
|
||||
return nil, notImplementedErr()
|
||||
}
|
||||
view, err := r.deps.Channels.GetChannel(ctx, userID, channelID)
|
||||
if err != nil {
|
||||
return nil, channelInvalidErr(err)
|
||||
}
|
||||
return r.channelStateUpdates(userID, view.Channel), nil
|
||||
} else if _, ok := channelIDFromLegacyInputPeer(userID, req.Peer); ok {
|
||||
return nil, err
|
||||
}
|
||||
peer, ok := r.domainPeerFromInputPeer(userID, req.Peer)
|
||||
if !ok || peer.Type != domain.PeerTypeUser || peer.ID == 0 {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
emoticon, err := chatThemeEmoticonFromInput(req.Theme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if r.deps.Messages == nil {
|
||||
return tgEmptyUpdates(int(r.clock.Now().Unix())), nil
|
||||
}
|
||||
recipientBlocked, err := r.peerBlocksUser(ctx, userID, peer.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authKeyID, _ := AuthKeyIDFrom(ctx)
|
||||
sessionID, _ := SessionIDFrom(ctx)
|
||||
res, err := r.deps.Messages.SetChatTheme(ctx, userID, domain.SetPrivateChatThemeRequest{
|
||||
OwnerUserID: userID,
|
||||
Peer: peer,
|
||||
Emoticon: emoticon,
|
||||
Date: int(r.clock.Now().Unix()),
|
||||
OriginAuthKeyID: authKeyID,
|
||||
OriginSessionID: sessionID,
|
||||
RecipientBlocked: recipientBlocked,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, domain.ErrMessageIDInvalid) {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
return nil, internalErr()
|
||||
}
|
||||
if res.Changed {
|
||||
r.invalidateRPCProjectionForPeer(userID, peer)
|
||||
r.invalidateRPCProjectionForPeer(peer.ID, domain.Peer{Type: domain.PeerTypeUser, ID: userID})
|
||||
}
|
||||
if !res.Changed || res.Send.SenderMessage.ID == 0 {
|
||||
return tgEmptyUpdates(int(r.clock.Now().Unix())), nil
|
||||
}
|
||||
return tgPrivateMessageUpdates(
|
||||
res.Send.SenderEvent,
|
||||
res.Send.SenderMessage,
|
||||
0,
|
||||
false,
|
||||
r.usersForMessageUpdate(ctx, userID, res.Send.SenderMessage),
|
||||
[]tg.ChatClass{},
|
||||
), nil
|
||||
}
|
||||
|
||||
func chatThemeEmoticonFromInput(theme tg.InputChatThemeClass) (string, error) {
|
||||
switch value := theme.(type) {
|
||||
case *tg.InputChatThemeEmpty:
|
||||
return "", nil
|
||||
case *tg.InputChatTheme:
|
||||
if value.Emoticon == "" {
|
||||
return "", nil
|
||||
}
|
||||
if !tdesktop.IsChatThemeEmoticon(value.Emoticon) {
|
||||
return "", themeInvalidErr()
|
||||
}
|
||||
return value.Emoticon, nil
|
||||
case *tg.InputChatThemeUniqueGift:
|
||||
return "", themeInvalidErr()
|
||||
default:
|
||||
return "", inputConstructorInvalidErr()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesSetChatWallPaper(ctx context.Context, req *tg.MessagesSetChatWallPaperRequest) (tg.UpdatesClass, error) {
|
||||
if req == nil {
|
||||
return nil, inputConstructorInvalidErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
peer, err := r.checkedDomainPeerFromInputPeer(ctx, userID, req.Peer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wallpaper, err := domainWallpaperFromSetChatWallPaper(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch peer.Type {
|
||||
case domain.PeerTypeUser:
|
||||
if peer.ID == 0 {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
return tgEmptyUpdates(int(r.clock.Now().Unix())), nil
|
||||
case domain.PeerTypeChannel:
|
||||
if r.deps.Channels == nil || peer.ID == 0 {
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
res, err := r.deps.Channels.SetWallpaper(ctx, userID, domain.SetChannelWallpaperRequest{
|
||||
UserID: userID,
|
||||
ChannelID: peer.ID,
|
||||
Wallpaper: wallpaper,
|
||||
Date: int(r.clock.Now().Unix()),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, channelAdminErr(err)
|
||||
}
|
||||
r.invalidateRPCProjectionForChannel(res.Channel.ID)
|
||||
if res.Changed && res.Event.Pts != 0 {
|
||||
r.enqueueChannelWallpaperFanout(ctx, userID, res)
|
||||
} else if res.Changed {
|
||||
r.pushChannelUpdates(ctx, userID, res.Channel.ID, res.Recipients, func(viewerUserID int64) *tg.Updates {
|
||||
return r.channelWallpaperUpdatesWithPeerCache(ctx, viewerUserID, res, nil)
|
||||
})
|
||||
}
|
||||
return r.channelWallpaperUpdatesWithPeerCache(ctx, userID, res, nil), nil
|
||||
default:
|
||||
return nil, peerIDInvalidErr()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Router) channelWallpaperUpdatesWithPeerCache(ctx context.Context, viewerUserID int64, res domain.SetChannelWallpaperResult, cache *viewerPeerCache) *tg.Updates {
|
||||
update := tgUpdatePeerWallpaper(domain.Peer{Type: domain.PeerTypeChannel, ID: res.Channel.ID}, res.Channel.Wallpaper)
|
||||
if res.Event.Pts != 0 {
|
||||
sendRes := domain.SendChannelMessageResult{
|
||||
Channel: res.Channel,
|
||||
Message: res.Message,
|
||||
Event: res.Event,
|
||||
Recipients: res.Recipients,
|
||||
}
|
||||
updates := r.channelMessageUpdatesWithPeerCache(ctx, viewerUserID, sendRes, 0, cache)
|
||||
updates.Updates = append(updates.Updates, update)
|
||||
return updates
|
||||
}
|
||||
return &tg.Updates{
|
||||
Updates: []tg.UpdateClass{update},
|
||||
Chats: []tg.ChatClass{tgChannelChatMin(viewerUserID, res.Channel)},
|
||||
Date: int(r.clock.Now().Unix()),
|
||||
Seq: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Router) enqueueChannelWallpaperFanout(ctx context.Context, originUserID int64, res domain.SetChannelWallpaperResult) {
|
||||
sendRes := domain.SendChannelMessageResult{
|
||||
Channel: res.Channel,
|
||||
Message: res.Message,
|
||||
Event: res.Event,
|
||||
Recipients: res.Recipients,
|
||||
}
|
||||
fanoutCache := newViewerPeerCache(r)
|
||||
ownerIDs := channelMessageFanoutOwnerIDs(sendRes, nil)
|
||||
r.enqueueChannelFanoutWithPrefetch(ctx, channelFanoutMembers, originUserID, res.Channel.ID, res.Event.Pts, res.Recipients,
|
||||
func(bgCtx context.Context, viewers []int64) {
|
||||
r.prefetchChannelFanoutUsers(bgCtx, fanoutCache, viewers, ownerIDs)
|
||||
},
|
||||
func(bgCtx context.Context, viewerUserID int64) *tg.Updates {
|
||||
return r.channelWallpaperUpdatesWithPeerCache(bgCtx, viewerUserID, res, fanoutCache)
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesToggleNoForwards(ctx context.Context, req *tg.MessagesToggleNoForwardsRequest) (tg.UpdatesClass, error) {
|
||||
if r.deps.Channels == nil {
|
||||
return nil, notImplementedErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
channelID, err := r.channelIDFromLegacyInputPeerChecked(ctx, userID, req.Peer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
channel, err := r.deps.Channels.SetNoForwards(ctx, userID, channelID, req.Enabled)
|
||||
if err != nil {
|
||||
return nil, channelAdminErr(err)
|
||||
}
|
||||
return r.channelStateMutationUpdates(ctx, userID, channel), nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesSetChatAvailableReactions(ctx context.Context, req *tg.MessagesSetChatAvailableReactionsRequest) (tg.UpdatesClass, error) {
|
||||
if r.deps.Channels == nil {
|
||||
return nil, notImplementedErr()
|
||||
}
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
channelID, err := r.channelIDFromLegacyInputPeerChecked(ctx, userID, req.Peer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policy, err := domainChannelReactionPolicy(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
channel, err := r.deps.Channels.SetAvailableReactions(ctx, userID, channelID, policy)
|
||||
if err != nil {
|
||||
return nil, channelAdminErr(err)
|
||||
}
|
||||
return r.channelStateMutationUpdates(ctx, userID, channel), nil
|
||||
}
|
||||
|
||||
func legacyBasicGroupAdminRights() tg.ChatAdminRights {
|
||||
return tg.ChatAdminRights{
|
||||
ChangeInfo: true,
|
||||
DeleteMessages: true,
|
||||
BanUsers: true,
|
||||
InviteUsers: true,
|
||||
PinMessages: true,
|
||||
Other: true,
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue