130 lines
4 KiB
Go
130 lines
4 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"github.com/gotd/td/tg"
|
|
"telesrv/internal/domain"
|
|
)
|
|
|
|
func (r *Router) onChannelsReadMessageContents(ctx context.Context, req *tg.ChannelsReadMessageContentsRequest) (bool, error) {
|
|
if r.deps.Channels == nil {
|
|
return false, notImplementedErr()
|
|
}
|
|
if req == nil {
|
|
return false, inputRequestInvalidErr()
|
|
}
|
|
userID, _, err := r.currentUserID(ctx)
|
|
if err != nil {
|
|
return false, internalErr()
|
|
}
|
|
channelID, err := r.channelIDFromInput(ctx, userID, req.Channel)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
read, err := r.deps.Channels.ReadMessageContents(ctx, userID, domain.ReadChannelMessageContentsRequest{
|
|
UserID: userID,
|
|
ChannelID: channelID,
|
|
IDs: req.ID,
|
|
})
|
|
if err != nil {
|
|
if errors.Is(err, domain.ErrMessageIDInvalid) {
|
|
return false, messageIDInvalidErr()
|
|
}
|
|
return false, channelInvalidErr(err)
|
|
}
|
|
if ids := readChannelMessageContentIDs(read.Messages); len(ids) > 0 {
|
|
r.pushUserUpdates(ctx, userID, &tg.Updates{
|
|
Updates: []tg.UpdateClass{&tg.UpdateChannelReadMessagesContents{
|
|
ChannelID: read.Channel.ID,
|
|
Messages: ids,
|
|
}},
|
|
Users: []tg.UserClass{},
|
|
Chats: []tg.ChatClass{tgChannelChatMin(userID, read.Channel)},
|
|
Date: int(r.clock.Now().Unix()),
|
|
Seq: 0,
|
|
})
|
|
}
|
|
if len(read.ClearedUnreadReactionMessageIDs) > 0 {
|
|
r.pushUserUpdates(ctx, userID, r.channelMessagesReactionsUpdates(ctx, userID, domain.ChannelMessageReactionsResult{
|
|
Channel: read.Channel,
|
|
Messages: read.Messages,
|
|
}, read.ClearedUnreadReactionMessageIDs))
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (r *Router) onChannelsReadHistory(ctx context.Context, req *tg.ChannelsReadHistoryRequest) (bool, error) {
|
|
if r.deps.Channels == nil {
|
|
return true, nil
|
|
}
|
|
userID, _, err := r.currentUserID(ctx)
|
|
if err != nil {
|
|
return false, internalErr()
|
|
}
|
|
channelID, err := r.channelIDFromInput(ctx, userID, req.Channel)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
read, err := r.deps.Channels.ReadHistory(ctx, userID, domain.ReadChannelHistoryRequest{
|
|
UserID: userID,
|
|
ChannelID: channelID,
|
|
MaxID: req.MaxID,
|
|
Date: int(r.clock.Now().Unix()),
|
|
})
|
|
if err != nil {
|
|
return false, channelInvalidErr(err)
|
|
}
|
|
if _, err := r.recordChannelReadInbox(ctx, userID, read); err != nil {
|
|
return false, err
|
|
}
|
|
r.pushChannelReadOutboxUpdates(ctx, read.ChannelID, read.OutboxUpdates)
|
|
r.advanceForumGeneralReadAfterChannelRead(ctx, userID, read)
|
|
return true, nil
|
|
}
|
|
|
|
func domainChannelReactionPolicy(req *tg.MessagesSetChatAvailableReactionsRequest) (domain.ChannelReactionPolicy, error) {
|
|
if req == nil || req.AvailableReactions == nil {
|
|
return domain.ChannelReactionPolicy{}, tgerr400("REACTION_INVALID")
|
|
}
|
|
if req.ReactionsLimit < 0 || req.ReactionsLimit > domain.MaxChannelReactionsLimit {
|
|
return domain.ChannelReactionPolicy{}, limitInvalidErr()
|
|
}
|
|
policy := domain.ChannelReactionPolicy{
|
|
Limit: req.ReactionsLimit,
|
|
PaidEnabled: req.PaidEnabled,
|
|
}
|
|
switch reactions := req.AvailableReactions.(type) {
|
|
case *tg.ChatReactionsNone:
|
|
policy.Type = domain.ChannelReactionPolicyNone
|
|
case *tg.ChatReactionsAll:
|
|
policy.Type = domain.ChannelReactionPolicyAll
|
|
policy.AllowCustom = reactions.AllowCustom
|
|
case *tg.ChatReactionsSome:
|
|
if len(reactions.Reactions) > domain.MaxChannelReactionTypes {
|
|
return domain.ChannelReactionPolicy{}, limitInvalidErr()
|
|
}
|
|
policy.Type = domain.ChannelReactionPolicySome
|
|
seen := make(map[string]struct{}, len(reactions.Reactions))
|
|
for _, reaction := range reactions.Reactions {
|
|
parsed, err := domainMessageReactionFromTL(reaction)
|
|
if err != nil {
|
|
return domain.ChannelReactionPolicy{}, tgerr400("REACTION_INVALID")
|
|
}
|
|
key := parsed.Key()
|
|
if _, ok := seen[key]; ok {
|
|
continue
|
|
}
|
|
seen[key] = struct{}{}
|
|
switch parsed.Type {
|
|
case domain.MessageReactionEmoji:
|
|
policy.Emoticons = append(policy.Emoticons, parsed.Emoticon)
|
|
case domain.MessageReactionCustomEmoji:
|
|
policy.CustomEmojiIDs = append(policy.CustomEmojiIDs, parsed.DocumentID)
|
|
}
|
|
}
|
|
default:
|
|
return domain.ChannelReactionPolicy{}, tgerr400("REACTION_INVALID")
|
|
}
|
|
return policy, nil
|
|
}
|