83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/iamxvbaba/td/tg"
|
|
|
|
"telesrv/internal/domain"
|
|
)
|
|
|
|
func (r *Router) ensureVoiceMessagesAllowed(ctx context.Context, senderUserID int64, peer domain.Peer, voiceOrRound bool) error {
|
|
if !voiceOrRound || peer.Type != domain.PeerTypeUser || peer.ID == 0 || peer.ID == senderUserID || r.deps.Privacy == nil {
|
|
return nil
|
|
}
|
|
allowed, err := r.deps.Privacy.CanSee(ctx, peer.ID, senderUserID, domain.PrivacyKeyVoiceMessages)
|
|
if err != nil {
|
|
return internalErr()
|
|
}
|
|
if !allowed {
|
|
return chatSendVoicesForbiddenErr()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// preflightVoiceOrRound inspects upload attributes and referenced documents
|
|
// before resolveInputMedia materializes any uploaded blob. Referenced document
|
|
// misses are loaded in one bounded read-model batch.
|
|
func (r *Router) preflightVoiceOrRound(ctx context.Context, inputs []tg.InputMediaClass) (bool, error) {
|
|
documentIDs := make([]int64, 0)
|
|
seen := make(map[int64]struct{})
|
|
for _, input := range inputs {
|
|
switch media := input.(type) {
|
|
case *tg.InputMediaUploadedDocument:
|
|
if documentAttributesVoiceOrRound(domainDocumentAttributes(media.Attributes)) {
|
|
return true, nil
|
|
}
|
|
case *tg.InputMediaDocument:
|
|
ids, ok := inputDocumentCandidateIDs(media.ID)
|
|
if !ok {
|
|
continue // resolveInputMedia retains MEDIA_INVALID precedence.
|
|
}
|
|
for _, id := range ids {
|
|
if id == 0 {
|
|
continue
|
|
}
|
|
if _, ok := seen[id]; ok {
|
|
continue
|
|
}
|
|
seen[id] = struct{}{}
|
|
documentIDs = append(documentIDs, id)
|
|
}
|
|
}
|
|
}
|
|
if len(documentIDs) == 0 || r.deps.Files == nil {
|
|
return false, nil
|
|
}
|
|
documents, err := r.deps.Files.GetDocuments(ctx, documentIDs)
|
|
if err != nil {
|
|
return false, internalErr()
|
|
}
|
|
for _, document := range documents {
|
|
if documentAttributesVoiceOrRound(document.Attributes) {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func documentAttributesVoiceOrRound(attributes []domain.DocumentAttribute) bool {
|
|
for _, attribute := range attributes {
|
|
switch attribute.Kind {
|
|
case domain.DocAttrAudio:
|
|
if attribute.Voice {
|
|
return true
|
|
}
|
|
case domain.DocAttrVideo:
|
|
if attribute.RoundMessage {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|