package bitrixClient import ( "encoding/json" "fmt" "github.com/gofiber/fiber/v2" "go.uber.org/zap" "penahub.gitlab.yandexcloud.net/backend/quiz/bitrix/internal/models" "penahub.gitlab.yandexcloud.net/backend/quiz/bitrix/internal/workers/limiter" "sync" "time" ) type Bitrix struct { fiberClient *fiber.Client logger *zap.Logger redirectionURL string integrationID string integrationSecret string rateLimiter *limiter.RateLimiter fileMutex sync.Mutex } type BitrixDeps struct { FiberClient *fiber.Client Logger *zap.Logger RedirectionURL string IntegrationID string IntegrationSecret string RateLimiter *limiter.RateLimiter } func NewBitrixClient(deps BitrixDeps) *Bitrix { if deps.FiberClient == nil { deps.FiberClient = fiber.AcquireClient() } return &Bitrix{ fiberClient: deps.FiberClient, logger: deps.Logger, redirectionURL: deps.RedirectionURL, integrationSecret: deps.IntegrationSecret, integrationID: deps.IntegrationID, rateLimiter: deps.RateLimiter, } } // https://dev.1c-bitrix.ru/rest_help/users/user_search.php func (b *Bitrix) GetUserList(accesToken string, domain string) (*models.ResponseGetListUsers, error) { for { if b.rateLimiter.Check() { uri := fmt.Sprintf("https://%s/rest/user.search", domain) agent := b.fiberClient.Post(uri) agent.Set("Authorization", "Bearer "+accesToken) statusCode, resBody, errs := agent.Bytes() if len(errs) > 0 { for _, err := range errs { b.logger.Error("error sending request in GetUserList", zap.Error(err)) } return nil, fmt.Errorf("request GetUserList failed: %v", errs[0]) } if statusCode != fiber.StatusOK { errorMessage := fmt.Sprintf("error GetUserList statusCode - %d, respBody - %s", statusCode, string(resBody)) b.logger.Error(errorMessage, zap.Int("status", statusCode)) return nil, fmt.Errorf(errorMessage) } var userListResponse models.ResponseGetListUsers err := json.Unmarshal(resBody, &userListResponse) if err != nil { b.logger.Error("error unmarshal ResponseGetListUsers:", zap.Error(err)) return nil, err } return &userListResponse, nil } time.Sleep(b.rateLimiter.Interval) } } // https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=99&LESSON_ID=2486 func (b *Bitrix) CreateWebHook(req models.WebHookRequest, domain string) (*models.CreateWebHookResp, error) { for { if b.rateLimiter.Check() { req.SetClientID(b.integrationID) req.SetClientSecret(b.integrationSecret) bodyBytes, err := json.Marshal(req) if err != nil { b.logger.Error("error marshal req in CreateWebHook:", zap.Error(err)) return nil, err } agent := b.fiberClient.Get(fmt.Sprintf("https://%s/oauth/token/", domain)) agent.Set("Content-Type", "application/json").Body(bodyBytes) statusCode, resBody, errs := agent.Bytes() if len(errs) > 0 { for _, err = range errs { b.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: %s", string(resBody)) b.logger.Error(errorMessage, zap.Int("status", statusCode)) return nil, fmt.Errorf(errorMessage) } var tokens models.CreateWebHookResp err = json.Unmarshal(resBody, &tokens) if err != nil { b.logger.Error("error unmarshal CreateWebHookResp:", zap.Error(err)) return nil, err } return &tokens, nil } time.Sleep(b.rateLimiter.Interval) } } // todo воронки и шаги надо понятиь что и как вообще обращаться ничо не понятно // todo fieeeeelds func (b *Bitrix) GetListFields(fieldType models.FieldsType, accessToken string, domain string) (interface{}, error) { for { if b.rateLimiter.Check() { switch fieldType { case models.FieldTypeCompany: fullURL := fmt.Sprintf("https://%s/rest/crm.deal.userfield.list", domain) agent := b.fiberClient.Post(fullURL) 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 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: %s", string(resBody)) b.logger.Error(errorMessage, zap.Int("status", statusCode)) return nil, fmt.Errorf(errorMessage) } var listFields models.Company err := json.Unmarshal(resBody, &listFields) if err != nil { b.logger.Error("error unmarshal models.Company:", zap.Error(err)) return nil, err } return string(resBody), nil case models.FieldTypeLeads: fullURL := fmt.Sprintf("https://%s/rest/crm.lead.fields", domain) agent := b.fiberClient.Post(fullURL) 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 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: %s", string(resBody)) b.logger.Error(errorMessage, zap.Int("status", statusCode)) return nil, fmt.Errorf(errorMessage) } var listFields models.Lead err := json.Unmarshal(resBody, &listFields) if err != nil { b.logger.Error("error unmarshal models.Lead:", zap.Error(err)) return nil, err } return listFields, nil case models.FieldTypeContact: fullURL := fmt.Sprintf("https://%s/rest/crm.contact.fields", domain) agent := b.fiberClient.Post(fullURL) 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 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: %s", string(resBody)) b.logger.Error(errorMessage, zap.Int("status", statusCode)) return nil, fmt.Errorf(errorMessage) } var listFields models.Contact err := json.Unmarshal(resBody, &listFields) if err != nil { b.logger.Error("error unmarshal models.Contact:", zap.Error(err)) return nil, err } return listFields, nil } } time.Sleep(b.rateLimiter.Interval) } }