andrei-mireichyk / amocrm-api-library
amoCRM API Client
Requires
- php: >=7.1
- ext-json: *
- amocrm/oauth2-amocrm: ^2.0
- fig/http-message-util: 1.*
- guzzlehttp/guzzle: 6.*
- illuminate/support: 5.* || 6.* || 7.*
- lcobucci/jwt: ^3.3
- ramsey/uuid: ^3 || ^4
- symfony/dotenv: 4.* || 5.*
Requires (Dev)
- phpunit/phpunit: 7.*.*
- squizlabs/php_codesniffer: 3.5.*
README
amoCRM API Library
В данном пакете представлен API клиент с поддержкой основных сущностей и авторизацией по протоколу OAuth 2.0 в amoCRM.
Оглавление
- Установка
- Начало работы
- Поддерживаемые методы и сервисы
- Обработка ошибок
- Фильтры
- Работа с Custom Fields сущностей
- Работа с тегами сущностей
- Константы
- Примеры
Установка
Установить библиотеку можно с помощью composer:
composer require amocrm/amocrm-api-library
Начало работы и авторизация
Для начала использования вам необходимо создать объект бибилиотеки:
$apiClient = new \AmoCRM\Client\AmoCRMApiClient($clientId, $clientSecret, $redirectUri);
Так же предоставляется фабрика для создания объектов \AmoCRM\AmoCRM\Client\AmoCRMApiClientFactory
.
Для ее использования вам нужно реализовать интерфейс \AmoCRM\OAuth\OAuthConfigInterface
и \AmoCRM\OAuth\OAuthServiceInterface
$apiClientFactory = new \AmoCRM\AmoCRM\Client\AmoCRMApiClientFactory($oAuthConfig, $oAuthService); $apiClient = $apiClientFactory->make();
Затем необходимо создать объект (\League\OAuth2\Client\Token\AccessToken
) Access токена из вашего хранилища токенов и установить его в API клиент.
Также необходимо установить домен аккаунта amoCRM в виде СУБДОМЕН.amocrm.(ru/com).
Вы можете установить функцию-callback на событие обновления Access токена, если хотите дополнительно обрабатывать новый токен (например сохранять его в хранилище токенов):
$apiClient->setAccessToken($accessToken) ->setAccountBaseDomain($accessToken->getValues()['baseDomain']) ->onAccessTokenRefresh( function (\League\OAuth2\Client\Token\AccessTokenInterface $accessToken, string $baseDomain) { saveToken( [ 'accessToken' => $accessToken->getToken(), 'refreshToken' => $accessToken->getRefreshToken(), 'expires' => $accessToken->getExpires(), 'baseDomain' => $baseDomain, ] ); });
Отправить пользователя на страницу авторизации можно 2мя способами:
- Отрисовав кнопку на сайт:
$apiClient->getOAuthClient()->getOAuthButton( [ 'title' => 'Установить интеграцию', 'compact' => true, 'class_name' => 'className', 'color' => 'default', 'error_callback' => 'handleOauthError', 'state' => $state, ] );
- Отправив пользователя на страницу авторизации
$authorizationUrl = $apiClient->getOAuthClient()->getAuthorizeUrl([ 'state' => $state, 'mode' => 'post_message', //post_message - редирект произойдет в открытом окне, popup - редирект произойдет в окне родителе ]); header('Location: ' . $authorizationUrl);
Для получения Access Token можно использовать следующий код в обработчике, который будет находится по адресу, указаному в redirect_uri
$accessToken = $apiClient->getOAuthClient()->getAccessTokenByCode($_GET['code']);
Пример авторизации можно посмотреть в файле examples/get_token.php
Подход к работе с библиотекой
В библиотеке используется сервисный подход. Для каждой сущности имеется сервис. Для каждого метода имеется свой объект коллекции и модели. Работа с данными происходит через коллекции и методы библиотеки.
Модели и коллекции имеют методы toArray()
и toApi()
, методы возвращают представление объекта в виде массива и в виде данных, отправляемых в API.
Также для работы с коллекциями имеют следующие методы:
add(BaseApiModel $model): self
- добавляет модель в конец коллекции.prepend(BaseApiModel $value): self
- добавляет модель в начало коллекции.all(): array
- возвращает массив моделей в коллекции.first(): ?BaseApiModel
- получение первой модели в коллекции.last(): ?BaseApiModel
- получение последней модели в коллекции.count(): int
- получение кол-ва элементов в коллекции.isEmpty(): bool
- проверяет, что коллекция не пустая.getBy($key, $value): ?BaseApiModel
- получение модели по значению ключа.replaceBy($key, $value, BaseApiModel $replacement): void
- замена модели по значению ключа.
При работе с библиотекой необходимо не забывать о лимитах API amoCRM. Для оптимальной работы с данными лучше всего создавать/изменять за раз не более 50 сущностей в методах, где есть пакетная обработка.
Нужно не забывать про обработку ошибок, а также не забывать о безопасности хранилища токенов. Утечка токена грозит потерей досутпа к аккаунту.
Поддерживаемые методы и сервисы
Библиотека поддерживает большое количество методов API. Методы сгруппированы и объекты-сервисы. Получить объект сервиса можно вызвав необходимый метод у библиотеки, например:
$leadsService = $apiClient->leads();
В данный момент доступны следующие сервисы:
Для большинства сервисов есть базовый набор методов:
-
getOne - Получить 1 сущность
- id (int|string) - id сущности
- with (array) - массив параметров with, которые поддерживает модель сервиса
- Результатом выполнения будет модель сущности
getOne($id, array $with => []);
-
get Получить несколько сущностей:
- filter (BaseEntityFilter) - фильтр для сущности
- with (array) - массив параметров with, которые поддерживает модель сервиса
- Результатом выполнения будет коллекция сущностей
get(BaseEntityFilter $filter = null, array $with = []);
-
addOne Создать одну сущность:
- model (BaseApiModel) - модель создаваемой сущности
- Результатом выполнения будет модель сущности
addOne(BaseApiModel $model);
-
add Создать сущности пакетно:
- collection (BaseApiCollection) - коллекция моделей создаваемой сущности
- Результатом выполнения будет коллекция моделей сущности
add(BaseApiCollection $collection);
-
updateOne Обновить одну сущность:
- model (BaseApiModel) - модель создаваемой сущности
- Результатом выполнения будет модель сущности
updateOne(BaseApiModel $model);
-
update Обновить сущности пакетно:
- collection (BaseApiCollection) - коллекция моделей создаваемой сущности
- Результатом выполнения будет коллекция моделей сущности
update(BaseApiCollection $collection);
-
syncOne Синхронизировать одну модель с сервером:
- model (BaseApiModel) - коллекция моделей создаваемой сущности
- with (array) - массив параметров with, которые поддерживает модель сервиса
- Результатом выполнения будет коллекция моделей сущности
syncOne(BaseApiModel $model, $with = []);
Не все методы доступны во всех сервисах. В случае их вызова будет выброшены Exception.
Некоторые сервисы имеют специфичные методы, ниже рассмотрим сервисы, которые имеют специфичные методы.
Методы доступные в сервисе getOAuthClient
:
-
getAuthorizeUrl получение ссылки на авторизация
- options (array)
- state (string) состояние приложения
- Результатом выполнения будет строка с ссылкой на авторизация приложения
getAuthorizeUrl(array $options = []);
- options (array)
-
getAccessTokenByCode получение аксес токена по коду авторизации
- code (string) код авторизации
- Результатом выполнения будет объект (AccessTokenInterface)
getAccessTokenByCode(string $code);
-
getAccessTokenByRefreshToken получение аксес токена по рефреш токену
- accessToken (AccessTokenInterface) объект аксес токена
- Результатом выполнения будет объект (AccessTokenInterface)
getAccessTokenByRefreshToken(AccessTokenInterface $accessToken);
-
setBaseDomain установка базового домена, куда будут отправляться запросы необходимые для работы с токенами
- domain (string)
setBaseDomain(string $domain);
-
setAccessTokenRefreshCallback установка callback, который будет вызван при обновлении аксес токена
- function (callable)
setAccessTokenRefreshCallback(callable $function);
-
getOAuthButton установка callback, который будет вызван при обновлении аксес токена
- options (array)
- state (string) состояние приложения
- color (string)
- title (string)
- compact (bool)
- class_name (string)
- error_callback (string)
- mode (string)
- Результатом выполнения будет строка с HTML кодом кнопки авторизации
getOAuthButton(array $options = []);
- options (array)
-
exchangeApiKey метод для обмена API ключа на код авторизации
- login - email пользователя, для которого обменивается API ключ
- apiKey - API ключ пользователя
- Код авторизации будет прислан на указанный в настройках приложения redirect_uri
exchangeApiKey(string $login, string $apiKey);
Методы связей доступны в сервисах leads
, contacts
, companies
, customers
:
-
link Привязать сущность
- model (BaseApiModel) - модель главной сущности
- links (LinksCollection|LinkModel) - коллекция или модель связи
- Результатом выполнения является коллекция связей (LinksCollection)
link(BaseApiModel $model, $linkedEntities);
-
getLinks Получить связи сущности
- model (BaseApiModel) - модель главной сущности
- filter (LinksFilter) - фильтр для связей
- Результатом выполнения является коллекция связей (LinksCollection)
getLinks(BaseApiModel $model, LinksFilter $filter);
-
unlink Отвязать сущность
- model (BaseApiModel) - модель главной сущности
- links (LinksCollection|LinkModel) - коллекция или модель связи
- Результатом выполнения является bool значение
unlink(BaseApiModel $model, $linkedEntities);
Методы удаления доступны в сервисах transactions
, lossReasons
, statuses
, pipelines
, customFields
, customFieldsGroups
, roles
, customersStatuses
:
-
delete
- model (BaseApiModel) - модель сущности
- Результатом выполнения является bool значение
deleteOne(BaseApiModel $model);
-
deleteOne
- collection (BaseApiCollection) - коллекция моделей сущностей
- Результатом выполнения является bool значение
deleteOne(BaseApiModel $model);
Методы доступные в сервисе customers
:
- setMode Смена режима покупателей (периодические покупки или сегментация). Если покупатели выключены - то они будут включены.
- mode (string) - тип режима (periodicity или segments)
- isEnabled (bool) - включен ли функционал покупателей, по-умолчанию - true
- Результатом выполнения является строка названия включенного режима или null в случае отключения функционала
setMode(string $mode, bool $isEnabled = true);
Методы доступные в сервисе notes
:
- getByParentId Получение данных по ID родительской сущности
- parentId - ID родительской сущности
- filter (BaseEntityFilter) - фильтр
- with (array) - массив параметров with, которые поддерживает модель сервиса
getByParentId(int $parentId, BaseEntityFilter $filter = null, array $with = []);
Методы доступные в сервисе account
- getCurrent
- with (array) - массив параметров with, которые поддерживает модель сервиса
- Результатом выполнения является модель AccountModel
getCurrent(array $with = []);
Методы доступные в сервисе unsorted
-
addOne Создать одну сущность:
- model (BaseApiModel) - модель создаваемой сущности
- Результатом выполнения будет модель сущности
addOne(BaseApiModel $model);
-
add Создать сущности пакетно:
- collection (BaseApiCollection) - коллекция моделей создаваемой сущности
- Результатом выполнения будет коллекция моделей сущности
add(BaseApiCollection $collection);
-
link
- model (BaseApiModel) - модель неразобранного
- body (array) - массив дополнительной информации для привязки
- Результатом выполнения будет модель LinkUnsortedModel
link(BaseApiModel $unsortedModel, $body = []);
-
accept
- model (BaseApiModel) - модель неразобранного
- body (array) - массив дополнительной информации для принятия
- Результатом выполнения будет модель AcceptUnsortedModel
accept(BaseApiModel $unsortedModel, $body = []);
-
decline
- model (BaseApiModel) - модель неразобранного
- body (array) - массив дополнительной информации для отклонения
- Результатом выполнения будет модель DeclineUnsortedModel
decline(BaseApiModel $unsortedModel, $body = []);
-
summary
- filter (BaseEntityFilter) - фильтр для сущности
- Результатом выполнения будет модель UnsortedSummaryModel
summary(BaseEntityFilter $filter);
Методы доступные в сервисе webhooks
-
subscribe
- model (WebhookModel) - модель вебхука
- Результатом выполнения является модель WebhookModel
subscribe(WebhookModel $webhookModel);
-
unsubscribe
- model (WebhookModel) - модель вебхука
- Результатом выполнения является bool значение
unsubscribe(WebhookModel $webhookModel);
Методы доступные в сервисе widgets
-
install
- model (WidgetModel) - модель виджета
- Результатом выполнения является модель WidgetModel
install(WidgetModel $widgetModel);
-
uninstall
- model (WidgetModel) - модель виджета
- Результатом выполнения является модель WidgetModel
uninstall(WidgetModel $widgetModel);
Методы доступные в сервисе products
-
settings
- Результатом выполнения является модель ProductsSettingsModel
settings();
-
updateSettings
- model (ProductsSettingsModel) - модель виджета
- Результатом выполнения является модель ProductsSettingsModel
updateSettings(ProductsSettingsModel $productsSettings);
Обработка ошибок
Вызов методов библиотеки может выбрасывать ошибки типа AmoCRMApiException
.
В данные момент доступны следующие типы ошибок, они все наследуют AmoCRMApiException:
У выброшенных Exception есть следующие методы:
getErrorCode()
getTitle()
getLastRequestInfo()
getDescription()
У ошибки типа AmoCRMApiErrorResponseException есть метод getValidationErrors()
, который вернет ошибки валидации входящих данных.
Фильтры
В данный момент библиотека поддерживает фильтры для следующих сервисов:
Работа с дополнительными полями сущностей
Дополнительные поля доступны у сущностей следующих сервисов:
leads
contacts
companies
customers
catalogElements
segments
У моделей, который возвращаются у этих сервисов, поля можно получить через метод getCustomFieldsValues()
.
На вызов данного метода возвращается объект CustomFieldsValuesCollection
или null
,
если значений полей нет.
Внутри коллекции CustomFieldsValuesCollection
находятся модели значений полей,
все модели наследуются от BaseCustomFieldValuesModel
, но зависят от типа поля.
У моделей, наследующих BaseCustomFieldValuesModel
доступны следующие методы:
getFieldId
,setFieldId
- получение/установка id поляgetFieldType
- получение типа поляgetFieldCode
,setFieldCode
- получение/установка кода поляgetFieldName
,setFieldName
- получение/установка названия поляgetValues
,setValues
- получение/установка коллекции значений
Так как некоторые поля могут иметь несколько значений,
в свойстве values хранится именно коллекция значений типа BaseCustomFieldValueCollection
.
Моделями коллекции являются модели типа BaseCustomFieldValueModel
.
Схема отношений объектов:
CustomFieldsValuesCollection 1 <---> n BaseCustomFieldValuesModel
BaseCustomFieldValuesModel::getValues() 1 <---> 1 BaseCustomFieldValueCollection
BaseCustomFieldValueCollection 1 <---> n BaseCustomFieldValueModel
Для разных типов полей мы уже подготовили разные модели и коллекции:
Namespace, в котором находятся модели значения - \AmoCRM\Models\CustomFieldsValues\ValueModels
Namespace, в котором находятся коллекции моделей значения - \AmoCRM\Models\CustomFieldsValues\ValueCollections
Namespace, в котором находятся модели дополнительных полей - \AmoCRM\Models\CustomFieldsValues
Пример кода, как создать коллекцию значения полей сущности:
//Создадим модель сущности $lead = new LeadModel(); $lead->setId(1); //Создадим коллекцию полей сущности $leadCustomFieldsValues = new CustomFieldsValuesCollection(); //Создадим модель значений поля типа текст $textCustomFieldValuesModel = new TextCustomFieldValuesModel(); //Укажем ID поля $textCustomFieldValuesModel->setFieldId(123); //Добавим значения $textCustomFieldValuesModel->setValues( (new TextCustomFieldValueCollection()) ->add((new TextCustomFieldValueModel())->setValue('Текст')) ); //Добавим значение в коллекцию полей сущности $leadCustomFieldsValues->add($textCustomFieldValuesModel); //Установим сущности эти поля $lead->setCustomFieldsValues($leadCustomFieldsValues);
Чтобы удалить значения поля доступен специальный объект \AmoCRM\Models\CustomFieldsValues\ValueCollections\NullCustomFieldValueCollection
.
Передав этот объект, вы зануляете значение поля.
Пример:
//Создадим модель сущности $lead = new LeadModel(); $lead->setId(1); //Создадим коллекцию полей сущности $leadCustomFieldsValues = new CustomFieldsValuesCollection(); //Создадим модель значений поля типа текст $textCustomFieldValuesModel = new TextCustomFieldValuesModel(); //Укажем ID поля $textCustomFieldValuesModel->setFieldId(123); //Обнулим значения $textCustomFieldValuesModel->setValues( (new NullCustomFieldValueCollection()) ); //Добавим значение в коллекцию полей сущности $leadCustomFieldsValues->add($textCustomFieldValuesModel); //Установим сущности эти поля $lead->setCustomFieldsValues($leadCustomFieldsValues);
Работа с тегами сущностей
Теги доступны как отдельный сервис tags
.
При создании данного сервиса, вы указываете тип сущности, с тегами которой вы будете работать.
В данный момент доступны:
- EntityTypesInterface::LEADS,
- EntityTypesInterface::CONTACTS,
- EntityTypesInterface::COMPANIES,
- EntityTypesInterface::CUSTOMERS,
Для работы с тегами конкретной сущности, нужно взаимодействовать с конкретной моделью сущности.
С помощью методов getTags
и setTags
вы можете получить коллекцию тегов сущности или установить её.
Для изменения тегов вам необходимо передавать всю коллекцию тегов, иначе теги могут быть потеряны.
Пример добавления/изменения тегов у сущности:
//Создадим модель сущности $lead = new LeadModel(); $lead->setId(1); //Создадим коллекцию тегов с тегами и установим их в сущности $lead->setTags((new TagsCollection()) ->add( (new TagModel()) ->setName('тег') )->add( (new TagModel()) ->setId(123123) ) );
или
//Создадим модель сущности $lead = new LeadModel(); $lead->setId(1); //Создадим коллекцию тегов с тегами и установим их в сущности $lead->setTags( TagsCollection::fromArray([ [ 'name' => 'тег', ], [ 'id' => 123, ], ]) );
Для удаления тегов в setTags можно передать в setTags
специальный объект \AmoCRM\Collections\NullTagsCollection
.
Пример удаления тегов у сущности:
//Создадим модель сущности $lead = new LeadModel(); $lead->setId(1); //Удалим теги $lead->setTags((new NullTagsCollection()));
Константы
Основные константы находятся в интерфейсе \AmoCRM\Helpers\EntityTypesInterface
.
Также доступны константы в следующих классах/интерфейсах:
\AmoCRM\OAuth\AmoCRMOAuth::BUTTON_COLORS
- доступные цвета для кнопки на сайт\AmoCRM\Models\Unsorted\BaseUnsortedModel
- константы для кодов категорий неразобранного\AmoCRM\Models\CustomFields\BirthdayCustomFieldModel
- константы для свойства remind у поля День Рождения\AmoCRM\Models\Interfaces\CallInterface
- константы статусов звонков\AmoCRM\EntitiesServices\Interfaces\HasParentEntity
- константы для ключей в запросах методов, у которых есть родительский сущность (в данный момент только notes)\AmoCRM\Models\CustomFieldsValues\ValueModels\ItemsCustomFieldValueModel
- константы для ключей значения поля Items\AmoCRM\Models\Rights\RightModel
- константы, связанные с правами\AmoCRM\Models\AccountModel
- константы для аргумента with для сервисаaccount
\AmoCRM\Models\TaskModel
- константы для дефолтных типов задач\AmoCRM\Models\NoteType\TargetingNote
- константы поддерживаемых внешних сервисов для примечаний о таргетинге (добавляют DP)\AmoCRM\Models\RoleModel
- константы для аргумента with для сервисаroles
\AmoCRM\Models\Factories\NoteFactory
- константы типов примечаний\AmoCRM\Models\NoteType\MessageCashierNote
- статусы примечания "Сообщение кассиру"\AmoCRM\Models\LeadModel
- константы для аргумента with для сервисаleads
\AmoCRM\Filters\Interfaces\HasOrderInterface
- константы для сортировки\AmoCRM\Models\EventModel
- константы для аргумента with для сервисаevents
\AmoCRM\Models\CustomFields\CustomFieldModel
- константы типов полей\AmoCRM\Models\Customers\CustomerModel
- константы для аргумента with для сервисаcustomers
\AmoCRM\Models\ContactModel
- константы для аргумента with для сервисаcontacts
\AmoCRM\Models\CompanyModel
- константы для аргумента with для сервисаcompanies
Работа в случае смены субдомена аккаунта
/** * Получим модель с информацией о домене аккаунта по access_token * Подробнее: @see AccountDomainModel * * Запрос уходит на www.amocrm.ru/oauth2/account/subdomain * С Authorization: Bearer {access_token} * curl 'https://www.amocrm.ru/oauth2/account/subdomain' -H 'Authorization: Bearer {access_token}' * * @example examples/get_account_subdomain.php */ $accountDomain = $apiClient->getOAuthClient() ->getAccountDomain($accessToken); // Возьмём из полученной модели текущий subdomain аккаунта и засетим наш апи клиент $apiClient->setAccountBaseDomain($accountDomain->getSubdomain()); // ... дальше продолжаем работу с апи клиентом
Одноразовые токены интеграций, расшифровка
// Как пример, получим заголовки с реквеста // И получим нужный нам X-Auth-Token $token = $_SERVER['HTTP_X_AUTH_TOKEN']; /** * Одноразовый токен для интеграций, для того чтобы его получить используйте * метод this.$authorizedAjax() в своей интеграции * Подробнее: @link https://www.amocrm.ru/developers/content/web_sdk/mechanics * * Данный токен должен передаваться в заголовках вместе с запросом на ваш удаленный сервер * X-Auth-Token: {disposable_token} * Время жизни токена: 30 минут * * Расшифруем пришедший токен и получим модель с информацией * Подробнее: @see DisposableTokenModel * @example examples/parse_disposable_token.php */ $disposableTokenModel = $apiClient->getOAuthClient() ->parseDisposableToken($token);
Примеры
В рамках данного репозитория имеется папка examples с различными примерами.
Для их работы необходимо добавить в неё файл .env со следующим содержимым, указав ваши значения:
CLIENT_ID="UUID интеграци" CLIENT_SECRET="Секретный ключ интеграции" CLIENT_REDIRECT_URI="https://example.com/examples/get_token.php (Важно обратить внимание, что он должен содержать в себе точно тот адрес, который был указан при создании интеграции)"
Затем вы можете поднять локальный сервер командой composer serve
. После конфигурацию необходимо перейти в браузере на страницу
http://localhost:8181/examples/get_token.php
для получения Access Token.
Для получения доступа к вашему локальному серверу из вне можно использовать сервис ngrok.io.
После авторизации вы можете проверить работу примеров, обращаясь к ним из браузера. Стоит отметить, что для корректной работы примеров необходимо проверить ID сущностей в них.
License
MIT