142 lines
4 KiB
Go
142 lines
4 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/gotd/td/tg"
|
|
|
|
"telesrv/internal/domain"
|
|
)
|
|
|
|
const (
|
|
maxPremiumBoostsListLimit = 100
|
|
maxPremiumBoostsOffsetBytes = 128
|
|
maxPremiumApplyBoostSlots = 16
|
|
)
|
|
|
|
func (r *Router) registerPremium(d *tg.ServerDispatcher) {
|
|
d.OnPremiumGetBoostsStatus(r.onPremiumGetBoostsStatus)
|
|
d.OnPremiumGetBoostsList(r.onPremiumGetBoostsList)
|
|
d.OnPremiumGetMyBoosts(r.onPremiumGetMyBoosts)
|
|
d.OnPremiumApplyBoost(r.onPremiumApplyBoost)
|
|
d.OnPremiumGetUserBoosts(r.onPremiumGetUserBoosts)
|
|
}
|
|
|
|
func (r *Router) onPremiumGetBoostsStatus(ctx context.Context, peer tg.InputPeerClass) (*tg.PremiumBoostsStatus, error) {
|
|
if _, _, err := r.premiumBoostChannelView(ctx, peer, false); err != nil {
|
|
return nil, err
|
|
}
|
|
return emptyPremiumBoostsStatus(), nil
|
|
}
|
|
|
|
func (r *Router) onPremiumGetBoostsList(ctx context.Context, req *tg.PremiumGetBoostsListRequest) (*tg.PremiumBoostsList, error) {
|
|
if req.Limit < 0 || req.Limit > maxPremiumBoostsListLimit || len(req.Offset) > maxPremiumBoostsOffsetBytes {
|
|
return nil, limitInvalidErr()
|
|
}
|
|
if _, _, err := r.premiumBoostChannelView(ctx, req.Peer, true); err != nil {
|
|
return nil, err
|
|
}
|
|
return emptyPremiumBoostsList(), nil
|
|
}
|
|
|
|
func (r *Router) onPremiumGetMyBoosts(ctx context.Context) (*tg.PremiumMyBoosts, error) {
|
|
if _, _, err := r.currentUserID(ctx); err != nil {
|
|
return nil, internalErr()
|
|
}
|
|
return emptyPremiumMyBoosts(), nil
|
|
}
|
|
|
|
func (r *Router) onPremiumApplyBoost(ctx context.Context, req *tg.PremiumApplyBoostRequest) (*tg.PremiumMyBoosts, error) {
|
|
slots, ok := req.GetSlots()
|
|
if !ok {
|
|
return nil, tgerr400("BOOSTS_EMPTY")
|
|
}
|
|
if len(slots) == 0 {
|
|
return nil, tgerr400("SLOTS_EMPTY")
|
|
}
|
|
if len(slots) > maxPremiumApplyBoostSlots {
|
|
return nil, limitInvalidErr()
|
|
}
|
|
for _, slot := range slots {
|
|
if slot < 0 {
|
|
return nil, tgerr400("SLOTS_INVALID")
|
|
}
|
|
}
|
|
if _, _, err := r.premiumBoostChannelView(ctx, req.Peer, false); err != nil {
|
|
return nil, err
|
|
}
|
|
return emptyPremiumMyBoosts(), nil
|
|
}
|
|
|
|
func (r *Router) onPremiumGetUserBoosts(ctx context.Context, req *tg.PremiumGetUserBoostsRequest) (*tg.PremiumBoostsList, error) {
|
|
userID, view, err := r.premiumBoostChannelView(ctx, req.Peer, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, err := r.userIDsFromInputUsers(ctx, userID, []tg.InputUserClass{req.UserID}); err != nil {
|
|
return nil, err
|
|
}
|
|
_ = view
|
|
return emptyPremiumBoostsList(), nil
|
|
}
|
|
|
|
func (r *Router) premiumBoostChannelView(ctx context.Context, peer tg.InputPeerClass, requireAdmin bool) (int64, domain.ChannelView, error) {
|
|
ref, ok := premiumBoostChannelRef(peer)
|
|
if !ok {
|
|
return 0, domain.ChannelView{}, peerIDInvalidErr()
|
|
}
|
|
input := &tg.InputChannel{ChannelID: ref.ID}
|
|
if ref.CheckAccessHash {
|
|
input.AccessHash = ref.AccessHash
|
|
}
|
|
userID, view, err := r.channelView(ctx, input)
|
|
if err != nil {
|
|
return 0, domain.ChannelView{}, err
|
|
}
|
|
if requireAdmin && view.Self.Role != domain.ChannelRoleCreator && view.Self.Role != domain.ChannelRoleAdmin {
|
|
return 0, domain.ChannelView{}, tgerr400("CHAT_ADMIN_REQUIRED")
|
|
}
|
|
return userID, view, nil
|
|
}
|
|
|
|
func premiumBoostChannelRef(peer tg.InputPeerClass) (channelInputRef, bool) {
|
|
switch p := peer.(type) {
|
|
case *tg.InputPeerChannel:
|
|
return channelInputRef{
|
|
ID: p.ChannelID,
|
|
AccessHash: p.AccessHash,
|
|
CheckAccessHash: p.AccessHash != 0,
|
|
}, p.ChannelID > 0
|
|
case *tg.InputPeerChannelFromMessage:
|
|
return channelInputRef{ID: p.ChannelID}, p.ChannelID > 0
|
|
case *tg.InputPeerChat:
|
|
return channelInputRef{ID: p.ChatID}, p.ChatID > 0
|
|
default:
|
|
return channelInputRef{}, false
|
|
}
|
|
}
|
|
|
|
func emptyPremiumBoostsStatus() *tg.PremiumBoostsStatus {
|
|
return &tg.PremiumBoostsStatus{
|
|
Level: 0,
|
|
CurrentLevelBoosts: 0,
|
|
Boosts: 0,
|
|
BoostURL: "",
|
|
}
|
|
}
|
|
|
|
func emptyPremiumBoostsList() *tg.PremiumBoostsList {
|
|
return &tg.PremiumBoostsList{
|
|
Count: 0,
|
|
Boosts: []tg.Boost{},
|
|
Users: []tg.UserClass{},
|
|
}
|
|
}
|
|
|
|
func emptyPremiumMyBoosts() *tg.PremiumMyBoosts {
|
|
return &tg.PremiumMyBoosts{
|
|
MyBoosts: []tg.MyBoost{},
|
|
Chats: []tg.ChatClass{},
|
|
Users: []tg.UserClass{},
|
|
}
|
|
}
|