В данном пакете представлен API клиент с поддержкой основных сущностей и авторизацией по протоколу OAuth 2.0 в amoCRM. Для работы библиотеки требуется PHP версии не ниже 7.1.
- Установка
- Начало работы
- Подход к работе с библиотекой
- Поддерживаемые методы и сервисы
- Обработка ошибок
- Фильтры
- Работа с Custom Fields сущностей
- Работа с тегами сущностей
- Особенности работы с источниками
- Константы
- Работа в случае смены субдомена аккаунта
- Одноразовые токены интеграций, расшифровка
- Работа с валютами
- Примеры
Установить библиотеку можно с помощью composer:
composer require amocrm/amocrm-api-library
Для начала использования вам необходимо создать объект библиотеки:
$apiClient = new \AmoCRM\Client\AmoCRMApiClient($clientId, $clientSecret, $redirectUri);
Также предоставляется фабрика для создания объектов \AmoCRM\Client\AmoCRMApiClientFactory
.
Для ее использования вам нужно реализовать интерфейс \AmoCRM\OAuth\OAuthConfigInterface
и \AmoCRM\OAuth\OAuthServiceInterface
$apiClientFactory = new \AmoCRM\Client\AmoCRMApiClientFactory($oAuthConfig, $oAuthService);
$apiClient = $apiClientFactory->make();
При использовании фабрики вам не нужно устанавливать callback onAccessTokenRefresh, при обновлении токена будет вызван метод saveOAuthToken из $oAuthService (\AmoCRM\OAuth\OAuthServiceInterface).
Затем необходимо создать объект (\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
Начиная с версии 1.4.0 появилась возможность авторизоваться с правами конкретного пользователя, если токен был выпущен администратором аккаунта.
Для авторизации под пользователем аккаунта - необходимо задать ID пользователя у объекта типа \AmoCRM\Client\AmoCRMApiClient
. Метод вернет новый объект с установленным контекстом.
$apiClient = new \AmoCRM\Client\AmoCRMApiClient($clientId, $clientSecret, $redirectUri);
$apiClientWithContext = $apiClient->withContextUserId(123);
В библиотеке используется сервисный подход. Для каждой сущности имеется сервис. Для каждого метода имеется свой объект коллекции и модели. Работа с данными происходит через коллекции и методы библиотеки.
Модели и коллекции имеют методы 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
- замена модели по значению ключа.removeBy($key, $value): int
- удаление моделей по значению ключа, возвращает количество удаленных моделей.removeFirstBy($key, $value): bool
- удаление первой модели по значению ключа, возвращает true если модель была удалена.chunk(int $size): array
- разделение коллекции на массив состоящий из коллекций определенной длины.pluck(string $column): array
- получение массива значений моделей коллекции по названию свойства.
При работе с библиотекой необходимо не забывать о лимитах API amoCRM. Для оптимальной работы с данными лучше всего создавать/изменять за раз не более 50 сущностей в методах, где есть пакетная обработка.
Нужно не забывать про обработку ошибок, а также не забывать о безопасности хранилища токенов. Утечка токена грозит потерей доступа к аккаунту.
Библиотека поддерживает большое количество методов API. Методы сгруппированы в объекты-сервисы. Получить объект сервиса можно вызвав необходимый метод у библиотеки, например:
$leadsService = $apiClient->leads();
В данный момент доступны следующие сервисы:
Сервис | Цель сервиса |
---|---|
notes | Примечание сущности |
tags | Теги сущностей |
tasks | Задачи |
leads | Сделки |
contacts | Контакты |
companies | Компании |
catalogs | Каталоги |
catalogElements | Элементы каталогов |
customFields | Пользовательские поля |
customFieldGroups | Группы пользовательских полей |
account | Информация об аккаунте |
roles | Роли пользователей |
users | Роли юзеров |
customersSegments | Сегменты покупателей |
events | Список событий |
webhooks | Вебхуки |
unsorted | Неразобранное |
pipelines | Воронки сделок |
statuses | Статусы сделок |
widgets | Виджеты |
lossReason | Причины отказа |
transactions | Покупки покупателей |
customers | Покупатели |
customersStatuses | Сегменты покупателя |
customersBonusPoints | Бонусные баллы покупателя |
calls | Звонки |
products | Товары |
links | Массовая привязка сущностей |
shortLinks | Короткие ссылки |
talks | Беседы |
sources | Источники |
chatTemplates | Шаблоны чатов |
entitySubscriptions | Подписчики сущности |
getOAuthClient | oAuth сервис |
getRequest | Голые запросы |
files | Файлы |
entityFiles | Связь файлов с сущностями |
-
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.
Некоторые сервисы имеют специфичные методы, ниже рассмотрим сервисы, которые имеют специфичные методы.
- addComplex Создать сделки пакетно со связанным контакт и компанией через комплексный метод с поддержкой контроля дублей
- collection (LeadsCollection) - коллекция моделей создаваемой сущности
- Результатом выполнения будет новая коллекция созданных сущностей
addComplex(LeadsCollection $collection);
- addOneComplex Создать одну сделку со связанным контакт и компанией через комплексный метод с поддержкой контроля дублей
- collection (LeadsCollection) - коллекция моделей создаваемой сущности
- Результатом выполнения будет новая модель созданной сделки
addOneComplex(LeadModel $model);
Подробнее про использование метода комплексного создания смотрите в примере
-
getAuthorizeUrl получение ссылки на авторизация
- options (array)
- state (string) состояние приложения
- Результатом выполнения будет строка со ссылкой на авторизация приложения
getAuthorizeUrl(array $options = []);
- options (array)
-
getAccessTokenByCode получение access токена по коду авторизации
- code (string) код авторизации
- Результатом выполнения будет объект (AccessTokenInterface)
getAccessTokenByCode(string $code);
-
getAccessTokenByRefreshToken получение access токена по refresh токену
- accessToken (AccessTokenInterface) объект access токена
- Результатом выполнения будет объект (AccessTokenInterface)
getAccessTokenByRefreshToken(AccessTokenInterface $accessToken);
-
setBaseDomain установка базового домена, куда будут отправляться запросы необходимые для работы с токенами
- domain (string)
setBaseDomain(string $domain);
-
setAccessTokenRefreshCallback установка callback, который будет вызван при обновлении access токена
- function (callable)
setAccessTokenRefreshCallback(callable $function);
-
getOAuthButton установка callback, который будет вызван при обновлении access токена
- 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);
-
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
, entityFiles
, files
:
-
delete
- model (BaseApiModel) - модель сущности
- Результатом выполнения является bool значение
deleteOne(BaseApiModel $model);
-
deleteOne
- collection (BaseApiCollection) - коллекция моделей сущностей
- Результатом выполнения является bool значение
deleteOne(BaseApiModel $model);
- setMode Смена режима покупателей (периодические покупки или сегментация). Если покупатели выключены - то они будут включены.
- mode (string) - тип режима (periodicity или segments)
- isEnabled (bool) - включен ли функционал покупателей, по-умолчанию - true
- Результатом выполнения является строка названия включенного режима или null в случае отключения функционала
setMode(string $mode, bool $isEnabled = true);
-
earnPoints Начисляет бонусные баллы покупателю
- model (BonusPointsActionModel) - модель в которой Id покупателя и количество баллов для начисления
- Результатом выполнения является обновленное количество бонусных баллов покупателя или null в случае если произошла ошибка
earnPoints(BonusPointsActionModel $bonusPointsActionModel)
-
redeemPoints Списывает бонусные баллы покупателя
- model (BonusPointsActionModel) - модель в которой Id покупателя и количество баллов для списания
- Результатом выполнения является обновленное количество бонусных баллов покупателя или null в случае если произошла ошибка
redeemPoints(BonusPointsActionModel $bonusPointsActionModel)
- getByParentId Получение данных по ID родительской сущности
- parentId - ID родительской сущности
- filter (BaseEntityFilter) - фильтр
- with (array) - массив параметров with, которые поддерживает модель сервиса
getByParentId(int $parentId, BaseEntityFilter $filter = null, array $with = []);
- getCurrent
- with (array) - массив параметров with, которые поддерживает модель сервиса
- Результатом выполнения является модель AccountModel
getCurrent(array $with = []);
-
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);
-
subscribe
- model (WebhookModel) - модель вебхука
- Результатом выполнения является модель WebhookModel
subscribe(WebhookModel $webhookModel);
-
unsubscribe
- model (WebhookModel) - модель вебхука
- Результатом выполнения является bool значение
unsubscribe(WebhookModel $webhookModel);
-
install
- model (WidgetModel) - модель виджета
- Результатом выполнения является модель WidgetModel
install(WidgetModel $widgetModel);
-
uninstall
- model (WidgetModel) - модель виджета
- Результатом выполнения является модель WidgetModel
uninstall(WidgetModel $widgetModel);
-
settings
- Результатом выполнения является модель ProductsSettingsModel
settings();
-
updateSettings
- model (ProductsSettingsModel) - модель виджета
- Результатом выполнения является модель ProductsSettingsModel
updateSettings(ProductsSettingsModel $productsSettings);
- close
- model (TalkCloseActionModel) - модель для закрытия беседы
- Результатом выполнения - является закрытие беседы или запуск NPS-бота для последующего закрытия беседы
close(TalkCloseActionModel $closeAction)
- uploadOne
- model (FileUploadModel) - модель файла для загрузки
- Результатом выполнения является модель FileModel
uploadOne(FileUploadModel $model);
Вызов методов библиотеки может выбрасывать ошибки типа AmoCRMApiException
.
В данные момент доступны следующие типы ошибок, они все наследуют AmoCRMApiException:
Тип | Условия |
---|---|
AmoCRM\Exceptions\AmoCRMApiConnectExceptionException | Подключение к серверу не было выполнено |
AmoCRM\Exceptions\AmoCRMApiErrorResponseException | Сервер вернул ошибку на выполняемый запрос |
AmoCRM\Exceptions\AmoCRMApiHttpClientException | Произошла ошибка http клиента |
AmoCRM\Exceptions\AmoCRMApiNoContentException | Сервер вернул код 204 без результата, ничего страшного не произошло, просто нет данных на ваш запрос |
AmoCRM\Exceptions\AmoCRMApiTooManyRedirectsException | Слишком много редиректов (в нормальном режиме не выкидывается) |
AmoCRM\Exceptions\AmoCRMoAuthApiException | Ошибка в oAuth клиенте |
AmoCRM\Exceptions\BadTypeException | Передан неверный тип данных |
AmoCRM\Exceptions\InvalidArgumentException | Передан неверный аргумент |
AmoCRM\Exceptions\NotAvailableForActionException | Метод не доступен для вызова |
AmoCRM\Exceptions\AmoCRMApiPageNotAvailableException | Выбрасывается в случае запроса следующей или предыдущей страницы коллекции, когда страница отсутствует |
AmoCRM\Exceptions\AmoCRMMissedTokenException | Не установлен Access Token для выполнения запроса |
У выброшенных Exception есть следующие методы:
getErrorCode()
getTitle()
getLastRequestInfo()
getDescription()
У ошибки типа AmoCRMApiErrorResponseException есть метод getValidationErrors()
, который вернет ошибки валидации входных данных.
В данный момент библиотека поддерживает фильтры для следующих сервисов:
Сервис | Фильтр | Особенности | Поддерживает ли сортировку? |
---|---|---|---|
catalogElements |
\AmoCRM\Filters\CatalogElementsFilter |
Доступен в ограниченном виде, в будущих версиях будет расширен | ❌ |
companies |
\AmoCRM\Filters\CompaniesFilter |
Доступен только на аккаунтах, которые подключены к тестированию функционала фильтрации по API | ✅ |
contacts |
\AmoCRM\Filters\ContactsFilter |
Доступен только на аккаунтах, которые подключены к тестированию функционала фильтрации по API | ✅ |
customers |
\AmoCRM\Filters\CustomersFilter |
Доступен только на аккаунтах, которые подключены к тестированию функционала фильтрации по API | ✅ |
customFields |
\AmoCRM\Filters\CustomFieldsFilter |
Фильтр для метода получения дополнительных полей \AmoCRM\EntitiesServices\CustomFields::get |
❌ |
leads |
\AmoCRM\Filters\LeadsFilter |
Доступен только на аккаунтах, которые подключены к тестированию функционала фильтрации по API | ✅ |
events |
\AmoCRM\Filters\EventsFilter |
Фильтр для списка событий | ❌ |
leads , contacts , customers , companies |
\AmoCRM\Filters\LinksFilter |
Фильтр для получения связей для метода \AmoCRM\EntitiesServices\HasLinkMethodInterface::getLinks |
❌ |
notes |
\AmoCRM\Filters\NotesFilter |
Фильтра для \AmoCRM\EntitiesServices\EntityNotes::get |
✅ |
tags |
\AmoCRM\Filters\TagsFilter |
Фильтр для \AmoCRM\EntitiesServices\EntityTags::get |
❌ |
tasks |
\AmoCRM\Filters\TasksFilter |
Фильтр для метода \AmoCRM\EntitiesServices\Tasks::get |
✅ |
unsorted |
\AmoCRM\Filters\UnsortedFilter |
Фильтр для метода \AmoCRM\EntitiesServices\Unsorted::get |
✅ |
unsorted |
\AmoCRM\Filters\UnsortedSummaryFilter |
Фильтр для метода \AmoCRM\EntitiesServices\Unsorted::summary |
❌ |
webhooks |
\AmoCRM\Filters\WebhooksFilter |
Фильтр для метода получения хуков | ❌ |
sources |
\AmoCRM\Filters\SourcesFilter |
Фильтр для метода получения источников \AmoCRM\EntitiesServices\Sources::get |
❌ |
chatTemplates |
\AmoCRM\Filters\Chats\TemplatesFilter |
Фильтр для метода получения шаблонов чатов \AmoCRM\EntitiesServices\Chats\Templates::get |
❌ |
Сервисы, где необходима постраничная навигация | \AmoCRM\Filters\PagesFilter |
Фильтр, который подходит для любого сервиса, где есть постраничная навигация | ❌ |
Дополнительные поля доступны у сущностей следующих сервисов:
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
Тип поля | Модель значения | Коллекция моделей значений | Модель доп поля | Контакт | Сделка | Компания | Покупатель | Каталог | Сегмент |
---|---|---|---|---|---|---|---|---|---|
Текст | TextCustomFieldValueModel | TextCustomFieldValueCollection | TextCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Число | NumericCustomFieldValueModel | NumericCustomFieldValueCollection | NumericCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Флаг | CheckboxCustomFieldValueModel | CheckboxCustomFieldValueCollection | CheckboxCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Список | SelectCustomFieldValueModel | SelectCustomFieldValueCollection | SelectCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Мультисписок | MultiselectCustomFieldValueModel | MultiselectCustomFieldValueCollection | MultiSelectCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Мультитекст | MultitextCustomFieldValueModel | MultitextCustomFieldValueCollection | MultitextCustomFieldValuesModel | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Дата | DateCustomFieldValueModel | DateCustomFieldValueCollection | DateCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Ссылка | UrlCustomFieldValueModel | UrlCustomFieldValueCollection | UrlCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Дата и время | DateTimeCustomFieldValueModel | DateTimeCustomFieldValueCollection | DateTimeCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Текстовая область | TextareaCustomFieldValueModel | TextareaCustomFieldValueCollection | TextareaCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Переключатель | RadiobuttonCustomFieldValueModel | RadiobuttonCustomFieldValueCollection | RadiobuttonCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Короткий адрес | StreetAddressCustomFieldValueModel | StreetAddressCustomFieldValueCollection | StreetAddressCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Адрес | SmartAddressCustomFieldValueModel | SmartAddressCustomFieldValueCollection | SmartAddressCustomFieldValuesModel | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
День рождения | BirthdayCustomFieldValueModel | BirthdayCustomFieldValueCollection | BirthdayCustomFieldValuesModel | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Юр. лицо | LegalEntityCustomFieldValueModel | LegalEntityCustomFieldValueCollection | LegalEntityCustomFieldValuesModel | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Цена | PriceCustomFieldValueModel | PriceCustomFieldValueCollection | PriceCustomFieldValuesModel | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
Категория | CategoryCustomFieldValueModel | CategoryCustomFieldValueCollection | CategoryCustomFieldValuesModel | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
Предметы | ItemsCustomFieldValueModel | ItemsCustomFieldValueCollection | ItemsCustomFieldValuesModel | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
Метка | TrackingDataCustomFieldValueModel | TrackingDataCustomFieldValueCollection | TrackingDataCustomFieldValuesModel | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
Связь с другим элементом | LinkedEntityCustomFieldValueModel | LinkedEntityCustomFieldValueCollection | LinkedEntityCustomFieldValuesModel | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
Денежное | MonetaryCustomFieldModel | MonetaryCustomFieldValueCollection | MonetaryCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
Каталоги и списки | ChainedListCustomFieldModel | ChainedListCustomFieldValueCollection | ChainedListCustomFieldValuesModel | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ |
Файл | FileCustomFieldModel | FileCustomFieldValueCollection | FileCustomFieldValuesModel | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
Плательщик | PayerCustomFieldModel | PayerCustomFieldValueCollection | PayerCustomFieldValuesModel | ❌ | ❌ | ❌ | ❌ | ✅ (только счета-покупки) | ❌ |
Поставщик | SupplierCustomFieldModel | SupplierCustomFieldValueCollection | SupplierCustomFieldValuesModel | ❌ | ❌ | ❌ | ❌ | ✅ (только счета-покупки) | ❌ |
Пример кода, как создать коллекцию значения полей сущности:
//Создадим модель сущности
$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()));
На данный момент источники созданные интеграциями учитываются только при создании неразобранного из чатов.
При добавлении источника обязательными полями являются external_id
, name
интеграция может создать в аккаунте
не более 50 активных источников на аккаунт. При удалении источника, к примеру, со значением external_id: 'sales'
и при повторном создании с тем же external_id
crm может вернуть id
раннее удаленного источника. Поэтому не стоит
на стороне интеграции формировать первичный ключ из поля id
.
Чтобы источник отображался в кнопке whatsapp CRM Plugin необходимо указать поле источника services
с таким содержимым:
[
{
"type": "whatsapp",
"pages": [
{
"id": "<идентификатор или номер телефона>",
"name": "My WhatsApp",
"link": "<номер телефона>"
}
]
}
]
Чтобы правильно сформировать поле services
можно воспользоваться моделью \AmoCRM\Collections\Sources\SourceServicesCollection
Источник по-умолчанию (с полем default=true
) может быть только один или отсутствовать совсем. При отсутствии источника
по-умолчанию в сделках будет указан источник АПИ-интеграция с названием интеграции (как при создании неразобранного через АПИ).
Чтобы сменить источник по-умолчанию, достаточно нужному источнику проставить поле default=true
, у предыдущего источника
поле default будет выставлено в default=false
. Но при удалении источника по-умолчанию интеграция сама должна указать
новый источник по-умолчанию.
Источник по-умолчанию может быть использован интеграцией при переходе на множественные источники, особенно если интеграция поддерживает опцию написать первым.
К примеру исходное состояние:
Есть аккаунт с подключенной интеграцией с чатами, эта интеграция поддерживает только 1 источник.
На данный момент нам не важно как была установлена интеграция: через DP или маркетплейс.
Интеграция начинает внедрение поддержки множественных источников, логически разобьем на этапы:
1 этап
Интеграция умеет работать с АПИ источниками (но не отправляет и не принимает источник в сообщениях amojo).
Добавляет источник по-умолчанию, который логически соответствует источнику, использовавшемуся когда не было поддержки нескольких источников. Теперь crm будет присылать в сообщениях external_id
этого источника для всех чатов которые явно
не закреплены за конкретным источником.
2 этап
Интеграция умеет работать с источниками и при отправке сообщений от клиента (при создании чата) указывает external_id
Все чаты с новыми сообщениями становятся размеченными по источнику.
Так же интеграция теперь обрабатывает источник и учитывает его при отправке сообщения от менеджера, в том числе при начале чата с клиентом (опция "написать первым").
3 этап
Интеграция позволяет администратору аккаунта добавить (через интеграцию) второй и последующие источники.
Вся переписка числится за каким-то источником
Важный момент Источник по-умолчанию не привязывается к чатам, если его явно не передавали с сообщениями и тогда при смене источника по-умолчанию чат без разметки будет "числиться" за новым источником
Основные константы находятся в интерфейсе \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
\AmoCRM\Models\CatalogElementModel
- константы для аргумента with для сервисаcatalogElements
\AmoCRM\Enum\InvoicesCustomFieldsEnums
- константы для работы с полями каталога счетов (с версии 0.12 константы статусов переехали в \AmoCRM\Enum\Invoices\BillStatusEnumCode)\AmoCRM\Enum\Chats\Templates\Buttons\ButtonsEnums
- типы кнопок шаблонов чатов\AmoCRM\Enum\Sources\SourceServiceTypeEnum
- типы сервисов для источников\AmoCRM\Enum\Tags\TagColorsEnum
- возможные цвета для тегов\AmoCRM\Enum\Invoices\BillStatusEnumCode
- предустановленные статусы для Счетов/Покупок\AmoCRM\Enum\SuppliersCustomFieldsEnums
- константы для свойств поля поставщик
/**
* Получим модель с информацией о домене аккаунта по 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'];
try {
/**
* Одноразовый токен для интеграций, для того чтобы его получить используйте
* метод this.$authorizedAjax() в своей интеграции
* Подробнее: @link https://www.amocrm.ru/developers/content/web_sdk/mechanics
*
* Данный токен должен передаваться в заголовках вместе с запросом на ваш удаленный сервер
* X-Auth-Token: {disposable_token}
* Время жизни токена: 30 минут
*
* Расшифруем пришедший токен и получим модель с информацией
* Подробнее: @see DisposableTokenModel
*/
$disposableTokenModel = $apiClient->getOAuthClient()
->parseDisposableToken($token);
var_dump($disposableTokenModel->toArray());
} catch (DisposableTokenExpiredException $e) {
// Время жизни токена истекло
printError($e);
die;
} catch (DisposableTokenInvalidDestinationException $e) {
// Не прошёл проверку на адресата токена
printError($e);
die;
} catch (DisposableTokenVerificationFailedException $e) {
// Токен не прошел проверку подписи
printError($e);
die;
}
Также вы можете распарсить и модель одноразового токена для Salesbot/Marketingbot.
Для этого необходимо сделать вызов метода parseBotDisposableToken
:
$token = 'XXX';
try {
/**
* Одноразовый токен для ботов, его вы можете получить, сделав вызов widget_request в виджете в боте
* Подробнее: @link https://www.amocrm.ru/developers/content/digital_pipeline/salesbot#handler-widget_request
*
* Данный токен содержит в себе информацию об аккаунте и о сущности, с которой работает бот
* Для продолжения бота необходимо сделать запрос на метод, который был получен в теле хука
* Подробнее: @link https://www.amocrm.ru/developers/content/crm_platform/widgets-api#widget-continue
*
* Расшифруем пришедший токен и получим модель с информацией
* Подробнее: @see BotDisposableTokenModel
*/
$botDisposableTokenModel = $apiClient->getOAuthClient()
->parseBotDisposableToken($token);
var_dump($botDisposableTokenModel->toArray());
} catch (DisposableTokenExpiredException $e) {
// Время жизни токена истекло
printError($e);
die;
} catch (DisposableTokenInvalidDestinationException $e) {
// Не прошёл проверку на адресата токена
printError($e);
die;
} catch (DisposableTokenVerificationFailedException $e) {
// Токен не прошел проверку подписи
printError($e);
die;
}
/** @var AmoCRMApiClient $apiClient */
# Получим сервис для работы с валютами
$service = $apiClient->currencies();
# Получение списка валют
try {
$collection = $service->get();
var_dump($collection);
} catch (AmoCRMApiException $e) {
printError($e);
die;
}
# Получение списка валют с фильтром
$filter = new CurrenciesFilter();
$filter->setLimit(50);
$filter->setPage(2);
try {
$collection = $service->get($filter);
var_dump($collection);
} catch (AmoCRMApiException $e) {
printError($e);
die;
}
В рамках данного репозитория имеется папка 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 сущностей в них.
Если вы столкнулись с проблемой при работе с библиотекой, вы можете составить Issue, который будет рассмотрен при первой возможности.
При составлении, детально опишите проблему, приложите примеры кода, а также ответы на запросы из getLastRequestInfo
.
Не забывайте удалять из примеров значимые данные, которые не должны стать достоянием общественности.
Также могут быть рассмотрены пожелания по улучшению библиотеки.
Вы можете предложить свои исправления/изменения исходного кода библиотеки, посредством создания Issue с описанием, а также Pull request с упоминанием Issue в комментарии к нему. Они будут рассмотрены и будут приняты или отклонены. Некоторые Pull Request могут остаться без ответа и действия, в случае, если правки потенциально жизнеспособны, но в данный момент не являются ключевыми для проекта.
Если вы столкнулись с проблемой функционала amoCRM - обратитесь в техническую поддержку через чат в вашем аккаунте.
MIT