2024-04-08 15:48:24 +00:00
|
|
|
|
package amoClient
|
2024-04-04 18:02:10 +00:00
|
|
|
|
|
|
|
|
|
import (
|
2024-05-10 15:34:34 +00:00
|
|
|
|
"bytes"
|
2024-04-04 18:32:56 +00:00
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
2025-02-27 13:30:52 +00:00
|
|
|
|
"gitea.pena/SQuiz/amocrm/internal/models"
|
|
|
|
|
"gitea.pena/SQuiz/amocrm/internal/workers/limiter"
|
|
|
|
|
"gitea.pena/SQuiz/common/model"
|
2024-05-10 15:34:34 +00:00
|
|
|
|
"io"
|
2024-04-08 08:20:10 +00:00
|
|
|
|
"net/url"
|
2024-05-10 15:34:34 +00:00
|
|
|
|
"os"
|
2024-05-11 16:42:58 +00:00
|
|
|
|
"strings"
|
2024-05-11 17:17:15 +00:00
|
|
|
|
"sync"
|
2024-04-10 10:53:19 +00:00
|
|
|
|
"time"
|
2024-04-08 08:20:10 +00:00
|
|
|
|
|
2024-04-04 18:02:10 +00:00
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Amo struct {
|
2024-04-09 15:52:37 +00:00
|
|
|
|
fiberClient *fiber.Client
|
|
|
|
|
logger *zap.Logger
|
|
|
|
|
redirectionURL string
|
|
|
|
|
integrationID string
|
|
|
|
|
integrationSecret string
|
2024-04-22 07:49:46 +00:00
|
|
|
|
rateLimiter *limiter.RateLimiter
|
2024-05-11 17:17:15 +00:00
|
|
|
|
fileMutex sync.Mutex
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type AmoDeps struct {
|
2024-04-09 15:52:37 +00:00
|
|
|
|
FiberClient *fiber.Client
|
|
|
|
|
Logger *zap.Logger
|
|
|
|
|
RedirectionURL string
|
|
|
|
|
IntegrationID string
|
|
|
|
|
IntegrationSecret string
|
2024-04-22 07:49:46 +00:00
|
|
|
|
RateLimiter *limiter.RateLimiter
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewAmoClient(deps AmoDeps) *Amo {
|
|
|
|
|
if deps.FiberClient == nil {
|
|
|
|
|
deps.FiberClient = fiber.AcquireClient()
|
|
|
|
|
}
|
|
|
|
|
return &Amo{
|
2024-04-09 15:52:37 +00:00
|
|
|
|
fiberClient: deps.FiberClient,
|
|
|
|
|
logger: deps.Logger,
|
|
|
|
|
redirectionURL: deps.RedirectionURL,
|
|
|
|
|
integrationSecret: deps.IntegrationSecret,
|
|
|
|
|
integrationID: deps.IntegrationID,
|
2024-04-10 10:53:19 +00:00
|
|
|
|
rateLimiter: deps.RateLimiter,
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-12 14:51:26 +00:00
|
|
|
|
// токен должен быть с правами администратора
|
2024-04-04 18:02:10 +00:00
|
|
|
|
// https://www.amocrm.ru/developers/content/crm_platform/users-api#users-list
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) GetUserList(req models.RequestGetListUsers, accesToken string, domain string) (*models.ResponseGetListUsers, error) {
|
2024-04-10 10:53:19 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/ajax/v3/users?with=rights&page=%d&limit=%d", domain, req.Page, req.Limit)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Get(uri)
|
2024-04-19 16:05:42 +00:00
|
|
|
|
agent.Set("Authorization", "Bearer "+accesToken)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err := range errs {
|
|
|
|
|
a.logger.Error("error sending request in GetUserList", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request GetUserList failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
switch statusCode {
|
|
|
|
|
case fiber.StatusForbidden:
|
|
|
|
|
errorMessage := fmt.Sprintf("error GetUserList StatusForbidden - %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
case fiber.StatusUnauthorized:
|
|
|
|
|
errorMessage := fmt.Sprintf("error GetUserList StatusUnauthorized - %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
default:
|
|
|
|
|
errorMessage := fmt.Sprintf("error GetUserList statusCode - %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-17 12:21:06 +00:00
|
|
|
|
var userListResponse models.ResponseGetListUsers
|
2024-04-10 10:53:19 +00:00
|
|
|
|
err := json.Unmarshal(resBody, &userListResponse)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal ResponseGetListUsers:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &userListResponse, nil
|
2024-04-04 18:32:56 +00:00
|
|
|
|
}
|
2024-04-22 07:49:46 +00:00
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
2024-04-04 18:32:56 +00:00
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://www.amocrm.ru/developers/content/oauth/step-by-step
|
2024-04-05 08:52:10 +00:00
|
|
|
|
// POST /oauth2/access_token
|
|
|
|
|
// тут и создание по коду и обновление по рефрешу в этом клиенте
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) CreateWebHook(req models.WebHookRequest, domain string) (*models.CreateWebHookResp, error) {
|
2024-04-10 10:53:19 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
|
|
|
|
req.SetClientID(a.integrationID)
|
|
|
|
|
req.SetClientSecret(a.integrationSecret)
|
|
|
|
|
req.SetRedirectURL(a.redirectionURL)
|
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal req in CreateWebHook:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-06-05 13:27:14 +00:00
|
|
|
|
agent := a.fiberClient.Post("https://" + domain + "/oauth2/access_token")
|
2024-04-10 10:53:19 +00:00
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request in CreateWebHook for create or update tokens", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
2024-04-11 15:50:27 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from CreateWebHook: %s", string(resBody))
|
2024-04-10 10:53:19 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-17 12:21:06 +00:00
|
|
|
|
var tokens models.CreateWebHookResp
|
2024-04-10 10:53:19 +00:00
|
|
|
|
err = json.Unmarshal(resBody, &tokens)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal CreateWebHookResp:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &tokens, nil
|
2024-04-05 08:52:10 +00:00
|
|
|
|
}
|
2024-04-22 07:49:46 +00:00
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
2024-04-05 08:52:10 +00:00
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D1%81%D1%82%D0%B0%D1%82%D1%83%D1%81%D0%BE%D0%B2-%D0%B2%D0%BE%D1%80%D0%BE%D0%BD%D0%BA%D0%B8-%D1%81%D0%B4%D0%B5%D0%BB%D0%BE%D0%BA
|
|
|
|
|
// GET /api/v4/leads/pipelines/{pipeline_id}/statuses
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) GetListSteps(pipelineID int, accessToken string, domain string) (*models.ResponseGetListSteps, error) {
|
2024-04-10 10:53:19 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/leads/pipelines/%d/statuses", domain, pipelineID)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
agent := a.fiberClient.Get(uri)
|
2024-04-11 15:50:27 +00:00
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err := range errs {
|
|
|
|
|
a.logger.Error("error sending request in GetListSteps", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request GetListSteps failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
2024-04-11 15:50:27 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from GetListSteps: %s", string(resBody))
|
2024-04-10 10:53:19 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-17 12:21:06 +00:00
|
|
|
|
var listSteps models.ResponseGetListSteps
|
2024-04-10 10:53:19 +00:00
|
|
|
|
err := json.Unmarshal(resBody, &listSteps)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal ResponseGetListSteps:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &listSteps, nil
|
2024-04-05 12:16:20 +00:00
|
|
|
|
}
|
2024-04-22 07:49:46 +00:00
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
2024-04-05 12:16:20 +00:00
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://www.amocrm.ru/developers/content/crm_platform/custom-fields#%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D0%BF%D0%BE%D0%BB%D0%B5%D0%B9-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B8
|
2024-04-05 12:16:20 +00:00
|
|
|
|
// GET /api/v4/leads/custom_fields
|
|
|
|
|
// GET /api/v4/contacts/custom_fields
|
|
|
|
|
// GET /api/v4/companies/custom_fields
|
|
|
|
|
// GET /api/v4/customers/custom_fields
|
2024-04-12 11:52:38 +00:00
|
|
|
|
|
|
|
|
|
// пока без этих двух
|
2024-04-05 12:16:20 +00:00
|
|
|
|
// GET /api/v4/customers/segments/custom_fields
|
|
|
|
|
// GET /api/v4/catalogs/{catalog_id}/custom_fields
|
|
|
|
|
// эти методы все относятся к одному и тому же, поэтому на вход будет урл и рек стуктура, выход у них один и тот же
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) GetListFields(req models.GetListFieldsReq, accessToken string, domain string) (*models.ResponseGetListFields, error) {
|
2024-04-10 10:53:19 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
fullURL := fmt.Sprintf("https://%s/api/v4/%s/custom_fields?limit=%d&page=%d", domain, req.EntityType, req.Limit, req.Page)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
agent := a.fiberClient.Get(fullURL)
|
2024-04-12 11:52:38 +00:00
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err := range errs {
|
|
|
|
|
a.logger.Error("error sending request in GetListFields", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request GetListFields failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
2024-04-11 15:50:27 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from GetListFields: %s", string(resBody))
|
2024-04-10 10:53:19 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-17 12:21:06 +00:00
|
|
|
|
var listFields models.ResponseGetListFields
|
2024-04-10 10:53:19 +00:00
|
|
|
|
err := json.Unmarshal(resBody, &listFields)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal ResponseGetListFields:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &listFields, nil
|
2024-04-05 12:16:20 +00:00
|
|
|
|
}
|
2024-04-22 07:49:46 +00:00
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
2024-04-05 12:16:20 +00:00
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://www.amocrm.ru/developers/content/crm_platform/tags-api#%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D1%82%D0%B5%D0%B3%D0%BE%D0%B2-%D0%B4%D0%BB%D1%8F-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B8
|
2024-04-05 12:16:20 +00:00
|
|
|
|
// GET /api/v4/{entity_type:leads|contacts|companies|customers}/tags
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) GetListTags(req models.GetListTagsReq, accessToken string, domain string) (*models.ResponseGetListTags, error) {
|
2024-04-10 10:53:19 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
fullURL := fmt.Sprintf("https://%s/api/v4/%s/tags?", domain, req.EntityType)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
|
|
|
|
|
if req.Filter.Name != "" {
|
|
|
|
|
fullURL += "&filter[name]=" + url.QueryEscape(req.Filter.Name)
|
|
|
|
|
}
|
|
|
|
|
if len(req.Filter.ID) > 0 {
|
|
|
|
|
for _, id := range req.Filter.ID {
|
|
|
|
|
fullURL += fmt.Sprintf("&filter[id][]=%d", id)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if req.Filter.Query != "" {
|
|
|
|
|
fullURL += "&filter[query]=" + url.QueryEscape(req.Filter.Query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fullURL += fmt.Sprintf("&page=%d&limit=%d", req.Page, req.Limit)
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Get(fullURL)
|
2024-04-11 17:02:44 +00:00
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err := range errs {
|
|
|
|
|
a.logger.Error("error sending request in GetListTags", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request GetListTags failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-04 12:53:03 +00:00
|
|
|
|
a.logger.Info("Succesfull get tags:", zap.String("respBody", string(resBody)), zap.String("fullUrl", fullURL))
|
2024-11-04 12:46:19 +00:00
|
|
|
|
|
2024-04-10 10:53:19 +00:00
|
|
|
|
if statusCode != fiber.StatusOK {
|
2024-11-04 12:33:13 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from GetListTags(%s): %s", fullURL, string(resBody))
|
2024-04-10 10:53:19 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-17 12:21:06 +00:00
|
|
|
|
var listTags models.ResponseGetListTags
|
2024-04-10 10:53:19 +00:00
|
|
|
|
err := json.Unmarshal(resBody, &listTags)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal ResponseGetListTags:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &listTags, nil
|
2024-04-05 12:16:20 +00:00
|
|
|
|
}
|
2024-04-22 07:49:46 +00:00
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
2024-04-05 12:16:20 +00:00
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
2024-04-10 08:54:18 +00:00
|
|
|
|
|
2024-04-14 15:02:26 +00:00
|
|
|
|
// https://www.amocrm.ru/developers/content/crm_platform/account-info
|
|
|
|
|
// GET /api/v4/account
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) GetUserInfo(accessToken string, domain string) (*models.AmocrmUserInformation, error) {
|
2024-04-10 10:53:19 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-08 15:13:09 +00:00
|
|
|
|
url := fmt.Sprintf("https://%s/api/v4/account?with=drive_url", domain)
|
2024-05-10 15:34:34 +00:00
|
|
|
|
agent := a.fiberClient.Get(url)
|
2024-04-10 10:53:19 +00:00
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err := range errs {
|
|
|
|
|
a.logger.Error("error sending request in GetUserInfo", zap.Error(err))
|
|
|
|
|
}
|
2024-04-11 13:58:31 +00:00
|
|
|
|
return nil, fmt.Errorf("request GetUserInfo failed: %v", errs[0])
|
2024-04-10 10:53:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
2024-04-11 15:50:27 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from GetUserInfo: %s", string(resBody))
|
2024-04-10 10:53:19 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-17 12:21:06 +00:00
|
|
|
|
var userInfo models.AmocrmUserInformation
|
2024-04-10 10:53:19 +00:00
|
|
|
|
err := json.Unmarshal(resBody, &userInfo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal AmocrmUserInformation:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &userInfo, nil
|
2024-04-10 08:54:18 +00:00
|
|
|
|
}
|
2024-04-22 07:49:46 +00:00
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
2024-04-10 08:54:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-11 13:58:31 +00:00
|
|
|
|
|
2024-04-19 16:05:42 +00:00
|
|
|
|
// https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D0%B2%D0%BE%D1%80%D0%BE%D0%BD%D0%BE%D0%BA-%D1%81%D0%B4%D0%B5%D0%BB%D0%BE%D0%BA
|
|
|
|
|
// GET /api/v4/leads/pipelines
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) GetListPipelines(accessToken string, domain string) (*models.PipelineResponse, error) {
|
2024-04-11 13:58:31 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/leads/pipelines", domain)
|
2024-04-11 15:08:54 +00:00
|
|
|
|
agent := a.fiberClient.Get(uri)
|
2024-04-19 16:05:42 +00:00
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
2024-04-11 13:58:31 +00:00
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err := range errs {
|
2024-04-19 16:05:42 +00:00
|
|
|
|
a.logger.Error("error sending request in GetListPipelines", zap.Error(err))
|
2024-04-11 13:58:31 +00:00
|
|
|
|
}
|
2024-04-19 16:05:42 +00:00
|
|
|
|
return nil, fmt.Errorf("request GetListPipelines failed: %v", errs[0])
|
2024-04-11 13:58:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
2024-04-19 16:05:42 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from GetListPipelines: %s", string(resBody))
|
2024-04-11 13:58:31 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-19 16:05:42 +00:00
|
|
|
|
var userInfo models.PipelineResponse
|
2024-04-11 13:58:31 +00:00
|
|
|
|
err := json.Unmarshal(resBody, &userInfo)
|
|
|
|
|
if err != nil {
|
2024-04-19 16:05:42 +00:00
|
|
|
|
a.logger.Error("error unmarshal PipelineResponse:", zap.Error(err))
|
2024-04-11 13:58:31 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &userInfo, nil
|
|
|
|
|
}
|
2024-04-22 07:49:46 +00:00
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
2024-04-11 13:58:31 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-11 15:08:54 +00:00
|
|
|
|
|
2024-04-19 16:05:42 +00:00
|
|
|
|
// токен должен быть с правами администратора
|
|
|
|
|
// https://www.amocrm.ru/developers/content/crm_platform/users-api#user-detail
|
|
|
|
|
// GET /api/v4/users/{id
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) GetUserByID(id int32, accessToken string, domain string) (*models.OneUserInfo, error) {
|
2024-04-11 15:08:54 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/users/%d?with=role,uuid", domain, id)
|
2024-04-11 15:08:54 +00:00
|
|
|
|
agent := a.fiberClient.Get(uri)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err := range errs {
|
2024-04-19 16:05:42 +00:00
|
|
|
|
a.logger.Error("error sending request in GetUserByID", zap.Error(err))
|
2024-04-11 15:08:54 +00:00
|
|
|
|
}
|
2024-04-19 16:05:42 +00:00
|
|
|
|
return nil, fmt.Errorf("request GetUserByID failed: %v", errs[0])
|
2024-04-11 15:08:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
2024-05-04 18:38:36 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from Get User By ID:%s", string(resBody))
|
2024-04-11 15:08:54 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-19 16:05:42 +00:00
|
|
|
|
var userInfo models.OneUserInfo
|
2024-04-11 15:08:54 +00:00
|
|
|
|
err := json.Unmarshal(resBody, &userInfo)
|
|
|
|
|
if err != nil {
|
2024-05-04 18:38:36 +00:00
|
|
|
|
a.logger.Error("error unmarshal response body in Get User By ID:", zap.Error(err))
|
2024-04-11 15:08:54 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &userInfo, nil
|
|
|
|
|
}
|
2024-04-22 07:49:46 +00:00
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
2024-04-11 15:08:54 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-29 12:23:40 +00:00
|
|
|
|
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) AddFields(req []models.AddLeadsFields, entity model.EntityType, accessToken string, domain string) (*models.ResponseGetListFields, error) {
|
2024-04-29 12:23:40 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/%s/custom_fields", domain, entity)
|
2024-04-29 12:23:40 +00:00
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
2024-05-04 18:38:36 +00:00
|
|
|
|
a.logger.Error("error marshal req in Add Fields:", zap.Error(err))
|
2024-04-29 12:23:40 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
agent := a.fiberClient.Post(uri)
|
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
2024-05-04 18:38:36 +00:00
|
|
|
|
a.logger.Error("error sending request in Add Fields for add fields", zap.Error(err))
|
2024-04-29 12:23:40 +00:00
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
2024-05-04 18:38:36 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from Add Fields: %s", string(resBody))
|
2024-04-29 12:23:40 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var fields models.ResponseGetListFields
|
|
|
|
|
err = json.Unmarshal(resBody, &fields)
|
|
|
|
|
if err != nil {
|
2024-05-04 18:38:36 +00:00
|
|
|
|
a.logger.Error("error unmarshal response body in Add Fields:", zap.Error(err))
|
2024-04-29 12:23:40 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &fields, nil
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-04 18:38:36 +00:00
|
|
|
|
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) CreatingDeal(req []models.DealReq, accessToken string, domain string) ([]models.DealResp, error) {
|
2024-05-04 18:38:36 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/leads/complex", domain)
|
2024-05-04 18:38:36 +00:00
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal req in Creating Deal:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Post(uri)
|
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request in Creating Deal for creating deals", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from Creating Deal: %s", string(resBody))
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-05 12:22:54 +00:00
|
|
|
|
var resp []models.DealResp
|
2024-05-04 18:38:36 +00:00
|
|
|
|
err = json.Unmarshal(resBody, &resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal response body in Creating Deal:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-05 12:22:54 +00:00
|
|
|
|
return resp, nil
|
2024-05-04 18:38:36 +00:00
|
|
|
|
}
|
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-06 20:30:59 +00:00
|
|
|
|
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) UpdatingDeal(req []models.UpdateDealReq, accessToken string, domain string) (*models.UpdateDealResp, error) {
|
2024-05-06 20:30:59 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/leads", domain)
|
2024-05-06 20:30:59 +00:00
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal req in Updating Deal:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
agent := a.fiberClient.Patch(uri)
|
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
2024-06-15 22:10:58 +00:00
|
|
|
|
a.logger.Error("error sending request in Updating Deal for updating deals", zap.Error(err))
|
2024-05-06 20:30:59 +00:00
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from Updating Deal: %s", string(resBody))
|
2024-06-15 22:10:58 +00:00
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode), zap.String("domain", domain), zap.String("token", accessToken))
|
2024-05-06 20:30:59 +00:00
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var resp models.UpdateDealResp
|
|
|
|
|
err = json.Unmarshal(resBody, &resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal response body in Updating Deal:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
|
|
|
|
}
|
2024-05-08 09:33:03 +00:00
|
|
|
|
}
|
2024-05-06 20:30:59 +00:00
|
|
|
|
|
2024-06-05 13:27:14 +00:00
|
|
|
|
func (a *Amo) CreatingCustomer(req []models.Customer, accessToken string, domain string) (*models.CustomerResp, error) {
|
2024-05-08 09:33:03 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-05 13:27:14 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/customers", domain)
|
2024-05-08 09:33:03 +00:00
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal req in Creating Customer:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Post(uri)
|
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request in Creating Customer for creating customers", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from Creating Customer: %s", string(resBody))
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var resp models.CustomerResp
|
|
|
|
|
err = json.Unmarshal(resBody, &resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal response body in Creating Customer:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
|
|
|
|
}
|
2024-05-06 20:30:59 +00:00
|
|
|
|
}
|
2024-05-10 15:34:34 +00:00
|
|
|
|
|
2024-06-05 13:27:14 +00:00
|
|
|
|
// todo подумать на счет хранилища в амо
|
2024-05-10 15:34:34 +00:00
|
|
|
|
func (a *Amo) downloadFile(urlFile string) (*os.File, error) {
|
|
|
|
|
var err error
|
|
|
|
|
agent := a.fiberClient.Get(urlFile)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request for getting file by url", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from getting file by url: %s", string(resBody))
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-11 16:42:58 +00:00
|
|
|
|
fileName := strings.Split(urlFile, "/")
|
|
|
|
|
tmpFile, err := os.Create(fileName[len(fileName)-1])
|
2024-05-10 15:34:34 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, err = io.Copy(tmpFile, bytes.NewReader(resBody))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tmpFile, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-08 15:13:09 +00:00
|
|
|
|
func (a *Amo) UploadFileToAmo(urlFile string, accessToken string, driveURL string) (*models.ValuesFile, error) {
|
2024-05-11 17:17:15 +00:00
|
|
|
|
a.fileMutex.Lock()
|
|
|
|
|
defer a.fileMutex.Unlock()
|
2024-05-10 15:34:34 +00:00
|
|
|
|
localFile, err := a.downloadFile(urlFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defer os.Remove(localFile.Name())
|
|
|
|
|
|
|
|
|
|
fileInfo, err := os.Stat(localFile.Name())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileSize := fileInfo.Size()
|
|
|
|
|
createSessionData := &models.CreateSession{
|
2024-05-11 16:42:58 +00:00
|
|
|
|
FileName: localFile.Name(),
|
2024-05-10 15:34:34 +00:00
|
|
|
|
FileSize: fileSize,
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-08 15:13:09 +00:00
|
|
|
|
uri := fmt.Sprintf("%s/v1.0/sessions", driveURL)
|
2024-05-10 15:34:34 +00:00
|
|
|
|
bodyBytes, err := json.Marshal(createSessionData)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal create session data:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Post(uri)
|
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request to create session for upload file in amo", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from creating upload file session: %s", string(resBody))
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var resp models.UploadSession
|
|
|
|
|
err = json.Unmarshal(resBody, &resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal response body in creating upload file session:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response, err := a.createPart(resp, localFile)
|
2024-05-11 16:42:58 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error create part file sending to amo:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-05-10 15:34:34 +00:00
|
|
|
|
|
|
|
|
|
return &models.ValuesFile{
|
|
|
|
|
Value: models.ValueFile{
|
|
|
|
|
FileUUID: response.UUID,
|
|
|
|
|
VersionUUID: response.VersionUUID,
|
|
|
|
|
FileName: response.Name,
|
|
|
|
|
FileSize: response.Size,
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (a *Amo) createPart(uploadData models.UploadSession, file *os.File) (*models.UploadedFile, error) {
|
2024-05-11 16:42:58 +00:00
|
|
|
|
defer file.Close()
|
2024-05-10 15:34:34 +00:00
|
|
|
|
fileInfo, err := file.Stat()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileSize := fileInfo.Size()
|
|
|
|
|
|
|
|
|
|
var uploadedFile models.UploadedFile
|
2024-05-11 16:42:58 +00:00
|
|
|
|
maxSize := uploadData.MaxPartSize
|
2024-05-10 15:34:34 +00:00
|
|
|
|
var remainingSize = fileSize
|
|
|
|
|
var start int64 = 0
|
|
|
|
|
|
|
|
|
|
for remainingSize > 0 {
|
2024-05-11 16:42:58 +00:00
|
|
|
|
end := start + maxSize
|
2024-05-10 15:34:34 +00:00
|
|
|
|
if end > fileSize {
|
|
|
|
|
end = fileSize
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
partSize := end - start
|
|
|
|
|
|
|
|
|
|
partFile, err := os.OpenFile(file.Name(), os.O_RDONLY, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer partFile.Close()
|
|
|
|
|
|
|
|
|
|
_, err = partFile.Seek(start, io.SeekStart)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer := make([]byte, partSize)
|
|
|
|
|
_, err = partFile.Read(buffer)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Post(uploadData.UploadURL).Body(buffer)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request to upload part file to amo", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-13 08:23:32 +00:00
|
|
|
|
if statusCode != fiber.StatusOK && statusCode != fiber.StatusAccepted {
|
2024-05-11 16:42:58 +00:00
|
|
|
|
return nil, fmt.Errorf("failed to upload part file to amo, status: %d, respBody: %s", statusCode, string(resBody))
|
2024-05-10 15:34:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start = end
|
|
|
|
|
remainingSize -= partSize
|
|
|
|
|
|
2024-08-13 08:23:32 +00:00
|
|
|
|
if statusCode == fiber.StatusAccepted {
|
2024-05-11 16:42:58 +00:00
|
|
|
|
var next struct {
|
|
|
|
|
NextUrl string `json:"next_url"`
|
|
|
|
|
SessionID int `json:"session_id"`
|
|
|
|
|
}
|
|
|
|
|
if err := json.Unmarshal(resBody, &next); err != nil {
|
2024-05-10 15:34:34 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-05-11 16:42:58 +00:00
|
|
|
|
uploadData.UploadURL = next.NextUrl
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := json.Unmarshal(resBody, &uploadedFile); err != nil {
|
|
|
|
|
return nil, err
|
2024-05-10 15:34:34 +00:00
|
|
|
|
}
|
2024-05-11 16:42:58 +00:00
|
|
|
|
return &uploadedFile, nil
|
2024-05-10 15:34:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-11 16:42:58 +00:00
|
|
|
|
return nil, nil
|
2024-05-10 15:34:34 +00:00
|
|
|
|
}
|
2024-06-21 11:54:43 +00:00
|
|
|
|
|
2024-06-23 10:23:53 +00:00
|
|
|
|
func (a *Amo) CreateContact(req []models.CreateContactReq, domain, accessToken string) (*models.ContactResponse, error) {
|
2024-06-21 11:54:43 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/contacts", domain)
|
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal req in Creating Contact:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Post(uri)
|
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request in Creating Contact", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from Creating Contact: %s", string(resBody))
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var resp models.ContactResponse
|
|
|
|
|
err = json.Unmarshal(resBody, &resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal response body in Creating Contact:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-21 12:52:11 +00:00
|
|
|
|
|
2024-06-21 16:03:37 +00:00
|
|
|
|
func (a *Amo) UpdateContact(req models.CreateContactReq, domain, accessToken string, idContact int32) (*models.ContactResponse, error) {
|
2024-06-21 12:52:11 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-21 16:03:37 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/contacts/%d", domain, idContact)
|
2024-06-21 12:52:11 +00:00
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal req in Update Contact:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Patch(uri)
|
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request in Update Contact", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from Update Contact: %s", string(resBody))
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var resp models.ContactResponse
|
|
|
|
|
err = json.Unmarshal(resBody, &resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal response body in Update Contact:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-23 13:48:44 +00:00
|
|
|
|
func (a *Amo) LinkedContactToContact(req []models.LinkedContactReq, domain, accessToken string, id int32) (*models.LinkedContactResponse, error) {
|
2024-06-21 12:52:11 +00:00
|
|
|
|
for {
|
|
|
|
|
if a.rateLimiter.Check() {
|
2024-06-23 13:48:44 +00:00
|
|
|
|
uri := fmt.Sprintf("https://%s/api/v4/contacts/%d/link", domain, id)
|
2024-06-21 12:52:11 +00:00
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal req in Linked Contact To Contact:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Post(uri)
|
|
|
|
|
agent.Set("Content-Type", "application/json").Body(bodyBytes)
|
|
|
|
|
agent.Set("Authorization", "Bearer "+accessToken)
|
|
|
|
|
|
|
|
|
|
statusCode, resBody, errs := agent.Bytes()
|
|
|
|
|
if len(errs) > 0 {
|
|
|
|
|
for _, err = range errs {
|
|
|
|
|
a.logger.Error("error sending request in Linked Contact To Contact", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
return nil, fmt.Errorf("request failed: %v", errs[0])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from Linked Contact To Contact: %s", string(resBody))
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var resp models.LinkedContactResponse
|
|
|
|
|
err = json.Unmarshal(resBody, &resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal response body in Linked Contact To Contact:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(a.rateLimiter.Interval)
|
|
|
|
|
}
|
|
|
|
|
}
|