diff --git a/go.mod b/go.mod index 4b515bd..16913de 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/lib/pq v1.10.9 github.com/twmb/franz-go v1.17.1 go.uber.org/zap v1.27.0 - penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241018135511-98fec66b1f21 + penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241021085437-741ed5875e98 penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240829220549-d35409b619a3 ) @@ -37,7 +37,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rs/xid v1.5.0 // indirect + github.com/rs/xid v1.6.0 // indirect github.com/tealeg/xlsx v1.0.5 // indirect github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf // indirect github.com/twmb/franz-go/pkg/kmsg v1.8.0 // indirect diff --git a/go.sum b/go.sum index c953c7f..d1bafdb 100644 --- a/go.sum +++ b/go.sum @@ -89,6 +89,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= @@ -141,7 +143,7 @@ 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-20240202120244-c4ef330cfe5d h1:gbaDt35HMDqOK84WYmDIlXMI7rstUcRqNttaT6Kx1do= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241018135511-98fec66b1f21 h1:eLmk/NfVrHNV+hajScK+8W9cTk1PuqbEtcGDsodNVtY= -penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241018135511-98fec66b1f21/go.mod h1:uOuosXduBzd2WbLH6TDZO7ME7ZextulA662oZ6OsoB0= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241021085437-741ed5875e98 h1:W4Wwu1Dq5+3ar/Ujhy8veyhCImmDV89RHkUkbSP6xns= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241021085437-741ed5875e98/go.mod h1:uOuosXduBzd2WbLH6TDZO7ME7ZextulA662oZ6OsoB0= penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240829220549-d35409b619a3 h1:sf6e2mp582L3i/FMDd2q6QuWm1njRXzYpIX0SipsvM4= penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240829220549-d35409b619a3/go.mod h1:i7M72RIpkSjcQtHID6KKj9RT/EYZ1rxS6tIPKWa/BSY= diff --git a/internal/models/getListFields.go b/internal/models/getListFields.go index 4dc677c..f22cd3f 100644 --- a/internal/models/getListFields.go +++ b/internal/models/getListFields.go @@ -1,9 +1,8 @@ package models import ( + "github.com/rs/xid" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" - "strconv" - "time" ) type FieldsResponse struct { @@ -40,8 +39,8 @@ type AddFields struct { } func (a *AddFields) GenFieldName() { - currentTime := time.Now().Unix() - currentTimeStr := strconv.FormatInt(currentTime, 10) - a.FieldName = currentTimeStr - a.XMLID = currentTimeStr + guid := xid.New() + guidGen := guid.String() + a.FieldName = guidGen + a.XMLID = guidGen } diff --git a/internal/workers/post_deals_worker/deals_worker.go b/internal/workers/post_deals_worker/deals_worker.go index 8d888d4..06ab91e 100644 --- a/internal/workers/post_deals_worker/deals_worker.go +++ b/internal/workers/post_deals_worker/deals_worker.go @@ -4,12 +4,14 @@ import ( "context" "database/sql" "encoding/json" + "errors" "fmt" "go.uber.org/zap" "penahub.gitlab.yandexcloud.net/backend/quiz/bitrix/internal/models" "penahub.gitlab.yandexcloud.net/backend/quiz/bitrix/pkg/bitrixClient" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/bitrix" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils" "strconv" @@ -231,28 +233,77 @@ func (wc *DealsWorker) constructField(ctx context.Context, dealReq models.Creati return nil, err } - // todo check duplicate contacts + //check duplicate contacts + var fields []string + var contactID int32 - contactReq := models.CreateContactReq{ - Fields: models.ContactFields{ - Name: resultInfo.Name, - TypeID: result.TypeID, - SourceID: result.SourceID, - Opened: "Y", - UtmSource: result.UTMs["utm_source"], - UtmCampaign: result.UTMs["utm_campaign"], - UtmContent: result.UTMs["utm_content"], - UtmMedium: result.UTMs["utm_medium"], - UtmTerm: result.UTMs["utm_term"], - }, + name := resultInfo.Name + if name == "" { + name = fmt.Sprintf("empty name, quiz %d, triggered by answer - %d", result.QuizID, result.AnswerID) } - contactReqMap := models.FormattingToMap(&contactReq, contactFields) - contactID, err := wc.bitrixClient.CreateContact(contactReqMap, result.AccessToken, result.SubDomain) - if err != nil { - wc.logger.Error("error creating contact", zap.Error(err)) + if len(resultInfo.Phone) > 4 || resultInfo.Phone != "" { + fields = append(fields, resultInfo.Phone) + } + + if resultInfo.Email != "" { + fields = append(fields, resultInfo.Email) + } + + existContactData, err := wc.bitrixRepo.BitrixRepo.GetExistingContactBitrix(ctx, result.AmoAccountID, fields) + if err != nil && !errors.Is(err, pj_errors.ErrNotFound) { return nil, err } + if errors.Is(err, pj_errors.ErrNotFound) || len(existContactData) == 0 { + fmt.Println("NO CONTACT", contactFields) + contactReq := models.CreateContactReq{ + Fields: models.ContactFields{ + Name: name, + TypeID: result.TypeID, + SourceID: result.SourceID, + Opened: "Y", + UtmSource: result.UTMs["utm_source"], + UtmCampaign: result.UTMs["utm_campaign"], + UtmContent: result.UTMs["utm_content"], + UtmMedium: result.UTMs["utm_medium"], + UtmTerm: result.UTMs["utm_term"], + }, + } + + contactReqMap := models.FormattingToMap(&contactReq, contactFields) + contactID, err = wc.bitrixClient.CreateContact(contactReqMap, result.AccessToken, result.SubDomain) + if err != nil { + wc.logger.Error("error creating contact", zap.Error(err)) + return nil, err + } + + if len(resultInfo.Phone) > 4 || resultInfo.Phone != "" { + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contactID, + Field: resultInfo.Phone, + }) + if err != nil { + return nil, err + } + } + + if resultInfo.Email != "" { + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contactID, + Field: resultInfo.Email, + }) + if err != nil { + return nil, err + } + } + } else if existContactData != nil && len(existContactData) > 0 { + contactID, err = wc.chooseAndCreateContact(ctx, result, resultInfo, existContactData, contactFields, contactRuleMap) + if err != nil { + return nil, err + } + } companyReq := models.CompanyReq{ Fields: models.CompanyFields{ @@ -293,6 +344,375 @@ func (wc *DealsWorker) addContactFields(ctx context.Context, contactFields map[s return contactFields, nil } +func (wc *DealsWorker) chooseAndCreateContact(ctx context.Context, result model.BitrixUsersTrueResults, resultInfo model.ResultContent, existingContacts map[int32][]model.ContactBitrix, contactFields map[string]string, contactRuleMap map[string]string) (int32, error) { + var err error + // 1 ищем контакт в котором совпадает и телефон и емайл + if (len(resultInfo.Phone) > 4 || resultInfo.Phone != "") && resultInfo.Email != "" { + phoneMatchedContacts := make(map[int32]bool) + for _, contactVariants := range existingContacts { + for _, contact := range contactVariants { + if contact.Field == resultInfo.Phone { + phoneMatchedContacts[contact.BitrixID] = true + } + } + } + for _, contactVariants := range existingContacts { + for _, contact := range contactVariants { + if contact.Field == resultInfo.Email { + if _, ok := phoneMatchedContacts[contact.BitrixID]; ok { + wc.logger.Info("нашлось телефон и емайл в бд, с одинаковым битрикс ид", zap.Any("битрикс ид", contact.BitrixID), zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + return contact.BitrixID, nil + } + } + } + } + + var phoneContactID, emailContactID int32 + var phoneID int64 /*emailID*/ + for _, contactVariants := range existingContacts { + for _, contact := range contactVariants { + if contact.Field == resultInfo.Phone { + phoneContactID = contact.BitrixID + phoneID = contact.ID + } + if contact.Field == resultInfo.Email { + emailContactID = contact.BitrixID + //emailID = contact.ID + } + } + } + + if phoneContactID != 0 && emailContactID != 0 && phoneContactID != emailContactID { + wc.logger.Info("нашлось телефон и емайл в бд, но это пока разные контакты", zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + // делаем обновление телефона там где уже есть email + valuePhone := make(map[string]string) + valuePhone, err = wc.addContactFields(ctx, valuePhone, resultInfo.Phone, model.TypeContactPhone, contactRuleMap) + if err != nil { + wc.logger.Error("error adding contact fields", zap.Error(err)) + return 0, err + } + name := resultInfo.Name + if name == "" { + name = fmt.Sprintf("empty name, quiz %d, triggered by answer - %d", result.QuizID, result.AnswerID) + } + + contactUpdateReq := models.CreateContactReq{ + Fields: models.ContactFields{ + Name: name, + }, + } + contactUpdateReqMap := models.FormattingToMap(&contactUpdateReq, valuePhone) + + err = wc.bitrixClient.UpdateContact(contactUpdateReqMap, result.AccessToken, result.SubDomain, emailContactID) + if err != nil { + wc.logger.Error("error updating contact", zap.Error(err)) + return 0, err + } + + err = wc.bitrixRepo.BitrixRepo.UpdateBitrixContact(ctx, phoneID, resultInfo.Phone, emailContactID) + if err != nil { + return 0, err + } + + // todo пока без линковки + //_, err = wc.amoClient.LinkedContactToContact([]models.LinkedContactReq{ + // { + // ToEntityID: emailContactID, + // ToEntityType: "contacts", + // //Metadata: struct { + // // //CatalogID int `json:"catalog_id"` + // // //Quantity int `json:"quantity"` + // // IsMain bool `json:"is_main"` + // // //UpdatedBy int `json:"updated_by"` + // // //PriceID int `json:"price_id"` + // //}(struct { + // // //CatalogID int + // // //Quantity int + // // IsMain bool + // // //UpdatedBy int + // // //PriceID int + // //}{IsMain: true}), + // }, + //}, result.SubDomain, result.AccessToken, phoneContactID) + //if err != nil { + // return 0, err + //} + + return emailContactID, nil + } + } + + // 2 ищем контакт только по телефону + if len(resultInfo.Phone) > 4 || resultInfo.Phone != "" { + for _, contactVariants := range existingContacts { + for _, contact := range contactVariants { + if contact.Field == resultInfo.Phone { + // нашли контакт по телефону + emailExists := false + for _, variant := range existingContacts[contact.BitrixID] { + if variant.Field != contact.Field { + if variant.Field != "" { + emailExists = true + break + } + } + } + if !emailExists && resultInfo.Email != "" { + // email пустой обновляем контакт добавляя email, если не пустой + wc.logger.Info("нашлось телефон, емайл не пустой, а в бд пустой. обновляем контакт", zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + valueEmail := make(map[string]string) + valueEmail, err = wc.addContactFields(ctx, valueEmail, resultInfo.Email, model.TypeContactEmail, contactRuleMap) + if err != nil { + wc.logger.Error("error adding contact fields", zap.Error(err)) + return 0, err + } + name := resultInfo.Name + if name == "" { + name = fmt.Sprintf("empty name, quiz %d, triggered by answer - %d", result.QuizID, result.AnswerID) + } + + contactUpdateReq := models.CreateContactReq{ + Fields: models.ContactFields{ + Name: name, + }, + } + contactUpdateReqMap := models.FormattingToMap(&contactUpdateReq, valueEmail) + + err = wc.bitrixClient.UpdateContact(contactUpdateReqMap, result.AccessToken, result.SubDomain, contact.BitrixID) + if err != nil { + wc.logger.Error("error updating contact", zap.Error(err)) + return 0, err + } + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contact.BitrixID, + Field: resultInfo.Email, + }) + if err != nil { + return 0, err + } + return contact.BitrixID, nil + } + if emailExists && resultInfo.Email != "" { + // email не пустой значит это новый контакт создаем если наш email тоже не пустой + wc.logger.Info("нашлось телефон, емайл не пустой и в бд не пустой. создаем новый контакт", zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + name := resultInfo.Name + if name == "" { + name = fmt.Sprintf("empty name, quiz %d, triggered by answer - %d", result.QuizID, result.AnswerID) + } + + contactCreateReq := models.CreateContactReq{ + Fields: models.ContactFields{ + Name: name, + TypeID: result.TypeID, + SourceID: result.SourceID, + Opened: "Y", + UtmSource: result.UTMs["utm_source"], + UtmCampaign: result.UTMs["utm_campaign"], + UtmContent: result.UTMs["utm_content"], + UtmMedium: result.UTMs["utm_medium"], + UtmTerm: result.UTMs["utm_term"], + }, + } + + contactCreateReqMap := models.FormattingToMap(&contactCreateReq, contactFields) + + contactID, err := wc.bitrixClient.CreateContact(contactCreateReqMap, result.AccessToken, result.SubDomain) + if err != nil { + wc.logger.Error("error creating contact", zap.Error(err)) + return 0, err + } + + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contactID, + Field: resultInfo.Phone, + }) + if err != nil { + return 0, err + } + + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contactID, + Field: resultInfo.Email, + }) + if err != nil { + return 0, err + } + return contactID, nil + } + // если пустой то это нужный контакт возвращаем его id, так как если мейл пустой у нас но номер совпадает а в бд не пустой значит оно нам надо + wc.logger.Info("нашлось телефон, емайл пустой возвращаем существующий контакт", zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + return contact.BitrixID, nil + } + } + } + } + + // 3 ищем контакт только по email + if resultInfo.Email != "" { + for _, contactVariants := range existingContacts { + for _, contact := range contactVariants { + if contact.Field == resultInfo.Email { + // нашли контакт по email + phoneExists := false + for _, variant := range existingContacts[contact.BitrixID] { + if variant.Field != contact.Field { + if variant.Field != "" { + phoneExists = true + break + } + } + } + if !phoneExists && (len(resultInfo.Phone) > 4 || resultInfo.Phone != "") { + // телефон пустой обновляем контакт добавляя телефон, если не пустой + wc.logger.Info("нашлось емайл, телефон не пустой, а в бд пустой. обновляем контакт", zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + valuePhone := make(map[string]string) + valuePhone, err = wc.addContactFields(ctx, valuePhone, resultInfo.Phone, model.TypeContactPhone, contactRuleMap) + if err != nil { + wc.logger.Error("error adding contact fields", zap.Error(err)) + return 0, err + } + name := resultInfo.Name + if name == "" { + name = fmt.Sprintf("empty name, quiz %d, triggered by answer - %d", result.QuizID, result.AnswerID) + } + + contactUpdateReq := models.CreateContactReq{ + Fields: models.ContactFields{ + Name: name, + }, + } + contactUpdateReqMap := models.FormattingToMap(&contactUpdateReq, valuePhone) + + err := wc.bitrixClient.UpdateContact(contactUpdateReqMap, result.AccessToken, result.SubDomain, contact.BitrixID) + if err != nil { + wc.logger.Error("error updating contact", zap.Error(err)) + return 0, err + } + + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contact.BitrixID, + Field: resultInfo.Phone, + }) + if err != nil { + return 0, err + } + return contact.BitrixID, nil + } + if phoneExists && (len(resultInfo.Phone) > 4 || resultInfo.Phone != "") { + // телефон не пустой значит это новый контакт создаем если наш телефон не пустой + wc.logger.Info("нашлось емайл, телефон не пустой и в бд не пустой. создаем новый контакт", zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + name := resultInfo.Name + if name == "" { + name = fmt.Sprintf("empty name, quiz %d, triggered by answer - %d", result.QuizID, result.AnswerID) + } + + contactCreateReq := models.CreateContactReq{ + Fields: models.ContactFields{ + Name: name, + TypeID: result.TypeID, + SourceID: result.SourceID, + Opened: "Y", + UtmSource: result.UTMs["utm_source"], + UtmCampaign: result.UTMs["utm_campaign"], + UtmContent: result.UTMs["utm_content"], + UtmMedium: result.UTMs["utm_medium"], + UtmTerm: result.UTMs["utm_term"], + }, + } + + contactCreateMapReq := models.FormattingToMap(&contactCreateReq, contactFields) + + contactID, err := wc.bitrixClient.CreateContact(contactCreateMapReq, result.AccessToken, result.SubDomain) + if err != nil { + wc.logger.Error("error creating contact", zap.Error(err)) + return 0, err + } + + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contactID, + Field: resultInfo.Phone, + }) + if err != nil { + return 0, err + } + + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contactID, + Field: resultInfo.Email, + }) + if err != nil { + return 0, err + } + return contactID, nil + } + + // если пустой то это нужный контакт возвращаем его id, так как если телефон пустой у нас но мейл совпадает а в бд не пустой значит оно нам надо + wc.logger.Info("нашлось емайл, телефон пустой возвращаем существующий контакт", zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + return contact.BitrixID, nil + } + } + } + } + + wc.logger.Info("ничего не нашлось, создаем новый контакт", zap.String("Name", resultInfo.Name), zap.String("Phone", resultInfo.Phone), zap.String("Email", resultInfo.Email)) + // если дошлю до сюда то это новый контакт с новым email and phone + name := resultInfo.Name + if name == "" { + name = fmt.Sprintf("empty name, quiz %d, triggered by answer - %d", result.QuizID, result.AnswerID) + } + + contactCreateReq := models.CreateContactReq{ + Fields: models.ContactFields{ + Name: name, + TypeID: result.TypeID, + SourceID: result.SourceID, + Opened: "Y", + UtmSource: result.UTMs["utm_source"], + UtmCampaign: result.UTMs["utm_campaign"], + UtmContent: result.UTMs["utm_content"], + UtmMedium: result.UTMs["utm_medium"], + UtmTerm: result.UTMs["utm_term"], + }, + } + + contactCreateMapReq := models.FormattingToMap(&contactCreateReq, contactFields) + + contactID, err := wc.bitrixClient.CreateContact(contactCreateMapReq, result.AccessToken, result.SubDomain) + if err != nil { + wc.logger.Error("error creating contact", zap.Error(err)) + return 0, err + } + + if len(resultInfo.Phone) > 4 || resultInfo.Phone != "" { + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contactID, + Field: resultInfo.Phone, + }) + if err != nil { + return 0, err + } + } + + if resultInfo.Email != "" { + _, err = wc.bitrixRepo.BitrixRepo.InsertContactBitrix(ctx, model.ContactBitrix{ + AccountID: result.AmoAccountID, + BitrixID: contactID, + Field: resultInfo.Email, + }) + if err != nil { + return 0, err + } + } + return contactID, nil +} + func (wc *DealsWorker) Stop(_ context.Context) error { return nil } diff --git a/pkg/bitrixClient/bitrix.go b/pkg/bitrixClient/bitrix.go index c11882d..e6b6805 100644 --- a/pkg/bitrixClient/bitrix.go +++ b/pkg/bitrixClient/bitrix.go @@ -649,6 +649,41 @@ func (b *Bitrix) CreateContact(req map[string]map[string]interface{}, accessToke } } +func (b *Bitrix) UpdateContact(req map[string]map[string]interface{}, accessToken string, domain string, contactID int32) error { + for { + if b.rateLimiter.Check() { + uri := fmt.Sprintf("https://%s/rest/crm.contact.update?ID=%d", domain, contactID) + bodyBytes, err := json.Marshal(req) + if err != nil { + b.logger.Error("error marshal req in Updating Contact:", zap.Error(err)) + return err + } + agent := b.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 { + b.logger.Error("error sending request in Updating Contact", zap.Error(err)) + } + return fmt.Errorf("request failed: %v", errs[0]) + } + + b.logger.Info("received response from Updating Contact:", zap.String("resBody", string(resBody))) + + if statusCode != fiber.StatusOK { + errorMessage := fmt.Sprintf("received an incorrect response from Creating Contact: %s", string(resBody)) + b.logger.Error(errorMessage, zap.Int("status", statusCode)) + return fmt.Errorf(errorMessage) + } + + return nil + } + time.Sleep(b.rateLimiter.Interval) + } +} + func (b *Bitrix) CheckScope(token, domain string) (any, error) { for { if b.rateLimiter.Check() { diff --git a/pkg/bitrixClient/bitrix_test.go b/pkg/bitrixClient/bitrix_test.go index c35bd33..ff4db8e 100644 --- a/pkg/bitrixClient/bitrix_test.go +++ b/pkg/bitrixClient/bitrix_test.go @@ -226,3 +226,36 @@ func Test_Add_Fields(t *testing.T) { } fmt.Println(resp) } + +func Test_Update_Contact(t *testing.T) { + ctx := context.Background() + lim := limiter.NewRateLimiter(ctx, 50, 2*time.Second) + logger := zap.NewNop() + b := NewBitrixClient(BitrixDeps{ + Logger: logger, + RedirectionURL: "https://squiz.pena.digital/integrations", + IntegrationID: "app.670bd825e44c52.61826940", + IntegrationSecret: "Ki0MElZXS6dE6tRsGxixri2jmxbxF2Xa4qQpBPziGdAvvLAHJx", + RateLimiter: lim, + }) + + contactFields := make(map[string]string) + contactFields["UF_CRM_1729426581"] = "phoneTESTUPDATE" + contactFields["UF_CRM_1729425300"] = "emailTESTUPDATE" + contactFields["UF_CRM_1729425184"] = "nameTESTUPDATE" + + reqContact := models.CreateContactReq{ + Fields: models.ContactFields{ + Name: "TEST UPDATE CONTACT", + }, + } + + reqMapContact := models.FormattingToMap(&reqContact, contactFields) + + err := b.UpdateContact(reqMapContact, "6b2c16670000071b0072541200000001000007b21dd57044f7de29fde6a9566e6932f1", "b24-s5jg6c.bitrix24.ru", 53) + if err != nil { + fmt.Println(err) + return + } + fmt.Println("GOOD") +}