diff --git a/go.sum b/go.sum index a909670..607786b 100644 --- a/go.sum +++ b/go.sum @@ -169,10 +169,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6 h1:oV+/HNX+JPoQ3/GUx08hio7d45WpY0AMGrFs7j70QlA= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240507152904-b2e6000c1f40 h1:2/7GQGyMcwISIXVj0bapGEy2FDHrI9FskMSqc6peGjM= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240507152904-b2e6000c1f40/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240507173031-17e2f6acba38 h1:50i28g5lzVthJHS5r+3sPrmRBlfNag8lngN+CkdrbN0= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240507173031-17e2f6acba38/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64= penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240507175756-10399fe4c21f h1:xUo4CsauxNgFhiTfv+5BKfF4Ekk6SHeR+ohwrBuJIrU= penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240507175756-10399fe4c21f/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64= penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af h1:jQ7HaXSutDX5iepU7VRImxhikK7lV/lBKkiloOZ4Emo= diff --git a/internal/controllers/rules.go b/internal/controllers/rules.go index b95f271..f19e5eb 100644 --- a/internal/controllers/rules.go +++ b/internal/controllers/rules.go @@ -25,7 +25,7 @@ func (c *Controller) ChangeQuizSettings(ctx *fiber.Ctx) error { return ctx.Status(fiber.StatusBadRequest).SendString("failed convert quizID to int") } - //accountID := "64f2cd7a7047f28fdabf6d9e" + //accountID := "654a8909725f47e926f0bebc" var request model.RulesReq if err := ctx.BodyParser(&request); err != nil { diff --git a/internal/models/createDeal.go b/internal/models/createDeal.go index 57bff5a..bd5e94a 100644 --- a/internal/models/createDeal.go +++ b/internal/models/createDeal.go @@ -35,8 +35,6 @@ type Embedd struct { } type Contact struct { - //ID int32 `json:"id"` // ID контакта - //IsMain bool `json:"is_main"` // Флаг, показывающий, является контакт главным или нет Name string `json:"first_name"` ResponsibleUserID int32 `json:"responsible_user_id"` // ID пользователя, ответственного за сделку, в нашем случае PerformerID CreatedBy int32 `json:"created_by"` // id пользователя amoid который создает сделку (тот кто подключил интеграцию) @@ -47,7 +45,6 @@ type Contact struct { } type Company struct { - //ID int32 `json:"id"` // ID компании Name string `json:"name"` // Название компании ResponsibleUserID int32 `json:"responsible_user_id"` // ID пользователя, ответственного за сделку, в нашем случае PerformerID CreatedBy int32 `json:"created_by"` // id пользователя amoid который создает сделку (тот кто подключил интеграцию) @@ -85,3 +82,31 @@ type EmbeddedUpdateDeal struct { UpdatedAt int64 `json:"updated_at"` } } + +type Customer struct { + Name string `json:"name"` + NextPrice int `json:"next_price"` + NextDate int64 `json:"next_date"` + ResponsibleUserID int32 `json:"responsible_user_id"` + StatusID *int32 `json:"status_id,omitempty"` + Periodicity int `json:"periodicity"` + CreatedBy int `json:"created_by"` + UpdatedBy int `json:"updated_by"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` + CustomFields []FieldsValues `json:"custom_fields_values"` + TagsToAdd []Tag `json:"tags_to_add"` + Embed Embedd `json:"_embedded"` + RequestID string `json:"request_id"` +} + +type CustomerResp struct { + Embedded EmbeddedCreateCustomers `json:"_embedded"` +} + +type EmbeddedCreateCustomers struct { + Customers []struct { + ID int32 `json:"id"` + RequestID string `json:"request_id"` + } +} diff --git a/internal/tools/construct.go b/internal/tools/construct.go index cde9496..6901656 100644 --- a/internal/tools/construct.go +++ b/internal/tools/construct.go @@ -69,8 +69,9 @@ func ToField(amoField []models.CustomField, entity model.EntityType) []model.Fie return fields } -// todo Для добавляемых сущностей (сделка, контакт, компания), можно передать не более 40 значений дополнительных полей. -func ConstructField(allAnswers []model.ResultAnswer, result model.AmoUsersTrueResults) ([]models.FieldsValues, []models.Contact, []models.Company, error) { +func ConstructField(allAnswers []model.ResultAnswer, result model.AmoUsersTrueResults) ([]models.FieldsValues, []models.Contact, []models.Company, []models.Customer, error) { + dateCreating := time.Now().Unix() + entityFieldsMap := make(map[model.EntityType]map[int][]models.Values) entityFieldsMap[model.LeadsType] = make(map[int][]models.Values) entityFieldsMap[model.CompaniesType] = make(map[int][]models.Values) @@ -118,7 +119,12 @@ func ConstructField(allAnswers []model.ResultAnswer, result model.AmoUsersTrueRe var resultInfo model.ResultContent err := json.Unmarshal([]byte(result.Content), &resultInfo) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, nil, err + } + + name := resultInfo.Name + if name == "" { + name = fmt.Sprintf("empty name, quiz %d, triggered by answer - %d", result.QuizID, result.AnswerID) } contactRuleMap := result.FieldsRule.Contact.ContactRuleMap @@ -131,22 +137,34 @@ func ConstructField(allAnswers []model.ResultAnswer, result model.AmoUsersTrueRe return leadFields, []models.Contact{ { - Name: resultInfo.Name, + Name: name, ResponsibleUserID: result.PerformerID, CreatedBy: 0, UpdatedBy: 0, - CreatedAt: time.Now().Unix(), + CreatedAt: dateCreating, CustomFieldsValues: contactFields, }, }, []models.Company{ { - Name: "OOO PENA CO", + Name: fmt.Sprintf("Компания %d", result.AnswerID), ResponsibleUserID: result.PerformerID, CreatedBy: 0, UpdatedBy: 0, - CreatedAt: time.Now().Unix(), + CreatedAt: dateCreating, CustomFieldsValues: companyFields, }, + }, []models.Customer{ + { + // в амо имя покупателя не может быть пустым, надо как то с этим жить + Name: name, + ResponsibleUserID: result.PerformerID, + //StatusID: , + CreatedBy: 0, + UpdatedBy: 0, + CreatedAt: dateCreating, + CustomFields: customerFields, + RequestID: fmt.Sprint(result.AnswerID), + }, }, nil } diff --git a/internal/workers/post_deals_worker/deals_worker.go b/internal/workers/post_deals_worker/deals_worker.go index 2a155cc..d8a1816 100644 --- a/internal/workers/post_deals_worker/deals_worker.go +++ b/internal/workers/post_deals_worker/deals_worker.go @@ -87,9 +87,15 @@ func (wc *PostDeals) startFetching(ctx context.Context) { RequestID: strconv.Itoa(int(result.AnswerID)), } - leadFields, contactData, companyData, err := tools.ConstructField(allAnswers, result) + leadFields, contactData, companyData, customerToCreate, err := tools.ConstructField(allAnswers, result) if err != nil { - wc.logger.Error("error serialization resultContent to model ResultContent") + wc.logger.Error("error serialization resultContent to model ResultContent", zap.Error(err)) + return + } + + _, err = wc.amoClient.CreatingCustomer(customerToCreate, result.AccessToken) + if err != nil { + wc.logger.Error("error sending requests for create customer", zap.Error(err)) return } @@ -106,7 +112,7 @@ func (wc *PostDeals) startFetching(ctx context.Context) { wc.logger.Info("reached maximum number of deals for access token", zap.String("access_token", result.AccessToken)) err = wc.sendingDealsReq(ctx, mapDealReq) if err != nil { - wc.logger.Error("error sending requests for create deals") + wc.logger.Error("error sending requests for create deals", zap.Error(err)) return } mapDealReq = make(map[string][]models.DealReq) @@ -117,7 +123,7 @@ func (wc *PostDeals) startFetching(ctx context.Context) { err = wc.sendingDealsReq(ctx, mapDealReq) if err != nil { - wc.logger.Error("error send requests for create deals") + wc.logger.Error("error send requests for create deals", zap.Error(err)) return } } diff --git a/pkg/amoClient/amo.go b/pkg/amoClient/amo.go index e49198a..97c1003 100644 --- a/pkg/amoClient/amo.go +++ b/pkg/amoClient/amo.go @@ -144,17 +144,6 @@ func (a *Amo) CreateWebHook(req models.WebHookRequest) (*models.CreateWebHookRes } } -// 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() { - for { - if a.rateLimiter.Check() { - return - } - time.Sleep(a.rateLimiter.Interval) - } - -} - // 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 func (a *Amo) GetListSteps(pipelineID int, accessToken string) (*models.ResponseGetListSteps, error) { @@ -508,5 +497,45 @@ func (a *Amo) UpdatingDeal(req []models.UpdateDealReq, accessToken string) (*mod } time.Sleep(a.rateLimiter.Interval) } - +} + +func (a *Amo) CreatingCustomer(req []models.Customer, accessToken string) (*models.CustomerResp, error) { + for { + if a.rateLimiter.Check() { + uri := fmt.Sprintf("%s/api/v4/customers", a.baseApiURL) + 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) + } }