owpengram-server/internal/rpc/account_reports.go
2026-07-24 11:56:59 +08:00

108 lines
3.4 KiB
Go

package rpc
import (
"context"
"unicode/utf8"
"github.com/iamxvbaba/td/tg"
"github.com/iamxvbaba/td/tgerr"
"telesrv/internal/domain"
)
func (r *Router) onAccountReportPeer(ctx context.Context, req *tg.AccountReportPeerRequest) (bool, error) {
if req == nil || req.Reason == nil {
return false, inputRequestInvalidErr()
}
if !utf8.ValidString(req.Message) || utf8.RuneCountInString(req.Message) > domain.MaxModerationCommentRunes {
return false, limitInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return false, internalErr()
}
target, err := r.checkedDomainPeerFromInputPeer(ctx, userID, req.Peer)
if err != nil {
return false, err
}
reason, ok := moderationReasonFromReportReason(req.Reason)
if !ok {
return false, tgerr.New(400, "REASON_INVALID")
}
if r.deps.Moderation == nil {
return false, internalErr()
}
if _, _, err := r.deps.Moderation.ReportPeer(
ctx, userID, domain.ModerationSourceAccountPeer, target,
reason, string(reason), req.Message, r.clock.Now(),
); err != nil {
return false, moderationReportError(err)
}
return true, nil
}
func (r *Router) onAccountReportProfilePhoto(ctx context.Context, req *tg.AccountReportProfilePhotoRequest) (bool, error) {
if req == nil || req.Reason == nil {
return false, inputRequestInvalidErr()
}
if !utf8.ValidString(req.Message) || utf8.RuneCountInString(req.Message) > domain.MaxModerationCommentRunes {
return false, limitInvalidErr()
}
photo, ok := req.PhotoID.(*tg.InputPhoto)
if !ok || photo == nil || photo.ID <= 0 {
return false, photoInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return false, internalErr()
}
target, err := r.checkedDomainPeerFromInputPeer(ctx, userID, req.Peer)
if err != nil {
return false, err
}
reason, ok := moderationReasonFromReportReason(req.Reason)
if !ok {
return false, tgerr.New(400, "REASON_INVALID")
}
if r.deps.Moderation == nil {
return false, internalErr()
}
if _, _, err := r.deps.Moderation.ReportProfilePhoto(ctx, domain.ModerationProfilePhotoReportRequest{
ReporterUserID: userID, Target: target, PhotoID: photo.ID,
AccessHash: photo.AccessHash, FileReference: append([]byte(nil), photo.FileReference...),
Reason: reason, Comment: req.Message, CreatedAt: r.clock.Now(),
}); err != nil {
if err == domain.ErrModerationEvidenceNotFound {
return false, photoInvalidErr()
}
return false, moderationReportError(err)
}
return true, nil
}
func moderationReasonFromReportReason(reason tg.ReportReasonClass) (domain.ModerationReason, bool) {
switch reason.(type) {
case *tg.InputReportReasonSpam:
return domain.ModerationReasonSpam, true
case *tg.InputReportReasonViolence:
return domain.ModerationReasonViolence, true
case *tg.InputReportReasonPornography:
return domain.ModerationReasonPornography, true
case *tg.InputReportReasonChildAbuse:
return domain.ModerationReasonChildAbuse, true
case *tg.InputReportReasonOther:
return domain.ModerationReasonOther, true
case *tg.InputReportReasonCopyright:
return domain.ModerationReasonCopyright, true
case *tg.InputReportReasonGeoIrrelevant:
return domain.ModerationReasonGeoIrrelevant, true
case *tg.InputReportReasonFake:
return domain.ModerationReasonFake, true
case *tg.InputReportReasonIllegalDrugs:
return domain.ModerationReasonIllegalDrugs, true
case *tg.InputReportReasonPersonalDetails:
return domain.ModerationReasonPersonalDetails, true
default:
return "", false
}
}