rework with files upload in amo

This commit is contained in:
Pavel 2024-05-11 19:42:58 +03:00
parent 74dfb8d4be
commit 6dd5085bf6
3 changed files with 33 additions and 15 deletions

@ -77,6 +77,7 @@ func Run(ctx context.Context, config initialize.Config, logger *zap.Logger) erro
IntegrationID: config.IntegrationID, IntegrationID: config.IntegrationID,
IntegrationSecret: config.IntegrationSecret, IntegrationSecret: config.IntegrationSecret,
RateLimiter: rateLimiter, RateLimiter: rateLimiter,
AmoStorageURL: config.AmoStorageURL,
}) })
redisRepo := repository.NewRepository(repository.Deps{ redisRepo := repository.NewRepository(repository.Deps{

@ -26,6 +26,7 @@ type Config struct {
IntegrationID string `env:"INTEGRATION_ID" envDefault:"2dbd6329-9be6-41f2-aa5f-964b9e723e49"` IntegrationID string `env:"INTEGRATION_ID" envDefault:"2dbd6329-9be6-41f2-aa5f-964b9e723e49"`
// секрет интеграции // секрет интеграции
IntegrationSecret string `env:"INTEGRATION_SECRET" envDefault:"tNK3LwL4ovP0OBK4jKDHJ3646PqRJDOKQYgY6P2t6DCuV8LEzDzszTDY0Fhwmzc8"` IntegrationSecret string `env:"INTEGRATION_SECRET" envDefault:"tNK3LwL4ovP0OBK4jKDHJ3646PqRJDOKQYgY6P2t6DCuV8LEzDzszTDY0Fhwmzc8"`
AmoStorageURL string `env:"AMO_STORAGE_URL" envDefault:"https://drive-b.amocrm.ru"`
} }
func LoadConfig() (*Config, error) { func LoadConfig() (*Config, error) {

@ -11,6 +11,7 @@ import (
"net/url" "net/url"
"os" "os"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
"strings"
"time" "time"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
@ -25,6 +26,7 @@ type Amo struct {
integrationID string integrationID string
integrationSecret string integrationSecret string
rateLimiter *limiter.RateLimiter rateLimiter *limiter.RateLimiter
amoStorageURL string
} }
type AmoDeps struct { type AmoDeps struct {
@ -35,6 +37,7 @@ type AmoDeps struct {
IntegrationID string IntegrationID string
IntegrationSecret string IntegrationSecret string
RateLimiter *limiter.RateLimiter RateLimiter *limiter.RateLimiter
AmoStorageURL string
} }
func NewAmoClient(deps AmoDeps) *Amo { func NewAmoClient(deps AmoDeps) *Amo {
@ -49,6 +52,7 @@ func NewAmoClient(deps AmoDeps) *Amo {
integrationSecret: deps.IntegrationSecret, integrationSecret: deps.IntegrationSecret,
integrationID: deps.IntegrationID, integrationID: deps.IntegrationID,
rateLimiter: deps.RateLimiter, rateLimiter: deps.RateLimiter,
amoStorageURL: deps.AmoStorageURL,
} }
} }
@ -560,11 +564,11 @@ func (a *Amo) downloadFile(urlFile string) (*os.File, error) {
return nil, fmt.Errorf(errorMessage) return nil, fmt.Errorf(errorMessage)
} }
tmpFile, err := os.CreateTemp("", "downloaded_file_*") fileName := strings.Split(urlFile, "/")
tmpFile, err := os.Create(fileName[len(fileName)-1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer tmpFile.Close()
_, err = io.Copy(tmpFile, bytes.NewReader(resBody)) _, err = io.Copy(tmpFile, bytes.NewReader(resBody))
if err != nil { if err != nil {
@ -575,7 +579,6 @@ func (a *Amo) downloadFile(urlFile string) (*os.File, error) {
} }
func (a *Amo) UploadFileToAmo(urlFile string, accessToken string) (*models.ValuesFile, error) { func (a *Amo) UploadFileToAmo(urlFile string, accessToken string) (*models.ValuesFile, error) {
fmt.Println(urlFile)
localFile, err := a.downloadFile(urlFile) localFile, err := a.downloadFile(urlFile)
if err != nil { if err != nil {
return nil, err return nil, err
@ -590,11 +593,11 @@ func (a *Amo) UploadFileToAmo(urlFile string, accessToken string) (*models.Value
fileSize := fileInfo.Size() fileSize := fileInfo.Size()
createSessionData := &models.CreateSession{ createSessionData := &models.CreateSession{
FileName: urlFile, FileName: localFile.Name(),
FileSize: fileSize, FileSize: fileSize,
} }
uri := fmt.Sprintf("%s/v1.0/sessions", "https://drive-b.amocrm.ru") uri := fmt.Sprintf("%s/v1.0/sessions", a.amoStorageURL)
bodyBytes, err := json.Marshal(createSessionData) bodyBytes, err := json.Marshal(createSessionData)
if err != nil { if err != nil {
a.logger.Error("error marshal create session data:", zap.Error(err)) a.logger.Error("error marshal create session data:", zap.Error(err))
@ -627,6 +630,10 @@ func (a *Amo) UploadFileToAmo(urlFile string, accessToken string) (*models.Value
} }
response, err := a.createPart(resp, localFile) response, err := a.createPart(resp, localFile)
if err != nil {
a.logger.Error("error create part file sending to amo:", zap.Error(err))
return nil, err
}
return &models.ValuesFile{ return &models.ValuesFile{
Value: models.ValueFile{ Value: models.ValueFile{
@ -639,6 +646,7 @@ func (a *Amo) UploadFileToAmo(urlFile string, accessToken string) (*models.Value
} }
func (a *Amo) createPart(uploadData models.UploadSession, file *os.File) (*models.UploadedFile, error) { func (a *Amo) createPart(uploadData models.UploadSession, file *os.File) (*models.UploadedFile, error) {
defer file.Close()
fileInfo, err := file.Stat() fileInfo, err := file.Stat()
if err != nil { if err != nil {
return nil, err return nil, err
@ -647,11 +655,12 @@ func (a *Amo) createPart(uploadData models.UploadSession, file *os.File) (*model
fileSize := fileInfo.Size() fileSize := fileInfo.Size()
var uploadedFile models.UploadedFile var uploadedFile models.UploadedFile
maxSize := uploadData.MaxPartSize
var remainingSize = fileSize var remainingSize = fileSize
var start int64 = 0 var start int64 = 0
for remainingSize > 0 { for remainingSize > 0 {
end := start + uploadData.MaxPartSize end := start + maxSize
if end > fileSize { if end > fileSize {
end = fileSize end = fileSize
} }
@ -688,23 +697,30 @@ func (a *Amo) createPart(uploadData models.UploadSession, file *os.File) (*model
return nil, fmt.Errorf("request failed: %v", errs[0]) return nil, fmt.Errorf("request failed: %v", errs[0])
} }
if statusCode != http.StatusOK { if statusCode != http.StatusOK && statusCode != http.StatusAccepted {
return nil, fmt.Errorf("failed to upload part file to amo, status: %d", statusCode) return nil, fmt.Errorf("failed to upload part file to amo, status: %d, respBody: %s", statusCode, string(resBody))
} }
start = end start = end
remainingSize -= partSize remainingSize -= partSize
var newUploadData models.UploadSession if statusCode == http.StatusAccepted {
if err := json.Unmarshal(resBody, &newUploadData); err == nil { var next struct {
uploadData = newUploadData NextUrl string `json:"next_url"`
} else { SessionID int `json:"session_id"`
if err := json.Unmarshal(resBody, &uploadedFile); err != nil { }
if err := json.Unmarshal(resBody, &next); err != nil {
return nil, err return nil, err
} }
break uploadData.UploadURL = next.NextUrl
continue
} }
if err := json.Unmarshal(resBody, &uploadedFile); err != nil {
return nil, err
}
return &uploadedFile, nil
} }
return &uploadedFile, nil return nil, nil
} }