156 lines
4.4 KiB
Go
156 lines
4.4 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/iamxvbaba/td/tg"
|
|
|
|
"telesrv/internal/domain"
|
|
)
|
|
|
|
func (r *Router) onMessagesTranslateText(ctx context.Context, req *tg.MessagesTranslateTextRequest) (*tg.MessagesTranslateResult, error) {
|
|
if req == nil {
|
|
return nil, inputTextEmptyErr()
|
|
}
|
|
userID, _, err := r.currentUserID(ctx)
|
|
if err != nil {
|
|
return nil, internalErr()
|
|
}
|
|
if r.deps.Translation == nil {
|
|
return nil, translationsDisabledErr()
|
|
}
|
|
if err := r.requireTranslationUser(ctx, userID); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
peerInput, idMode := req.GetPeer()
|
|
ids, idsSet := req.GetID()
|
|
texts, textMode := req.GetText()
|
|
if idMode != idsSet || idMode == textMode {
|
|
return nil, inputTextEmptyErr()
|
|
}
|
|
request := domain.TranslationRequest{
|
|
UserID: userID,
|
|
ToLang: req.ToLang,
|
|
Tone: req.Tone,
|
|
}
|
|
if idMode {
|
|
peer, err := r.checkedTranslationPeer(ctx, userID, peerInput)
|
|
if err != nil {
|
|
return nil, peerIDInvalidErr()
|
|
}
|
|
request.Peer = peer
|
|
request.IDs = append([]int(nil), ids...)
|
|
} else {
|
|
request.Texts = make([]domain.TranslationText, 0, len(texts))
|
|
for _, text := range texts {
|
|
request.Texts = append(request.Texts, domain.TranslationText{
|
|
Text: text.Text,
|
|
Entities: domainMessageEntitiesForViewer(userID, text.Entities),
|
|
})
|
|
}
|
|
}
|
|
result, err := r.deps.Translation.Translate(ctx, request)
|
|
if err != nil {
|
|
return nil, translationRPCErr(err)
|
|
}
|
|
out := &tg.MessagesTranslateResult{Result: make([]tg.TextWithEntities, 0, len(result.Texts))}
|
|
for _, text := range result.Texts {
|
|
out.Result = append(out.Result, tg.TextWithEntities{
|
|
Text: text.Text,
|
|
Entities: tgMessageEntities(text.Entities),
|
|
})
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func (r *Router) onMessagesTogglePeerTranslations(ctx context.Context, req *tg.MessagesTogglePeerTranslationsRequest) (bool, error) {
|
|
if req == nil || req.Peer == nil {
|
|
return false, peerIDInvalidErr()
|
|
}
|
|
userID, _, err := r.currentUserID(ctx)
|
|
if err != nil {
|
|
return false, internalErr()
|
|
}
|
|
if r.deps.Translation == nil {
|
|
return false, translationsDisabledErr()
|
|
}
|
|
if err := r.requireTranslationUser(ctx, userID); err != nil {
|
|
return false, err
|
|
}
|
|
peer, err := r.checkedTranslationPeer(ctx, userID, req.Peer)
|
|
if err != nil {
|
|
return false, peerIDInvalidErr()
|
|
}
|
|
if _, err := r.deps.Translation.SetPeerDisabled(ctx, userID, peer, req.Disabled); err != nil {
|
|
return false, translationRPCErr(err)
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (r *Router) requireTranslationUser(ctx context.Context, userID int64) error {
|
|
if r.deps.Users == nil {
|
|
return nil
|
|
}
|
|
self, err := r.deps.Users.Self(ctx, userID)
|
|
if err != nil {
|
|
return internalErr()
|
|
}
|
|
if self.Bot {
|
|
return botMethodInvalidErr()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *Router) checkedTranslationPeer(ctx context.Context, userID int64, input tg.InputPeerClass) (domain.Peer, error) {
|
|
peer, err := r.checkedDomainPeerFromInputPeer(ctx, userID, input)
|
|
if err != nil {
|
|
return domain.Peer{}, err
|
|
}
|
|
if peer.Type != domain.PeerTypeUser || r.deps.Users == nil {
|
|
return peer, nil
|
|
}
|
|
var userInput tg.InputUserClass
|
|
switch value := input.(type) {
|
|
case *tg.InputPeerSelf:
|
|
userInput = &tg.InputUserSelf{}
|
|
case *tg.InputPeerUser:
|
|
userInput = &tg.InputUser{UserID: value.UserID, AccessHash: value.AccessHash}
|
|
default:
|
|
return domain.Peer{}, peerIDInvalidErr()
|
|
}
|
|
_, found, err := r.userFromInput(ctx, userID, userInput)
|
|
if err != nil {
|
|
return domain.Peer{}, internalErr()
|
|
}
|
|
if !found {
|
|
return domain.Peer{}, peerIDInvalidErr()
|
|
}
|
|
return peer, nil
|
|
}
|
|
|
|
func translationRPCErr(err error) error {
|
|
switch {
|
|
case errors.Is(err, domain.ErrTranslationInputEmpty):
|
|
return inputTextEmptyErr()
|
|
case errors.Is(err, domain.ErrTranslationInputTooLong):
|
|
return inputTextTooLongErr()
|
|
case errors.Is(err, domain.ErrTranslationLanguageInvalid):
|
|
return toLangInvalidErr()
|
|
case errors.Is(err, domain.ErrTranslationMessageInvalid), errors.Is(err, domain.ErrMessageIDInvalid):
|
|
return msgIDInvalidErr()
|
|
case errors.Is(err, domain.ErrTranslationPeerInvalid), errors.Is(err, domain.ErrChannelInvalid), errors.Is(err, domain.ErrChannelPrivate):
|
|
return peerIDInvalidErr()
|
|
case errors.Is(err, domain.ErrTranslationRateLimited):
|
|
return translateReqQuotaExceededErr()
|
|
case errors.Is(err, domain.ErrTranslationDisabled):
|
|
return translationsDisabledErr()
|
|
case errors.Is(err, domain.ErrTranslationTimeout):
|
|
return translationTimeoutErr()
|
|
case errors.Is(err, domain.ErrTranslationProviderUnavailable):
|
|
return translateReqFailedErr()
|
|
default:
|
|
return internalErr()
|
|
}
|
|
}
|