2024-04-04 18:02:10 +00:00
|
|
|
|
package amoClients
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"amocrm/models/amo"
|
2024-04-04 18:32:56 +00:00
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
2024-04-08 08:20:10 +00:00
|
|
|
|
"net/url"
|
|
|
|
|
|
2024-04-04 18:02:10 +00:00
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Amo struct {
|
|
|
|
|
urlUserList string
|
|
|
|
|
urlCreateWebHook string
|
|
|
|
|
urlDeleteWebHook string
|
2024-04-05 12:16:20 +00:00
|
|
|
|
baseApiURL string
|
2024-04-04 18:02:10 +00:00
|
|
|
|
fiberClient *fiber.Client
|
|
|
|
|
logger *zap.Logger
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type AmoDeps struct {
|
|
|
|
|
UrlUserList string
|
|
|
|
|
UrlCreateWebHook string
|
|
|
|
|
UrlDeleteWebHook string
|
2024-04-05 12:16:20 +00:00
|
|
|
|
BaseApiURL string
|
2024-04-04 18:02:10 +00:00
|
|
|
|
FiberClient *fiber.Client
|
|
|
|
|
Logger *zap.Logger
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewAmoClient(deps AmoDeps) *Amo {
|
|
|
|
|
if deps.FiberClient == nil {
|
|
|
|
|
deps.FiberClient = fiber.AcquireClient()
|
|
|
|
|
}
|
|
|
|
|
return &Amo{
|
|
|
|
|
urlUserList: deps.UrlUserList,
|
|
|
|
|
urlCreateWebHook: deps.UrlCreateWebHook,
|
|
|
|
|
urlDeleteWebHook: deps.UrlDeleteWebHook,
|
2024-04-05 12:16:20 +00:00
|
|
|
|
baseApiURL: deps.BaseApiURL,
|
2024-04-04 18:02:10 +00:00
|
|
|
|
fiberClient: deps.FiberClient,
|
|
|
|
|
logger: deps.Logger,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-05 12:16:20 +00:00
|
|
|
|
// todo тут наверное ко всем этим методам токен авторизации нужно прикладывать прочитать подробнее про это
|
|
|
|
|
|
2024-04-04 18:02:10 +00:00
|
|
|
|
// https://www.amocrm.ru/developers/content/crm_platform/users-api#users-list
|
2024-04-04 18:32:56 +00:00
|
|
|
|
func (a *Amo) GetUserList(req amo.RequestGetListUsers) (*amo.ResponseGetListUsers, error) {
|
2024-04-05 12:16:20 +00:00
|
|
|
|
uri := fmt.Sprintf("%s?page=%d&limit=%d&with=%s", a.urlUserList, req.Page, req.Limit, req.With)
|
2024-04-04 18:02:10 +00:00
|
|
|
|
|
2024-04-05 12:16:20 +00:00
|
|
|
|
agent := a.fiberClient.Get(uri)
|
2024-04-04 18:32:56 +00:00
|
|
|
|
|
2024-04-05 08:52:10 +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])
|
2024-04-04 18:32:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
switch statusCode {
|
|
|
|
|
case fiber.StatusForbidden:
|
2024-04-05 08:52:10 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("error GetUserList StatusForbidden - %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
2024-04-04 18:32:56 +00:00
|
|
|
|
case fiber.StatusUnauthorized:
|
2024-04-05 08:52:10 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("error GetUserList StatusUnauthorized - %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
2024-04-04 18:32:56 +00:00
|
|
|
|
default:
|
2024-04-05 08:52:10 +00:00
|
|
|
|
errorMessage := fmt.Sprintf("error GetUserList statusCode - %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
2024-04-04 18:32:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var userListResponse amo.ResponseGetListUsers
|
2024-04-05 08:52:10 +00:00
|
|
|
|
err := json.Unmarshal(resBody, &userListResponse)
|
2024-04-04 18:32:56 +00:00
|
|
|
|
if err != nil {
|
2024-04-05 12:16:20 +00:00
|
|
|
|
a.logger.Error("error unmarshal ResponseGetListUsers:", zap.Error(err))
|
2024-04-04 18:32:56 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &userListResponse, nil
|
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
|
|
|
|
|
// тут и создание по коду и обновление по рефрешу в этом клиенте
|
|
|
|
|
func (a *Amo) CreateWebHook(req amo.WebHookRequest) (*amo.CreateWebHookResp, error) {
|
|
|
|
|
bodyBytes, err := json.Marshal(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error marshal req in CreateWebHook:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Post(a.urlCreateWebHook)
|
|
|
|
|
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 {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from CreateWebHook: %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var tokens amo.CreateWebHookResp
|
|
|
|
|
err = json.Unmarshal(resBody, &tokens)
|
|
|
|
|
if err != nil {
|
2024-04-05 12:16:20 +00:00
|
|
|
|
a.logger.Error("error unmarshal CreateWebHookResp:", zap.Error(err))
|
2024-04-05 08:52:10 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
|
2024-04-05 08:52:10 +00:00
|
|
|
|
return &tokens, nil
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://www.amocrm.ru/developers/content/oauth/step-by-step#%D0%A5%D1%83%D0%BA-%D0%BE%D0%B1-%D0%BE%D1%82%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B8-%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D0%B8
|
|
|
|
|
func (a *Amo) DeleteWebHook() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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-04-05 12:16:20 +00:00
|
|
|
|
func (a *Amo) GetListSteps(pipelineID int) (*amo.ResponseGetListSteps, error) {
|
|
|
|
|
uri := fmt.Sprintf("%s/api/v4/leads/pipelines/%d/statuses", a.baseApiURL, pipelineID)
|
|
|
|
|
|
|
|
|
|
agent := a.fiberClient.Get(uri)
|
|
|
|
|
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 {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from GetListSteps: %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var listSteps amo.ResponseGetListSteps
|
|
|
|
|
err := json.Unmarshal(resBody, &listSteps)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal ResponseGetListSteps:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
|
2024-04-05 12:16:20 +00:00
|
|
|
|
return &listSteps, nil
|
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
|
|
|
|
|
// GET /api/v4/customers/segments/custom_fields
|
|
|
|
|
// GET /api/v4/catalogs/{catalog_id}/custom_fields
|
|
|
|
|
// эти методы все относятся к одному и тому же, поэтому на вход будет урл и рек стуктура, выход у них один и тот же
|
|
|
|
|
func (a *Amo) GetListFields(req amo.GetListFieldsReq, url string) (*amo.ResponseGetListFields, error) {
|
|
|
|
|
fullURL := fmt.Sprintf("%s?limit=%d&page=%d", url, req.Limit, req.Page)
|
|
|
|
|
agent := a.fiberClient.Get(fullURL)
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from GetListFields: %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
|
2024-04-05 12:16:20 +00:00
|
|
|
|
var listFields amo.ResponseGetListFields
|
|
|
|
|
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-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
|
|
|
|
|
func (a *Amo) GetListTags(req amo.GetListTagsReq) (*amo.ResponseGetListTags, error) {
|
|
|
|
|
fullURL := fmt.Sprintf("%s/%s/tags?", a.baseApiURL, req.EntityType)
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
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])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
|
errorMessage := fmt.Sprintf("received an incorrect response from GetListTags: %d", statusCode)
|
|
|
|
|
a.logger.Error(errorMessage, zap.Int("status", statusCode))
|
|
|
|
|
return nil, fmt.Errorf(errorMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var listTags amo.ResponseGetListTags
|
|
|
|
|
err := json.Unmarshal(resBody, &listTags)
|
|
|
|
|
if err != nil {
|
|
|
|
|
a.logger.Error("error unmarshal ResponseGetListTags:", zap.Error(err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-04-04 18:02:10 +00:00
|
|
|
|
|
2024-04-05 12:16:20 +00:00
|
|
|
|
return &listTags, nil
|
2024-04-04 18:02:10 +00:00
|
|
|
|
}
|