andrey-tech / amocrm-api-php
Простая обертка для работы с API amoCRM v2 с авторизацией по протоколу oAuth 2.0 или по API-ключу пользователя, поддержкой AJAX-запросов к frontend-методам, троттлингом запросов, блокировкой одновременного обновления одной сущности и логированием запросов/ответов к API в файл
Installs: 5 050
Dependents: 1
Suggesters: 0
Security: 0
Stars: 34
Watchers: 6
Forks: 12
Open Issues: 0
Requires
- php: >=7.0
- ext-curl: *
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^6
README
Простая обертка на PHP7+ для работы с REST API amoCRM v2 (версии 2) с авторизацией по протоколу oAuth 2.0 или по API-ключу пользователя, поддержкой AJAX-запросов к frontend-методам, троттлингом запросов к API, блокировкой одновременного обновления одной сущности и логированием запросов/ответов к API в файл.
Данная библиотека была создана для удовлетворения новых требований amoCRM, предъявляемых к публичным интеграциям:
Публичные интеграции должны использовать механизм авторизации oAuth 2.0, использование механизма API ключей не допускается. Требование с февраля 2020 года.
С 1 июля 2020 г. информация о API-ключе пользователя стала недоступна в интерфейсе amoCRM.
В настоящее время актуальной версией является REST API amoCRM v4 (версия 4) (запросы к API отправляются на /api/v4/).
Документация по REST API amoCRM v2
Документация по REST API v2 теперь недоступна на русскоязычной версии сайта amoCRM. На англоязычной версии сайта эта документация перенесена в раздел API V2 GENERAL METHODS.
Архив документации по REST API amoCRM v2 в формате HTML вынесен в самостоятельный репозиторий.
Ниже приведены ссылки на отдельные HTML-файлы этого архива:
- Аккаунт
- Авторизация
- Компании
- Контакты
- Сделки
- События
- Задачи
- Списки
- Элементы списков
- Неразобранное
- Webhooks
- Покупатели
- Дополнительные поля
- Виджеты
- Товары
- Воронки и этапы продаж
- Логирование звонков
- Уведомление о звонке
- Коды ошибок
- Ограничения и рекомендации
Содержание
- Требования
- Установка
- Авторизация
- Параметры настройки
- Работа с сущностями amoCRM
- Список методов и констант моделей
- Базовый класс моделей
AmoObject
- Класс
AmoContact
- модель контакта - Класс
AmoCompany
- модель компании - Класс
AmoLead
- модель сделки - Класс
AmoTask
- модель задачи - Класс
AmoNote
- модель события (примечания) - Класс
AmoCatalog
- модель списка (каталога) - Класс
AmoCatalogElement
- модель элемента списка (каталога) - Класс
AmoIncomingLead
- базовая модель заявки из неразобранного
- Базовый класс моделей
- Методы для загрузки сущностей
- Методы для пакетного сохранения сущностей
- Методы для пакетного удаления сущностей
- Методы для webhooks
- Методы для неразобранного
- Дополнительные методы
- Список методов и констант моделей
- Блокировка одновременного обновления одной сущности
- Троттлинг запросов к API
- Отладочный режим и логирование
- Обработка ошибок
- Примеры
- Работа с контактами
- Работа с компаниями
- Работа со сделками
- Работа с событиями
- Работа с задачами
- Работа со списками (каталогами)
- Работа с элементами списков (каталогов)
- Работа с webhooks
- Работа с заявками из неразобранного
- Поддержка AJAX-запросов к frontend-методам
- Работа с несколькими поддоменами
- Отладка и логирование
- UML-диаграмма классов
- Автор
- Лицензия
Требования
- PHP >= 7.0.
- Произвольный автозагрузчик классов, реализующий стандарт PSR-4.
Установка
Установка через composer:
$ composer require andrey-tech/amocrm-api-php:"^2.7"
или путем добавления:
"andrey-tech/amocrm-api-php": "^2.7"
в секцию require файла composer.json.
Авторизация
Авторизация по протоколу oAuth 2.0 (актуальный метод)
static AmoAPI::oAuth2(string $subdomain, string $clientId, string $clientSecret, string $redirectUri, string $authCode = null) :array
$subdomain
- поддомен или полный домен amoCRM;$clientId
- ID интеграции;$clientSecret
- секрет интеграции;$redirectUri
- URI перенаправления;$authCode
- код авторизации (временный ключ) для обмена на access токен и refresh токен.
Первичная авторизация и обмен кода авторизации на access токен и refresh токен
При первичной авторизации производится обмен кода авторизации authCode
на access токен и refresh токен, которые сохраняются в хранилище токенов вместе с переданными значениями $clientId
, $clientSecret
и $redirectUri
.
use AmoCRM\{AmoAPI, AmoAPIException}; use AmoCRM\TokenStorage\TokenStorageException; try { // Параметры авторизации по протоколу oAuth 2.0 $clientId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'; $clientSecret = 'TFPoaG2A5hp3G3o6opCL8eC9v92Mm0fKQWEHBDwIjedCmVliT4kI3XQcjOOP1s'; $authCode = 'eee60208cc09e3ae3506d667228038345b6578a11d4862094655f630074c8c6ed87a9d804d49b5880e'; $redirectUri = 'https://www.example.com/oauth2/'; $subdomain = 'testsubdomain'; // Первичная авторизация AmoAPI::oAuth2($subdomain, $clientId, $clientSecret, $redirectUri, $authCode); // Получение информации об аккаунте вместе с пользователями и группами print_r(AmoAPI::getAccount($with = 'users,groups')); } catch (AmoAPIException $e) { printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); } catch (TokenStorageException $e) { printf('Ошибка обработки токенов (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Последующие авторизации
После первичного обмена кода авторизации на access токен и refresh токен, при последующих авторизациях,
достаточно передать только $subdomain
- поддомен или полный домен amoCRM.
use AmoCRM\{AmoAPI, AmoAPIException}; use AmoCRM\TokenStorage\TokenStorageException; try { // Последующие авторизации $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Получение информации об аккаунте print_r(AmoAPI::getAccount()); } catch (AmoAPIException $e) { printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); } catch (TokenStorageException $e) { printf('Ошибка обработки токенов (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Получение нового access токена и refresh токена по истечении срока действия access токена происходит автоматически,
когда на запрос к API amoCRM приходит ответ с HTTP-статусом 401 Unauthorized
.
Хранение access и refresh токенов
Сохранение и загрузка токенов выполняется с помощью классов, реализующих интерфейс \AmoCRM\TokenStorage\TokenStorageInterface
.
Интерфейс TokenStorageInterface
В интерфейсе \AmoCRM\TokenStorage\TokenStorageInterface
определены три метода:
save(array $tokens, string $domain) :void
Сохраняет параметры авторизации и токены.$tokens
- ассоциативный массив параметров авторизации и токенов:
[ 'access_token' => '...', 'refresh_token' => '...', 'client_id' => '...', 'client_secret' => '...', 'redirect_uri'=> '...' ]
;$domain
- полный домен amoCRM (например,testsubdomain.amocrm.ru
).
load(string $domain) :?array
Загружает параметры авторизации и токены и возвращает их. Метод должен возвращатьnull
, когда нет сохраненных токенов.$domain
- полный домен amoCRM.
hasTokens(string $domain) :bool
Проверяет существуют ли токены для заданного домена amoCRM, то есть была ли выполнена первичная авторизация.$domain
- полный домен amoCRM.
Класс FileStorage
По умолчанию для сохранения и загрузки токенов используется класс \AmoCRM\TokenStorage\FileStorage
,
реализующий интерфейс \AmoCRM\TokenStorage\TokenStorageInterface
.
Класс хранит токены в JSON-файлах, с именами, соответствующими именам доменов amoCRM (например, testsubdomain.amocrm.ru.json
).
В параметрах, передаваемых конструктору класса, можно указать каталог для хранения файлов токенов:
__construct(string $storageFolder = '')
Конструктор класса.$storageFolder
- каталог для хранения файлов токенов. Может быть задан абсолютный путь или путь относительно текущего рабочего каталога. Если передана пустая строка, то создается каталог по умолчанию - 'tokens'.
При возникновении ошибок выбрасывается исключение класса \AmoCRM\TokenStorage\TokenStorageException
.
Использование собственного класса для сохранения токенов
Пример использования собственного класса для сохранения токенов в базе данных:
use AmoCRM\{AmoAPI, AmoAPIException}; use AmoCRM\TokenStorage\DatabaseStorage; try { // Параметры авторизации по протоколу oAuth 2.0 $clientId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'; $clientSecret = 'TFPoaG2A5hp3G3o6opCL8eC9v92Mm0fKQWEHBDwIjedCmVliT4kI3XQcjOOP1s'; $authCode = 'eee60208cc09e3ae3506d667228038345b6578a11d4862094655f630074c8c6ed87a9d804d49b5880e'; $redirectUri = 'https://www.example.com/oauth2/'; $subdomain = 'testsubdomain'; // Устанавливаем объект класса, обеспечивающего сохранение токенов AmoAPI::$tokenStorage = new DatabaseStorage(); // Авторизация AmoAPI::oAuth2($subdomain, $clientId, $clientSecret, $redirectUri, $authCode); // Получение информации об аккаунте print_r(AmoAPI::getAccount()); } catch (AmoAPIException $e) { printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Пример класса \AmoCRM\TokenStorage\DatabaseStorage
:
<?php namespace AmoCRM\TokenStorage; class DatabaseStorage implements TokenStorageInterface { /** * Сохраняет токены * @param array $tokens Токены для сохранения * @param string $domain Полный домен amoCRM * @return void */ public function save(array $tokens, string $domain) { // Здесь токены сохраняются в базе данных } /** * Загружает токены * @param string $domain Полный домен amoCRM * @return array|null */ public function load(string $domain) { // Здесь токены извлекаются из базы данных } /** * Проверяет: существуют ли токены для заданного домена amoCRM, * то есть была ли выполнена первичная авторизация * @param string $domain Полный домен amoCRM * @return boolean */ public function hasTokens(string $domain) :bool { // Здесь проверяется наличие токенов в базе данных } }
Проверка наличия первичной авторизации
Чтобы проверить, происходила ли первичная авторизация для нужного поддомена amoCRM,
можно воспользоваться методом hasTokens() интерфейса \AmoCRM\TokenStorage\TokenStorageInterface
:
use AmoCRM\{AmoAPI, AmoAPIException}; use AmoCRM\TokenStorage\{FileStorage, TokenStorageException}; try { // Параметры авторизации по протоколу oAuth 2.0 $clientId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'; $clientSecret = 'TFPoaG2A5hp3G3o6opCL8eC9v92Mm0fKQWEHBDwIjedCmVliT4kI3XQcjOOP1s'; $authCode = 'eee60208cc09e3ae3506d667228038345b6578a11d4862094655f630074c8c6ed87a9d804d49b5880e'; $redirectUri = 'https://www.example.com/oauth2/'; $subdomain = 'testsubdomain'; AmoAPI::$tokenStorage = new FileStorage(); $domain = AmoAPI::getAmoDomain($subdomain); $isFirstAuth = ! AmoAPI::$tokenStorage->hasTokens($domain); if ($isFirstAuth) { // Первичная авторизация AmoAPI::oAuth2($subdomain, $clientId, $clientSecret, $redirectUri, $authCode); } else { // Последующие авторизации AmoAPI::oAuth2($subdomain); } } catch (AmoAPIException $e) { printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); } catch (TokenStorageException $e) { printf('Ошибка обработки токенов (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Авторизация по API-ключу пользователя (устаревший метод)
С 1 июля 2020 г. информация о API-ключе пользователя стала недоступна в интерфейсе amoCRM.
static AmoAPI::oauth(string $login, string $hash, string $subdomain) :array
$login
- логин пользователя;$hash
- API-ключ пользователя;$subdomain
- поддомен или полный домен amoCRM.
Пример авторизации по API-ключу пользователя.
use \AmoCRM\{AmoAPI, AmoAPIException}; try { // Параметры авторизации по API-ключу пользователя $login = 'login@example.com'; $hash = 'TFPoaG2A5hp3G3o6opCL8eC9v92Mm0fKQWEHBDwIjedCmVliT4kI3XQcjOOP1s'; $subdomain = 'testsubdomain'; // Авторизация AmoAPI::auth($login, $hash, $subdomain); // Получение информации об аккаунте print_r(AmoAPI::getAccount()); } catch (AmoAPIException $e) { printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Одновременная авторизация в нескольких аккаунтах amoCRM
Библиотека позволяет одновременно работать с несколькими поддоменами (аккаунтами) amoCRM. Для этого необходимо последовательно выполнить авторизацию в каждом их поддоменов.
use AmoCRM\{AmoAPI, AmoAPIException}; try { // Авторизация в поддомене 1 AmoAPI::oAuth2($subdomain1, $clientId1, $clientSecret1, $redirectUri1, $authCode1); // Авторизация в поддомене 2 AmoAPI::auth($login2, $hash2, $subdomain2); //... // Авторизация в поддомене N AmoAPI::oAuth2($subdomainN, $clientIdN, $clientSecretN, $redirectUriN, $authCodeN); } catch (AmoAPIException $e) { printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Параметры настройки
Все параметры настройки библиотеки устанавливаются через статические свойства класса AmoAPI
.
Работа с сущностями amoCRM
Работа с сущностями amoCRM строится с помощью:
- методов классов-моделей:
AmoContact
- модель контакта;AmoCompany
- модель компании;AmoLead
- модель сделки;AmoNote
- модель события (примечания);AmoTask
- модель задачи;AmoCatalog
- модель списка (каталога);AmoCatalogElement
- модель элемента списка (каталога);AmoIncomingLead
- абстрактная базовая модель заявки из неразобранного;AmoIncomingLeadForm
- модель заявки из неразобранного при добавлении заявки из веб-формы;AmoIncomingLeadSip
- модель заявки из неразобранного с типом входящий звонок.
- дополнительных статических методов класса
AmoAPI
; - параметров моделей, доступных через публичные свойства объектов классов-моделей.
Список методов и констант моделей
Базовый класс моделей AmoObject
Абстрактный базовый класс всех моделей - AmoObject
содержит следующие общие методы:
__construct(array $params = [], string $subdomain = null)
Создает новый объект модели и заполняет ее.$params
- параметры модели;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней авторизации.
fillById(int|string $id, array $params = []) :AmoObject
Заполняет модель данными по ID сущности.$id
- ID сущности;$params
- дополнительные параметры, передаваемые в GET-запросе к amoCRM.
getParams() :array
Возвращает все параметры модели.getCustomFields(array|int $ids) :array
Возвращает дополнительные поля по ID полей.$ids
- ID поля или массив ID полей.
getCustomFieldValueById(int $id, bool $returnFirst = true, string $returnValue = 'value')
Возвращает значение дополнительного поля по ID поля.$i
- ID поля;$returnFirst
- вернуть только первое значение из списка значений;$returnValue
- имя параметра, значение которого возвращается (value
,enum
,subtype
).
setCustomFields(array $params) :AmoObject
Устанавливает значения дополнительных полей.$params
- массив значений дополнительных полей.
addTags(array|string $tags) :AmoObject
Добавляет теги.$tags
- тег или массив тегов.
delTags(array|string $tags) :AmoObject
Удаляет теги.$tags
- тег или массив тегов.
save(bool $returnResponse = false)
Сохраняет объект модели в amoCRM и возвращает ID сущности.$returnResponse
- вернуть ответ сервера вместо ID сущности.
Константы, определяющие типы привязываемых сущностей:
CONTACT_TYPE = 1
- контакт;LEAD_TYPE = 2
- сделка;COMPANY_TYPE = 3
- компания;TASK_TYPE = 4
- задача;CUSTOMER_TYPE = 12
- покупатель.
Класс AmoContact
- модель контакта
addLeads(array|int $id)
Привязывает сделки по ID.addCustomers(array|int $id)
Привязывает покупателей по ID.addCompany(int $id)
Привязывает компанию по ID.getPhone()
Возвращает первый телефон контакта.getEmail()
Возвращает первый e-mail контакта.
Класс AmoCompany
- модель компании
addLeads(array|int $id)
Привязывает сделки по ID.addContacts(array|int $id)
Привязывает контакты по ID.addCustomers(array|int $id)
Привязывает покупателей по ID.getPhone()
Возвращает первый телефон компании.getEmail()
Возвращает первый e-mail компании.
Класс AmoLead
- модель сделки
⚠ Для заявок из неразобранного существуют специальные методы.
addContacts(array|int $id)
Привязывает контакты по ID контакта(ов) (не более 40 контактов у одной сделки).removeContacts(array|int $id)
Отвязывает контакты по ID контакта(ов).addCompany(int $id)
Привязывает компанию по ID компании.removeCompany(int $id)
Отвязывает компанию по ID компании.setCatalogElements(array $catalogElements)
Устанавливает элементы списков (каталогов) по ID списков.
Класс AmoTask
- модель задачи
addContact(int $id)
Привязывает контакт по ID.addLead(int $id)
Привязывает сделку по ID.
Константы класса, определяющие типы задач:
CALL_TASKTYPE = 1
- звонок;MEET_TASKTYPE = 2
- встреча;MAIL_TASKTYPE = 3
- написать письмо.
Класс AmoNote
- модель события (примечания)
Константы класса, определяющие типы событий:
LEAD_CREATED_NOTETYPE = 1
- создание сделки;CONTACT_CREATED_NOTETYPE = 2
- создание контакта;LEAD_STATUS_CHANGED_NOTETYPE = 3
- изменение статуса сделки;COMMON_NOTETYPE = 4
- обычное примечание;COMPANY_CREATED_NOTETYPE = 12
- создание компании;TASK_RESULT_NOTETYPE = 13
результат по задаче;SYSTEM_NOTETYPE = 25
- системное сообщение;SMS_IN_NOTETYPE = 102
- входящее SMS сообщение;SMS_OUT_NOTETYPE = 103
- исходящее SMS сообщение.
Класс AmoCatalog
- модель списка (каталога)
Класс AmoCatalog
не имеет собственных специфических методов.
Класс AmoCatalogElement
- модель элемента списка (каталога)
Класс AmoCatalogElement
не имеет собственных специфических методов.
Класс AmoIncomingLead
- базовая модель заявки из неразобранного
Работа с заявками из неразобранного существенно отличается от работы с другими сущностями amoCRM.
Согласно официальной документации:
Изначально неразобранное было в отдельном хранилище и являлось отдельной сущностью именно поэтому до сих пор в интерфейсах amoCRM и в API есть особенности которые отличают поведение сделки в статусе Неразобранное от сделок в других статусах.
⚠ Поэтому для моделей заявок из неразобранного не работают следующие методы класса AmoObject
:
fillById()
;getCustomFields()
;getCustomFieldValueById()
;setCustomFields()
;addTags()
;delTags()
;AmoAPI::saveObjects()
;AmoAPI::saveObjectsWithLimit()
.
Общие методы для работы с заявками из неразобранного
Абстрактный базовый класс модели заявки из неразобранного - AmoIncomingLead
содержит следующие методы:
fillByUid(int|string $uid, array $params = []) :AmoObject
Заполняет модель заявки данными по UID заявки.$uid
- UID сущности;$params
- дополнительные параметры, передаваемые в GET-запросе к amoCRM.
setIncomingLeadInfo(array $params) :AmoIncomingLead
Устанавливает параметры заявки из неразобранного.$params
- параметры неразобранного.
addIncomingLead(AmoLead|array $lead) :AmoIncomingLeadSip
Добавляет параметры сделки.$lead
- объект классаAmoLead
или массив параметров сделки.
addIncomingContact(AmoContact|array $contact) :AmoIncomingLead
Добавляет параметры контакта.$contact
- объект классаAmoContact
или массив параметров контакта.
addIncomingCompany(AmoCompany|array $company) :AmoIncomingLead
Добавляет параметры компании.$company
- объект классаAmoCompany
или массив параметров компании.
save(bool $returnResponse = false)
Добавляет новую заявку в неразобранное и возвращает массив, содержащий UID заявки.$returnResponse
- вернуть ответ сервера вместо UID.
Статические методы для пакетного добавления заявок в amoCRM, а также для принятия или отклонения неразобранных заявок находятся в классе AmoAPI
.
Класс AmoIncomingLeadForm
- модель заявки из неразобранного при добавлении из веб-формы
Дочерний класс AmoIncomingLeadForm
не имеет собственных специфических методов.
Класс AmoIncomingLeadSip
- модель заявки из неразобранного с типом входящий звонок
Дочерний класс AmoIncomingLeadSip
не имеет собственных специфических методов.
Методы для загрузки сущностей
Класс AmoAPI
содержит следующие общие статические методы для загрузки сущностей:
static getAll<Entities> (array $params, bool $returnResponse = false, string $subdomain = null) :\Generator
Загружает ВСЕ сущности заданного типа <Entities> c возможностью фильтрации.
Возвращает объект типа \Generator для последующей выборки параметров сущностей.<Entities>
:- Contacts
- Companies
- Leads
- Tasks
- Notes
- CatalogElements
- IncomingLeads
$params
- параметры фильтрации;$returnResponse
- возвращать полный ответ сервера amoCRM вместо массива параметров сущностей;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
static get<Entities>(array $params, bool $returnResponse = false, string $subdomain = null) :?array
Загружает сущности заданного типа <Entities> c возможностью фильтрации и постраничной выборки.
Возвращает массив параметров сущностей для заполнения моделей или null.<Entities>
:- Contacts
- Companies
- Leads
- Tasks
- Notes
- Webhooks
- Widgets
- IncomingLeads
- IncomingLeadsSummary
- Pipelines
- Catalogs
- CatalogElements
$params
- параметры фильтрации и постраничной выборки;$returnResponse
- возвращать полный ответ сервера amoCRM вместо массива параметров сущностей;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
Методы для пакетного сохранения сущностей
Класс AmoAPI
содержит статические методы для пакетного сохранения (добавления или обновления) за один запрос до 500
сущностей различного типа для одного поддомена amoCRM.
Согласно официальной документации:
Максимальное кол-во создаваемых/изменяем сущностей не более 500, для более оптимальной работы интеграции и избежания ошибок, рекомендуется не более 250. В случае получения 504 ошибки рекомендуется уменьшить количество передаваемых сущностей в запросе и повторить запрос.
static saveObjects(array $amoObjects, bool $returnResponses = false, string $subdomain = null) :array
Добавляет или обновляет сущности в amoCRM. Возвращает массив параметров сущностей.$amoObjects
Массив объектов классов-моделей (не более 500 объектов одного типа):AmoContact
,AmoCompany
,...;$returnResponses
- возвращать массив ответов сервера amoCRM вместо массива параметров сущностей;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
static saveObjectsWithLimit(array $amoObjects, bool $returnResponses = false, string $subdomain = null, $limit = 250) :array
Добавляет или обновляет сущности в amoCRM с ограничением на число сущностей в одном запросе к API. Возвращает массив параметров сущностей.$amoObjects
Массив объектов классов-моделей:AmoContact
,AmoCompany
,...;$returnResponses
- возвращать массив ответов сервера amoCRM вместо массива параметров сущностей;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации;$limit
- максимальное число сущностей в одном запросе к API.
Методы для пакетного удаления сущностей
Класс AmoAPI
содержит статический метод для пакетного удаления списков и элементов списков:
static delteObjects(array $amoObjects, bool $returnResponses = false, string $subdomain = null) :array
Удаляет сущности в amoCRM. Возвращает пустой массив параметров сущностей.$amoObjects
Массив объектов классов-моделей:AmoCatalog
илиAmoCatalogElement
;$returnResponses
- возвращать массив ответов сервера amoCRM вместо пустого массива параметров сущностей;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
Методы для webhooks
Класс AmoAPI
содержит статические методы для добавления и удаления webhooks:
static addWebhooks(array $params, bool $returnResponse = false, string $subdomain = null) :array
Добавляет один webhook или несколько webhooks (не более 100).params
- параметры webhook или массив параметров webhooks;$returnResponse
- возвращать массив ответов сервера amoCRM вместо массива параметров webhook;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
static deleteWebhooks(array $params, bool $returnResponse = false, string $subdomain = null) :array
Удаляет один webhook или несколько webhooks (не более 100).params
- параметры webhook или массив параметров webhooks;$returnResponse
- возвращать массив ответов сервера amoCRM вместо массива параметров webhook;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
Методы для неразобранного
Класс AmoAPI
содержит следующие статические методы для работы с заявками из неразобранного:
static saveIncomingObjects(AmoIncomingLeadForm|AmoIncomingLeadSip|array $amoObjects, bool $returnResponses = false, string $subdomain = null) :array
Пакетно добавляет заявки в неразобранное. Возвращает массив параметров UID неразобранного.$amoObjects
- объект классов-моделейAmoIncomingLeadForm
илиAmoIncomingLeadSip
или массив этих объектов;$returnResponses
- возвращать массив ответов сервера amoCRM вместо массива UID;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
static saveIncomingObjectsWithLimit(AmoIncomingLeadForm|AmoIncomingLeadSip|array $amoObjects, bool $returnResponses = false, string $subdomain = null, $limit = 250) :array
Пакетно добавляет заявки в неразобранное с ограничением на число заявок в одном запросе к API. Возвращает массив UID неразобранного.$amoObjects
- объект классов-моделейAmoIncomingLeadForm
илиAmoIncomingLeadSip
или массив этих объектов;$returnResponses
- возвращать массив ответов сервера amoCRM вместо массива UID;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации;$limit
- максимальное число заявок в одном запросе к API.
static acceptIncomingLeads(array $params, bool $returnResponse = false, $subdomain = null) :array
Принимает неразобранные заявки.params
- параметры заявок;$returnResponse
- возвращать ответ сервера amoCRM вместо массива параметров принятой заявки;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
static declineIncomingLeads(array $params, bool $returnResponse = false, $subdomain = null) :array
Отклоняет неразобранные заявки.params
- параметры заявок;$returnResponse
- возвращать ответ сервера amoCRM вместо массива параметров отклоненной заявки;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
Дополнительные методы
Дополнительные статические методы класса AmoAPI
:
static getAccount(string $with = '', string $subdomain = null) :array
Возвращает информацию об аккаунте amoCRM.$with
- Разделенный запятыми список возвращаемых дополнительных параметров аккаунта, включающий:custom_fields
- дополнительные поля сущностей;users
- пользователи;pipelines
- воронки;groups
- группы пользователей;note_types
- типы событий (примечаний);task_types
- типы задач.
$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
static getAccountDomain(string $subdomain = null) :array
Возвращает информацию о домене аккаунта amoCRM при авторизации по протоколу oAuth2.0.$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.
static getLastResponse(bool $unescapeUnicode = true) :?string
Возвращает последний ответ сервера amoCRM в сыром виде.$unescapeUnicode
- Декодировать символы UTF-8 \uXXXX в ответе сервера.
static request(string $query, string $type = 'GET', array $params = [], string $subdomain = null) :?array
Позволяет выполнить RAW запрос к API amoCRM.$query
- путь в URL запроса;$type
- метод запроса 'GET', 'POST' или 'AJAX';$params
- параметры запроса;$subdomain
- поддомен или полный домен amoCRM. Если null, то используется поддомен последней авторизации.
static getAmoDomain(string $subdomain) :string
Возвращает полное имя домена amoCRM.$subdomain
- поддомен или полный домен amoCRM.
Блокировка одновременного обновления одной сущности
При одновременном обновлении одной и той же сущности (сделки, контакта, компании и т.д. с одинаковым ID)
в разных процессах или потоках исполнения в API amoCRM может возникать ошибка "Last modified date is older than in database"
из-за передаваемого вместе с запросом на обновление значения updated_at
сущностей.
Для предотвращения возникновения данной ошибки в методе save()
реализован механизм блокировки одновременного обновления одной сущности.
До окончания обновления сущности в первом по времени запущенном процессе (потоке исполнения), то есть до получения ответа от API amoCRM,
другие процессы, конкурирующие за обновление той же сущности, приостанавливаются и предпринимают повторные попытки выполнить обновление сущности
каждые AmoAPI::$lockEntityTimeout
секунд с максимально допустимым числом попыток AmoAPI::$lockEntityAttempts
.
Троттлинг запросов к API
Для предотвращения превышения максимально допустимого числа запросов к API amoCRM (не более 7 запросов в секунду)
в рамках одного процесса или потока исполнения в библиотеке реализован простой алгоритм троттлинга запросов,
основанный на вычислении времени, прошедшего с момента отправки последнего запроса к API, и приостановке процесса
до истечения 1/AmoAPI::$throttle
секунд.
Отладочный режим и логирование
При включении отладочного режима AmoAPI::$debug = true
информация о каждом запросе/ответе к API amoCRM выводится в STDOUT.
Для логирования каждого запроса/ответа к API amoCRM может быть использован произвольный класс-логгер, реализующий стандарт PSR-3,
или простейший класс-логгер AmoAPIDebugLogger
. Объект класса-логгера устанавливается в свойстве AmoAPI::$debugLogger
.
Логирование выполняется независимо от состояния отладочного режима AmoAPI::$debug
.
При каждом запросе/ответе к API в классе-логгере вызывается метод debug()
.
В конструктор класса AmoAPIDebugLogger
может быть передано имя лог-файла:
__construct(string $logFile = 'logs/debug.log')
$logFile
- лог-файл.
Обработка ошибок
При возникновении ошибок выбрасывается исключение с объектом класса \AmoCRM\AmoAPIException
.
Класс-исключение AmoAPIException
содержит следующие вспомогательные методы:
getErrors() :array
Возвращает массив сообщений об ошибках (errors) из ответа сервера amoCRM;getItems() :array
Возвращает массив параметров сущностей (items) из ответа сервера amoCRM.
Примеры
Работа с контактами
use AmoCRM\{AmoAPI, AmoContact, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Загрузка ВСЕХ контактов с возможностью фильтрации $generator = AmoAPI::getAllContacts([ 'query' => 'Ганс' ]); foreach ($generator as $items) { foreach ($items as $item) { print_r($item); } } // Загрузка контактов с возможностью фильтрации и постраничной выборки $items = AmoAPI::getContacts([ 'limit_rows' => 100, 'limit_offset' => 1000 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Создание нового контакта $contact1 = new AmoContact([ 'name' => 'Ганс-Дитрих Геншер', 'responsible_user_id' => 12345678 ]); // Установка дополнительных полей $contact1->setCustomFields([ '6532343' => 41, '123456' => [[ 'value' => '+79451112233', 'enum' => 'WORK' ]], '123467' => [[ 'value' => 'hans@example.com', 'enum' => 'WORK' ]] ]); // Сохранение контакта и получение его ID $contact1Id = $contact1->save(); // Обновление существующего контакта и получение ответа сервера amoCRM $contact2 = new AmoContact([ 'id' => 12300344, 'name' => 'Улоф Йоаким Пальме' ]); $contact2->first_name = 'Улоф'; $contact2->last_name = 'Пальме'; print_r($contact1->save($returnResponse = true)); // Пакетное добавление и/или обновление контактов $items = AmoAPI::saveObjects([ $contact1, $contact2 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Заполнение модели контакта по ID контакта $contact3 = new AmoContact(); $contact3->fillById(12345679); // Получение всех дополнительных полей контакта print_r($contact3->custom_fields); // Получение всех параметров контакта из модели print_r($contact3->getParams()); // Получение дополнительных полей контакта по ID полей print_r($contact3->getCustomFields([ 123456, 123467 ])); // Получение первого значения дополнительного поля контакта по ID поля print_r($contact3->getCustomFieldValueById(155114)); // Получение всех значений дополнительного поля контакта по ID поля print_r($contact3->getCustomFieldValueById(155116, $returnFirst = false)); // Получение первого ENUM дополнительного поля контакта по ID поля print_r($contact3->getCustomFieldValueById(155116, $returnFirst = true, $returnValue = 'enum')); // Получение всех ENUM дополнительного поля контакта по ID поля print_r($contact3->getCustomFieldValueById(155116, $returnFirst = false, $returnValue = 'enum')); // ------------------------------------------------------------------------- // Привязка сделок к контакту по ID сделок $contact3->addLeads([ 12380925, 12364352 ]); // Привязка покупателей к контакту по ID покупателей $contact3->addCustomers([ 1237374, 1239658 ]); // Добавление тегов к контакту $contact3->addTags([ 'сотрудник', 'стажер' ]); // Удаление тегов контакта $contact3->delTags('курьер'); // Сохранение контакта $contact3->save(); // ------------------------------------------------------------------------- $items = AmoAPI::getContacts([ 'responsible_user_id' => 12373452 ]); // Пакетная привязка сделки к контактам $contacts = []; foreach ($items as $item) { $contacts[] = (new AmoContact($item))->addLeads(12380925); } // Пакетное сохранение контактов AmoAPI::saveObjects($contacts); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Работа с компаниями
use AmoCRM\{AmoAPI, AmoCompany, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Загрузка ВСЕХ компаний с возможностью фильтрации $generator = AmoAPI::getAllCompanies([ 'query' => 'OOO', 'limit_offset' => 12000 ]); foreach ($generator as $items) { foreach ($items as $item) { print_r($item); } } // Загрузка компаний с возможностью фильтрации и постраничной выборки $items = AmoAPI::getCompanies([ 'responsible_user_id' => 12357492, 'limit_rows' => 250, 'limit_offset' => 1000 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Создание новой компании $company1 = new AmoCompany([ 'name' => 'ООО МММ', 'responsible_user_id' => 12358394, ]); // Установка дополнительных полей $company1->setCustomFields([ '2390423' => 'Город Москва', '123456' => [[ 'value' => '+79457778899', 'enum' => 'WORK' ]], '123467' => [[ 'value' => 'mmm@example.com', 'enum' => 'WORK' ]] ]); // Привязка контакта $company1->addContacts(12375435); // Привязка сделки $company1->addLeads(12349693); // Привязка покупателя $company1->addCustomers(1237374); // Добавление тега $company1->addTags('Акционер'); // Сохранение компании и получение ее ID $companyId = $company1->save(); // Обновление существующей компании и получение ответа сервера amoCRM $company2 = new AmoCompany([ 'id' => 12375435, 'created_by' => 12396034, 'name' => 'ООО Рога и Копыта', ]); $response = $company2->save($returnResponse = true); // Пакетное добавление и/или обновление компаний $items = AmoAPI::saveObjects([ $company1, $company2 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Заполнение модели компании по ID $company3 = new AmoCompany(); $company3->fillById(12375435); // Получение всех параметров компании из модели print_r($company3->getParams()); // Получение дополнительных полей компании по ID полей print_r($company3->getCustomFields([ 123456, 123467, 2390423 ])); // Получение первого значения дополнительного поля компании по ID поля print_r($company3->getCustomFieldValueById(2390423)); // Получение всех значений дополнительного поля компании по ID поля print_r($company3->getCustomFieldValueById(2390423, $returnFirst = false)); // Получение первого subtype дополнительного поля компании по ID поля print_r($company3->getCustomFieldValueById(2390423, $returnFirst = true, $returnValue = 'subtype')); // Получение первого ENUM дополнительного поля компании по ID поля print_r($company3->getCustomFieldValueById(2390423, $returnFirst = true, $returnValue = 'enum')); // ------------------------------------------------------------------------- $items = AmoAPI::getCompanies([ 'responsible_user_id' => 12358394 ]); // Пакетная привязка сделки к компаниям $companies = []; foreach ($items as $item) { $companies[] = (new AmoCompany($item))->addLeads([ 12380925 ]); } // Пакетное сохранение компаний AmoAPI::saveObjects($companies); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Работа со сделками
Работа с заявками из неразобранного существенно отличается от работы со сделками. Для них используются специальные методы.
use AmoCRM\{AmoAPI, AmoLead, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Загрузка ВСЕХ сделок с возможностью фильтрации $generator = AmoAPI::getAllLeads([ 'responsible_user_id' => 12357492 ]); foreach ($generator as $items) { foreach ($items as $item) { print_r($item); } } // Загрузка сделок с возможностью фильтрации и постраничной выборки $items = AmoAPI::getLeads([ 'limit_rows' => 250, 'limit_offset' => 2000 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Создание новой сделки $lead1 = new AmoLead([ 'name' => 'Заказ № 964023', 'responsible_user_id' => 12358394, 'pipeline' => [ 'id' => 45232121 ], 'status_id' => 142, 'sale' => 15000 ]); // Установка дополнительных полей $lead1->setCustomFields([ '3434323' => 'Акционерное общество', '3434327' => [ 1121, 1122, 1123 ] ]); // Привязка контакта $lead1->addContacts(12375435); // Привязка компании $lead1->addCompany(12364643); // Установка элементов списка $lead1->setCatalogElements([ 93492 => [ 9898 => 10, 9899 => 5 ] ]); // Добавление тега $lead1->addTags('Акционер'); // Сохранение сделки и получение ее ID $leadId = $lead1->save(); // Обновление существующей компании и получение ответа сервера amoCRM $lead2 = new AmoLead([ 'id' => 123057838, 'sale' => 175000 ]); $response = $lead2->save($returnResponse = true); // Пакетное добавление и/или обновление сделок $items = AmoAPI::saveObjects([ $lead1, $lead2 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Заполнение модели сделки по ID $lead3 = new AmoLead(); $lead3->fillById(12328958); // Отвязка контакта от сделки $lead3->removeContacts(12345678); // Отвязка компании от сделки $lead3->removeCompany(12345671); // Получение параметров сделки из модели print_r($lead3->getParams()); // Получение дополнительных полей сделки по ID полей print_r($lead3->getCustomFields([ 123456, 123467, 2390423 ])); // Получение первого значения дополнительного поля сделки по ID поля print_r($lead3->getCustomFieldValueById(2390423)); // Получение всех значений дополнительного поля сделки по ID поля print_r($lead3->getCustomFieldValueById(2390423, $returnFirst = false)); // Получение всех ENUM дополнительного поля сделки по ID поля print_r($lead3->getCustomFieldValueById(2390423, $returnFirst = true, $returnValue = 'enum')); // ------------------------------------------------------------------------- $leads = AmoAPI::getLeads([ 'responsible_user_id' => 12358394 ]); // Пакетная привязка компании к сделкам $leads = []; foreach ($items as $item) { $leads[] = (new AmoLead($item))->addCompany(12380925); } // Пакетное сохранение сделок AmoAPI::saveObjects($leads); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Работа с событиями
use AmoCRM\{AmoAPI, AmoNote, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Загрузка ВСЕХ событий, привязанных к сделкам, с возможностью фильтрации $generator = AmoAPI::getAllNotes([ 'type' => 'lead', 'note_type' => AmoNote::COMMON_NOTETYPE ]); foreach ($generator as $items) { foreach ($items as $item) { print_r($item); } } // Загрузка событий, привязанных к контактам, с возможностью фильтрации и постраничной выборки $items = AmoAPI::getLeads([ 'type' => 'contact', 'limit_rows' => 250, 'limit_offset' => 2000 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Создание нового события типа "обычное примечание", привязанного к сделке $note = new AmoNote([ 'element_id' => 12328687, 'note_type' => AmoNote::COMMON_NOTETYPE, 'element_type' => AmoNOTE::LEAD_TYPE, 'text' => 'Текст примечания к сделке' ]); // Сохранение события и получение его ID $noteId = $note->save(); // Обновление существующего события $note2 = new AmoNote([ 'id' => 12300958, 'text' => 'Обновленный текст события' ]); // Заполнение модели события по ID и изменение текста события $note3 = new AmoNote(); $note3->fillById(12347842); $note3->text = 'Новый тест события'; // Получение параметров события из модели print_r($note3->getParams()); // Пакетное сохранение событий AmoAPI::saveObjects([ $note2, $note3 ]); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Работа с задачами
use AmoCRM\{AmoAPI, AmoTask, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Загрузка ВСЕХ задач, привязанных к сделкам, с возможностью фильтрации $generator = AmoAPI::getAllTasks([ 'type' => 'lead', 'filter' => [ 'task_type' => [ AmoTask::CALL_TASKTYPE, AmoTask::MAIL_TASKTYPE ] ] ]); foreach ($generator as $items) { foreach ($items as $item) { print_r($item); } } // Загрузка задач, с возможностью фильтрации и постраничной выборки $items = AmoAPI::getTasks([ 'responsible_user_id' => 12381202, 'limit_rows' => 100, 'limit_offset' => 800 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Создание новой задачи типа "написать письмо", привязанной к контакту $task = new AmoTask([ 'task_type' => AmoTASK::MAIL_TASKTYPE, 'element_type' => AmoTask::CONTACT_TYPE, 'element_id' => 12367433, 'text' => 'Необходимо написать письмо', 'complete_till_at' => 1508706000 ]); // Сохранение задачи и получение её ID $taskId = $task->save(); // Обновление существующей задачи $task2 = new AmoTask([ 'id' => 12311954, 'text' => 'Обновленный текст задачи' ]); // Привязка сделки к задаче по ID $task2->addLead(12389536); // Заполнение модели задачи по ID и изменение текста задачи $task3 = new AmoTask(); $task3->fillById(12327872); $task3->text = 'Новый тест события'; // Получение параметров задачи из модели print_r($task3->getParams()); // Пакетное сохранение задач AmoAPI::saveObjects([ $task2, $task3 ]); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Работа со списками (каталогами)
use AmoCRM\{AmoAPI, AmoCatalog, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Загрузка перечня списков с возможностью фильтрации $items = AmoAPI::getCatalogs(); foreach ($items as $item) { print_r($item); } // Создание нового списка $catalog = new AmoCatalog([ 'name' => 'Товары на складе' ]); // Сохранение списка и получение его ID $catalogId = $catalog->save(); // Обновление существующего списка $catalog2 = new AmoCatalog([ 'id' => 7185, 'name' => 'Не товары' ]); // Заполнение модели списка по ID и изменение названия списка $catalog3 = new AmoCatalog(); $catalog3->fillById(7187); $catalog3->name = 'Актуальные товары'; // Получение параметров списка из модели print_r($catalog3->getParams()); // Пакетное сохранение списков AmoAPI::saveObjects([ $catalog2, $catalog3 ]); // Пакетное удаление списков AmoAPI::deleteObjects([ $catalog2, $catalog3 ]); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Работа с элементами списков (каталогов)
use AmoCRM\{AmoAPI, AmoCatalogElement, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Загрузка ВСЕХ элементов заданного списка с возможностью фильтрации $generator = AmoAPI::getAllCatalogElements([ 'catalog_id' => 4422, 'term' => 'Маркер' ]); foreach ($generator as $items) { foreach ($items as $item) { print_r($item); } } // Загрузка элементов заданного списка с фильтрацией с постраничной выборкой $items = AmoAPI::getCatalogElements([ 'catalog_id' => 4422, 'term' => 'Фломастер', 'page' => 21 ]); foreach ($items as $item) { print_r($item); } // ------------------------------------------------------------------------- // Создание нового элемента каталога $element = new AmoCatalogElement([ 'catalog_id' => 4422, 'name' => 'Ручка гелевая' ]); // Установка дополнительных полей $element->setCustomFields([ '20423' => 'Артикул 14567323', '24233' => 120 ]); // Сохранение элемента списка и получение его ID $elementId = $element->save(); // Обновление существующего элемента списка $element2 = new AmoCatalogElement([ 'id' => 12312312, 'text' => 'Ручка перьевая' ]); // Заполнение модели элемента списка по ID и изменение имени элемента $element3 = new AmoCatalogElement(); $element3->fillById(12398096); $element3->name = 'Карандаш'; // Получение параметров элемента списка из модели print_r($element3->getParams()); // Пакетное сохранение элементов AmoAPI::saveObjects([ $element2, $element3 ]); // Пакетное удаление элементов AmoAPI::deleteObjects([ $element2, $element3 ]); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Работа с webhooks
use AmoCRM\{AmoAPI, AmoAPIException}; try { // Авторизация $subdomain = 'subdomain'; AmoAPI::oAuth2($subdomain); // Получаем список установленных webhooks $webhooks = AmoAPI::getWebhooks(); print_r($webhooks); // Добавляем webhook AmoAPI::addWebhooks([ 'url' => 'https://example.com/webhook/', 'events' => [ 'add_lead' ] ]); // Удаляем webhook AmoAPI::deleteWebhooks([ 'url' => 'https://example.com/webhook/', 'events' => [ 'add_lead' ] ]); // Добавляем несколько webhooks AmoAPI::addWebhooks([ [ 'url' => 'https://example1.com/webhook/', 'events' => [ 'add_lead' ] ], [ 'url' => 'https://example2.com/webhook/', 'events' => [ 'update_lead' ] ] ]); // Удаляем несколько webhooks AmoAPI::deleteWebhooks([ [ 'url' => 'https://example1.com/webhook/', 'events' => [ 'add_lead' ] ], [ 'url' => 'https://example2.com/webhook/', 'events' => [ 'update_lead' ] ] ]); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Работа с заявками из неразобранного
Работа с заявками из неразобранного существенно отличается от работы с другими сущностями amoCRM.
Согласно официальной документации:
Изначально неразобранное было в отдельном хранилище и являлось отдельной сущностью именно поэтому до сих пор в интерфейсах amoCRM и в API есть особенности которые отличают поведение сделки в статусе Неразобранное от сделок в других статусах.
Пример работы с заявками из неразобранного при добавлении из веб-формы.
use AmoCRM\{AmoAPI, AmoLead, AmoContact, AmoIncomingLeadForm, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); // Создаем новую заявку в неразобранном при добавлении из веб-формы $incomingLead = new AmoIncomingLeadForm(); // Устанавливаем обязательные параметры $incomingLead->setIncomingLeadInfo([ 'form_id' => 1, 'form_page' => 'https://www.example.com', 'form_name' => 'Home page form' ]); // Добавляем параметры сделки $lead = new AmoLead([ 'name' => 'Новая заявка с сайта' ]); $lead->setCustomFields([ 25475362 => '#1543252' ]); $incomingLead->addIncomingLead($lead); // Добавляем параметры контакта $contact = new AmoContact([ 'name' => 'Ганс-Дитрих Геншер' ]); $contact->setCustomFields([ 255114 => [[ 'value' => '+10349654820', 'enum' => 'WORK' ]], 255116 => [[ 'value' => 'hans@example.com', 'enum' => 'WORK' ]] ]); $incomingLead->addIncomingContact($contact); // Добавляем параметры компании $incomingLead->addIncomingCompany([ 'name' => 'Freie Demokratische Partei' ]); // Сохраняем заявку AmoAPI::saveIncomingObjects($incomingLead); // ------------------------------------------------------------------------ // Получаем заявку из неразобранного по UID $uid = 'f03c796fb5455667e648dd0ec9755fc9680bc3775ac76a540753d249d455'; $incomingLead2 = new AmoIncomingLeadForm(); $incomingLead2->fillByUid($uid); print_r($incomingLead2->getParams()); // Загрузка ВСЕХ заявок из неразобранного с фильтрацией по категории $generator = AmoAPI::getAllIncomingLeads([ 'categories' => [ 'forms' ] ]); foreach ($generator as $items) { foreach ($items as $item) { print_r($item); } } // ------------------------------------------------------------------------ // Принимаем заявки из неразобранного AmoAPI::acceptIncomingLeads([ 'accept' => [ 'f03c796fb5455667e648dd0ec9755fc9680bc3775ac76a540753d249d455', 'a12c723fb54556676e6487d0e89795fc9080bc3975ac86a548752302d478', ], 'user_id' => 13752426, 'status_id' => 142 ]); // Отклоняем заявки из неразобранного AmoAPI::declineIncomingLeads([ 'decline' => [ 'e21c796dfb5sd566de648ccb80ec546a4d25e4baecbd343actf0b3ed4363c4' ], 'user_id' => 13752426 ]); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Поддержка AJAX-запросов к frontend-методам
Метод \AmoCRM\AmoAPI::request()
позволяет выполнять AJAX-запросы к frontend-методам.
use AmoCRM\{AmoAPI, AmoAPIException}; try { // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); $params = [ 'filter' => [ 'cf'=> [ '681165'=> [ 'from' => '30.03.2022', 'to' => '30.03.2022' ] ], ], 'useFilter' => 'y', 'element_type' => 1, 'json' => 1, 'page' => 1 ]; $data = AmoAPI::request('/ajax/contacts/list', 'AJAX', $params); print_r($data); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Пример ответа (фрагмент):
{
"response": {
"url": "\/contacts\/list\/contacts\/",
"items": [
{
"id": 68207643,
"tags": {
"items": []
},
"url": "\/contacts\/detail\/68207643",
"element_type": 1,
"entity": "contact",
"is_deleted": false,
"rights": {
"contacts": {
"edit": true
},
"companies": {
"edit": true
}
},
"class_name": "",
"name": {
"text": "Звонок от 79521111111",
"url": "\/contacts\/detail\/68207643"
},
"company_name": {
"name": "",
"url": "#"
},
"manager": "Иван Петров",
"date_create": "Сегодня 11:30",
"creator": "Робот",
"date_modified": "Сегодня 11:31",
"modified_by": "Робот",
"date_of_nearest_task": {
"date": 1652641199,
"failed": false
},
"custom_fields": [
{
"id": "72797",
"name": "Телефон",
"values": [
{
"enum": "112761",
"value": "+7 952 111-11-11"
}
]
}
],
...
Работа с несколькими поддоменами
use AmoCRM\{AmoAPI, AmoCompany, AmoAPIException}; try { // Авторизация в поддомене 1 // ... AmoAPI::oAuth2($subdomain1, $clientId1, $clientSecret1, $redirectUri1, $authCode1); // Авторизация в поддомене 2 // ... AmoAPI::oAuth2($subdomain2, $clientId2, $clientSecret2, $redirectUri2, $authCode2); // Загрузка компаний из поддомена 1 $items1 = AmoAPI::getCompanies([ 'responsible_user_id' => 12357492 ], $subdomain1); // Загрузка всех компаний из поддомена 2 $generator2 = AmoAPI::getAllCompanies([ 'query' => 'OOO' ], $subdomain2); // Создание новой компании для поддомена 1 $company1 = new AmoCompany([ 'name' => 'ООО Абракадабра', ], $subdomain1); // Обновление существующей компании для поддомена 1 $company2 = new AmoCompany([], $subdomain1); $company2->fillById(12389423); $company2->name = 'OOO Розенталь'; // Пакетное сохранение компаний для поддомена 1 AmoAPI::saveObjects([ $company1, $company2 ], $subomain1); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
Отладка и логирование
use AmoCRM\{AmoAPI, AmoAPIDebugLogger, AmoAPIException}; try { // Включение вывода запросов/ответов к API в STDOUT AmoAPI::$debug = true; // Включение логирования запросов/ответов к API в файл AmoAPI::$debugLogger = new AmoAPIDebugLogger($logFile = 'logs/debug_amocrm_api.log'); // Авторизация $subdomain = 'testsubdomain'; AmoAPI::oAuth2($subdomain); } catch (AmoAPIException $e) { printf('Ошибка (%d): %s' . PHP_EOL, $e->getCode(), $e->getMessage()); }
UML-диаграмма классов
Автор
© 2019-2021 andrey-tech
Лицензия
Данная библиотека распространяется на условиях лицензии MIT.