shadoll / anemone
Library for Kommo (AmoCRM)
Requires
- php: >=7.2
- ext-json: *
- ext-zip: *
- graylog2/gelf-php: ^1.6
- guzzlehttp/guzzle: ^6.4|^7.0
- illuminate/support: >=5.8
- monolog/monolog: >=1.0
- psr/log: ^1.0|^2.0|^3.0
- vlucas/phpdotenv: ^4.0|^5.1
Requires (Dev)
- phpstan/phpstan: ^0.12
- phpstan/phpstan-phpunit: ^0.12
- phpstan/phpstan-strict-rules: ^0.12
- phpunit/phpunit: ^9
- sebastian/phpcpd: ^6.0
- dev-master
- v4.15.0
- v4.14.1
- v4.14.0
- v4.13.7
- v4.13.6
- v4.13.5
- v4.13.4
- v4.13.3
- v4.13.2
- v4.13.1
- v4.13.0
- v4.12.1
- v4.12.0
- v4.11.0
- v4.10.0
- v4.9.0
- v4.8.4
- v4.8.3
- v4.8.2
- v4.8.1
- v4.8.0
- v4.7.1
- v4.7.0
- v4.6.6
- v4.6.5
- v4.6.3
- v4.6.2
- v4.6.0
- v4.5.7
- v4.5.6
- v4.5.4
- v4.5.2
- v4.5.1
- v4.5.0
- v4.4.3
- v4.4.2
- v4.4.1
- v4.4.0
- v4.3.14
- v4.3.13
- v4.3.12
- v4.3.8
- v4.3.7
- v4.3.6
- v4.3.5
- v4.3.4
- v4.3.3
- v4.3.1
- v4.3.0
- v4.2.3
- v4.2.2
- v4.2.1
- v4.2.0
- v4.1.3
- v4.1.2
- v4.1.1
- v4.1.0
- v4.0.6
- v4.0.5
- 4.0.4
- v4.0.3
- v4.0.2
- v4.0.1
- v4.0.0
- v2.4.0
- v2.3.0
- v2.2.2
- v2.2.1
- v2.2.0
- v2.1.1
- v2.1.0
- v2.0.0
- v1.12.0
- v1.11.0
- v1.10.0
- v1.9.0
- v1.8.0
- v1.7.2-patch
- v1.7.1
- v1.7.0
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.15
- v1.4.14
- v1.4.13
- v1.4.12
- v1.4.11
- v1.4.10
- v1.4.9
- v1.4.8
- v1.4.7
- v1.4.6
- v1.4.5
- v1.4.4
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.1
- v1.3.0
- v1.2.0
- v1.1.0
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v0.4.0
- v0.3.0
- v0.2.0
- v0.1.2
- v0.1.1
- v0.1.0
- dev-old
- dev-fixed_v2
This package is auto-updated.
Last update: 2024-11-11 21:51:02 UTC
README
Library for AmoCRM
Install
composer require shadoll/anemone
Поддерживает множественную авторизацию (работу с более чем 1 аккаунт).
Настройка
Библиотека работает с настройками по умолчанию. Вы можете их переопределить через переменные окружения. Описание переменных окружения:
- logging:
A_LOG_POWER
- boolean, включение/отключение логирования запросов (по умолчаниюtrue
).A_LOG_DRIVER
- enum in 'daily' or 'stack', включение ротации логов по днях или в один файл (по умолчаниюdaily
).A_LOG_PATH
- string, путь хранения логов (по умолчаниюstorage/logs/amo
).A_LOG_DAYS
- integer, количество файлов для ротвций логов (по умолчанию14
).A_LOG_CROP
- boolean, ограничивать развер строк записываемих в лог (по умолчаниюtrue
).
- cookies:
A_COOKIES_PATH
- string, путь хранения cookies (по умолчаниюstorage/cookies/amo
).
- cache:
A_CACHE_POWER
- boolean, включение/отключение кеша (по умолчаниюtrue
).A_CACHE_PATH
- string, путь хранения cache (по умолчаниюstorage/cache/amo
).A_CACHE_T_OTHER
- integer, время кеширования (в сек) для ДРУГОЕ (по умолчанию300
).A_CACHE_T_ACCOUNT
- integer, время кеширования (в сек) для АККАУНТ (по умолчанию600
).A_CACHE_T_LEAD
- integer, время кеширования (в сек) для СДЕЛОК (по умолчанию60
).A_CACHE_T_CUSTOMER
- integer, время кеширования (в сек) для ПОКУПАТЕЛЯ (по умолчанию60
).A_CACHE_T_CONTACT
- integer, время кеширования (в сек) для КОНТАКТА (по умолчанию60
).A_CACHE_T_COMPANY
- integer, время кеширования (в сек) для КОМПАНИИ (по умолчанию60
).A_CACHE_T_TASK
- integer, время кеширования (в сек) для ЗАДАЧ (по умолчанию60
).
auth (
2020-03-14
)A_AUTH_CONNECTOR
- string, класс коннектора для oauth2 обновлений токенов (по умолчанию\Anemone\Core\Auth\Connectors\JsonConnector
) добавить свои - реализуя интерфейс\Anemone\Contracts\BeAuthConnector
.A_AUTH_PATH
- string, директория для хранения файла коннектора (по умолчаниюstorage/oauth/amo
).
(Документация была переделана с старой версии anemone
- соответственно
возможно где-то остались незамечены старые данные при действиях с тем
или инными методами. Для болей точного понимания - необходимо
ознакомится с официальной документацией амо апи и все станет на места.
правки приветствуются!)
Client
Для начала работы с библиотекой - необходимо создать (зарегистрировать) Клиент пользователя:
OAuth2 Client (новый 2020-03-14)
Добавлен новый метод авторизации. Для пользователя библиотеки кроме входных параметров разницы от старого клиента нет. Все версии при инициализации, коллекции клиентов, добавление, удаление клиентов ... так же как и в старом клиенте.
Обязательно при использовании авторизации oauth2 достаточно указать лишь domain
и access_token
.
Но при этом после просрачивания токена (время жизни одни сутки (2020-03-14)) - любой запрос будет сопровождаться
выбросом исключения.
$client = new \Anemone\Client([
"domain" => "jarvis.amocrm.ru",
"access_token" => "access_token...",
]);
Как описано выше в параметрах .env
пункта 5 - есть коннекторы (пока 1 для json) с помощью которых можно
обновлять состояния токенов доступа и обновления.
Чтобы запускались механизмы обновления и сохранения токенов в автоматическом режиме - необходимо при инициализации
клиента добавить больше параметров:
$client = new \Anemone\Client(
[
"domain" => "jarvis.amocrm.ru",
"token_type" => 'Bearer', // optional
"access_token" => "access_token...",
"refresh_token" => "refresh_token...",
"client_secret" => 'f6oD33Bjxhl0ostKULaME7eUQJXrhBMp5v66W5M9nMkki1S2lXVDsLRUaLaBQEcY',
"client_id" => 'c4c8e476-d280-47d4-b206-b5cc36ba772f',
'redirect_uri' => 'https://redirect.server.com',
]
);
название параметров говорят сами за себя (обьяснению не подлежит, тем кто читал амо документацию).
Client по api key (старый)
$client = new \Anemone\Client([
"domain" => "jarvis.amocrm.ru",
"login" => "jarvis@google.com",
"secret_key" => "jarvis_api_key",
]);
Можно инициализировать несколько клиентов одновременно передав коллекцию авторизационных данных:
$collection = new \Illuminate\Support\Collection([
[
"domain" => "jarvis.amocrm.ru",
"login" => "jarvis@google.com",
"secret_key" => "jarvis_api_key",
],
[
"domain" => "jarvis2.amocrm.ru",
"login" => "jarvis2@google.com",
"secret_key" => "jarvis2_api_key",
],
]);
\Anemone\Client::initClients($collection);
// в любом месте можете получить Клиент по domain
$client = \Anemone\Client::getInstance('jarvis2.amocrm.ru');
// коллекцию Клиентов по domain в массиве
$clients = \Anemone\Client::getInstance(['jarvis2.amocrm.ru', 'jarvis.amocrm.ru']);
// коллекцию всех доступных Клиентов
$clients = \Anemone\Client::getInstance();
При создании обьекта Клиента (new \Anemone\Client(...)
) - он не будет доступен в статическом методе
getInstance
, по необходимости Клиент или коллекцию Клиентов можно будет добавить:
$client = new \Anemone\Client([
"domain" => "jarvis.amocrm.ru",
"login" => "jarvis@google.com",
"secret_key" => "jarvis_api_key",
]);
$client2 = new \Anemone\Client([
"domain" => "jarvis2.amocrm.ru",
"login" => "jarvis2@google.com",
"secret_key" => "jarvis2_api_key",
]);
$collection = new \Illuminate\Support\Collection([
$client,
$client2,
]);
\Anemone\Client::addInstance($collection);
// или
\Anemone\Client::addInstance($client);
Сам Клиент не много чего умеет, необходимо делегировать его определенному Инстансу. Пример:
$client->account
- возвращает\Anemone\Models\Instances\AccountInstance
для работы с аккаунтом клиента.$client->leads
- возвращает\Anemone\Models\Instances\LeadsInstance
для работы с сделками клиента.$client->customers
- возвращает\Anemone\Models\Instances\CustomersInstance
для работы с покупателями клиента.$client->contacts
- возвращает\Anemone\Models\Instances\ContactsInstance
для работы с контактами клиента.$client->companies
- возвращает\Anemone\Models\Instances\CompaniesInstance
для работы с компаниями клиента.$client->tasks
- возвращает\Anemone\Models\Instances\TasksInstance
для работы с задачами клиента.
и т.д. ...
Инстансы, ModelInstance
Любой Инстанс - обьект интерфейса \Anemone\Contracts\BeInstanceModel
, не является моделью, это
больше средство для работы с моделями, коллекциями моделей, (прослойка между моделью и сырыми данными
с сервера).
Все Инстансы имеют общего предка \Anemone\Models\Instances\ModelInstance
.
Инстанс может получать данные (с учетом фильтров), создавать, обновлять, удалять данные.
Работа с коллекциями
В библиотеке почти все массивы данных работают на Коллекциях \Anemone\Core\Collection\Collection
.
Коллекция наследует \Illuminate\Support\Collection
соответственно имеет в своем арсенале большой
набор методов для обхода, изменений, фильтраций, трансформаций коллекции.
illuminate/support
Модели
Практически все данные являются обьектами. В зависимости от реализации определенного интерфейса
имеют свои свойства (\Anemone\Contracts\BeBaseModel
, \Anemone\Contracts\BeStaticallyModel
,
\Anemone\Contracts\BeModel
, \Anemone\Contracts\BeCustomField
..)
Основные модели могут напрямую работать со своим Инстансом, если его (инстанс) делегировать внутрь модели.
(через конструктор или метод setInstance
) .
Все модели и коллекции моделей серриализуеми, что позволяет легко просмотреть данные выведя их в окно, или отдать коллекцию Frontend приложению.
Работа с Аккаунтом и AccountInstance
\Anemone\Models\Instances\AccountInstance
Для получения модели аккаунта Клиента:
/**
* @var \Anemone\Models\Instances\AccountInstance $accountInstance
* @var \Anemone\Models\Account $account
*/
$accountInstance = $client->account;
$account = $accountInstance->get();
Работа с LeadsInstance, CustomersInstance, ContactsInstance, CompaniesInstance, TasksInstance
Примечание: Некоторые фильтра не работают в связи перехода на v4. После тестирования фильтров компанией АМО СРМ и обновления документации - фильтра будут добавлены (обещают достаточно хорошие фильтра doc)
Для получения моделей (результат будет коллекция моделей \Anemone\Core\Collection\Collection
):
// LEADS
/**
* @var \Anemone\Models\Instances\LeadsInstance $leadInstance
* @var \Anemone\Core\Collection\Collection $leads
*/
$leadInstance = $client->leads;
// получить все сделки (возвращается коллекция моделей)
$leads = $leadInstance->get();
// получить все сделки с условием (возвращается коллекция моделей, даже если там одна модель, или пустая)
$leads = $leadInstance->find(12345)->get();
$leads = $leadInstance->find([12345, 54321])->get();
$leads = $leadInstance
->query('search')
->responsibleUser([111111, 222222]) // не работает (в ожидании фильров)
->with(['loss_reason_name', 'is_price_modified_by_robot'])
->status(55555)
->dateModify('13.09.2019', '14.09.2019')
->active(false)
->unTasks()
->limit(40)
->get();
$leads = $leadInstance
->query('search')
->responsibleUser(111111)
->with('loss_reason_name')
->status([55555, 666666])
->dateCreate('12.09.2019', '13.09.2019')
->active(true)
->noTasks()
->limit(100)
->page(2)
->get();
// CUSTOMERS
/**
* @var \Anemone\Models\Instances\CustomersInstance $customerInstance
* @var \Anemone\Core\Collection\Collection $customers
*/
$customerInstance = $client->customers;
// получить все покупатели (возвращается коллекция моделей)
$customers = $customerInstance->get();
// получить все покупатели с условием (возвращается коллекция моделей, даже если там одна модель, или пустая)
$customers = $customerInstance->find(12345)->get();
$customers = $customerInstance->find([12345, 54321])->get();
$customers = $customerInstance
->responsibleUser([111111, 222222])
->dateModify('13.09.2019', '14.09.2019')
->limit(40)
->get();
$customers = $customerInstance
->responsibleUser(111111)
->dateCreate('12.09.2019', '13.09.2019')
->limit(100)
->get();
// CONTACTS
/**
* @var \Anemone\Models\Instances\ContactsInstance $contactInstance
* @var \Anemone\Core\Collection\Collection $contacts
*/
$contactInstance = $client->contacts;
// получить все контакты (возвращается коллекция моделей)
$contacts = $contactInstance->get();
// получить все контакты с условием (возвращается коллекция моделей, даже если там одна модель, или пустая)
$contacts = $contactInstance->find(12345)->get();
$contacts = $contactInstance->find([12345, 54321])->get();
// переход на другую версию
$contactInstance->setVersion('2');
$contacts = $contactInstance
->query('search')
->responsibleUser([111111, 222222])
->limit(40)
->get();
// включаем автоматическую адаптацию под версии
$contactInstance->setFixedVersion(false);
$contacts = $contactInstance
->query('search')
->responsibleUser(111111)
->limit(100)
->get();
// COMPANIES
/**
* @var \Anemone\Models\Instances\CompaniesInstance $companyInstance
* @var \Anemone\Core\Collection\Collection $companies
*/
$companyInstance = $client->companies;
// получить все компании (возвращается коллекция моделей)
$companies = $companyInstance->get();
// получить все компании с условием (возвращается коллекция моделей, даже если там одна модель, или пустая)
$companies = $companyInstance->find(12345)->get();
$companies = $companyInstance->find([12345, 54321])->get();
$companies = $companyInstance
->query('search')
->responsibleUser([111111, 222222])
->limit(40)
->get();
$companies = $companyInstance
->query('search')
->responsibleUser(111111)
->limit(100)
->get();
// TASKS
/**
* @var \Anemone\Models\Instances\TasksInstance $taskInstance
* @var \Anemone\Core\Collection\Collection $tasks
*/
$taskInstance = $client->tasks;
// получить все задачи (возвращается коллекция моделей)
$tasks = $taskInstance->get();
// получить все задачи с условием (возвращается коллекция моделей, даже если там одна модель, или пустая)
$tasks = $taskInstance->find(12345)->get();
$tasks = $taskInstance->find([12345, 54321])->get();
$tasks = $leadInstance
->responsibleUser([111111, 222222])
->dateModify('13.09.2019', '14.09.2019')
->limit(40)
->pipe([
[
'pipeline' => 12345,
'statuses' => [11111, 22222, 33333],
],
[
'pipeline' => 54321,
'statuses' => [44444, 55555, 66666],
],
])
->get();
$tasks = $leadInstance
->responsibleUser(111111)
->dateCreate('12.09.2019', '13.09.2019')
->limit(100)
->withStatus(true)
->createdBy([1234567, 543212])
->taskType([1, 2])
->forTypeEntity('lead')
->forEntityID(98765)
->get();
Поиск по телефону и email (add 11.12.2019) (временно @deprecated
)
Поиск доступен только для контактов и компаний
// CONTACTS
/**
* @var \Anemone\Core\Collection\Collection $contacts
*/
$contacts = $client->contacts->findByPhone('0988888888');
$contacts = $client->contacts->findByEmail('jarvis@google.com');
/**
* @var \Anemone\Core\Collection\Collection $companies
*/
$companies = $client->companies->findByPhone('0988888888');
$companies = $client->companies->findByEmail('jarvis@google.com');
Создать любую базовую модель (кроме аккаунта) можно 2 способами:
- Через соответствующий Инстанс,
- Через саму модель (по факту это так же через Инстанс ток в обвертке)
Все модели перед созданием (даже одну) нужно поместить в коллекцию (обязательно которая реализует
интерфейс \Anemone\Contracts\BeCollection
), для этого уже есть \Anemone\Core\Collection\Collection
:
// Создание через инстанс
/**
* @var \Anemone\Models\Instances\LeadsInstance $leadInstance
*/
$leadInstance = $client->leads;
// store lead
$lead = new \Anemone\Models\Lead();
$lead->name = 'Lead stored by Jarvis';
$lead->responsible_user_id = 12345;
// ...
// коллекция сделок
$leadsCollection = new \Anemone\Core\Collection\Collection([
new \Anemone\Models\Lead(null, [
'name' => 'Lead stored by other Jarvis',
]),
$lead,
]);
// создание
$status = $leadInstance->save($leadsCollection);
// Остальные сущности (customer, contact, company, task) создаются по аналогии
// Создание из модели
/**
* @var \Anemone\Models\Instances\LeadsInstance $leadInstance
*/
$leadInstance = $client->leads;
// store lead
$lead = new \Anemone\Models\Lead($leadInstance); // <- при создании через модель инстанс передается в конструктор
// или можно будет позже (но обязательно) через метод
$lead->setInstance($leadInstance);
$lead->name = 'Lead stored by Jarvis';
$lead->responsible_user_id = 12345;
$lead2->attachTags(new Tag(['name' => 'tagByJarvis']));
$lead2->detachTags('tagNotJarvis');
// ...
$lead2 = new \Anemone\Models\Lead($leadInstance, [
'name' => 'Lead stored by other Jarvis',
]);
$lead2->attachTags(new \Anemone\Core\Collection\Collection([
new Tag(['name' => 'tagByJarvis']),
new Tag(['name' => 'tagNotJarvis']),
]));
$lead2->detachTags(['tagNotJarvis', 'tagByJarvis']);
// ...
// создание
$lead->save();
$lead2->save();
// Остальные сущности (customer, contact, company, task) создаются по аналогии
Обновить любую базовую модель (кроме аккаунта) можно 2 способами (если вы получили коллекцию моделей с сервера - нужный Инстанс уже внедрен, из кеша так же внедряется):
- Через соответствующий Инстанс,
- Через саму модель (по факту это так же через Инстанс ток в обвертке)
Все модели перед обновлением (даже одну) нужно поместить в коллекцию (обязательно которая реализует
интерфейс \Anemone\Contracts\BeCollection
), для этого уже есть \Anemone\Core\Collection\Collection
:
// Обновление через инстанс
/**
* @var \Anemone\Models\Instances\LeadsInstance $leadInstance
*/
$leadInstance = $client->leads;
// получим список
$collect = $leadInstance->find([12345, 67890, 09876, 54321])->get();
$collectFiltered = $collect->filter(function($item) {
return $item->id > 22222;
});
$collectFiltered->each(function($item) {
$item->name = 'Name change by Jarvis';
});
// обновление
$status = $leadInstance->save($collectFiltered);
// Остальные сущности (customer, contact, company, task) обновляются по аналогии
// Обновление из модели
/**
* @var \Anemone\Models\Instances\LeadsInstance $leadInstance
*/
$leadInstance = $client->leads;
// получим список
$collect = $leadInstance->find([12345, 67890, 09876, 54321])->get();
$collectFiltered = $collect->filter(function($item) {
return $item->id > 22222;
});
// обновление
$collectFiltered->each(function($item) {
$item->name = 'Name change by Jarvis';
$item->save();
});
// Остальные сущности (customer, contact, company, task) обновляются по аналогии
Deprecated
Удалить любую базовую модель (кроме аккаунта) можно 2 способами (если вы получили коллекцию моделей с сервера - нужный Инстанс уже внедрен, из кеша так же внедряется):
- Через соответствующий Инстанс,
- Через саму модель (по факту это так же через Инстанс ток в обвертке)
Как описано выше удалить модель можно только в версии _
.
Все модели перед удалением (даже одну) нужно поместить в коллекцию (обязательно которая реализует
интерфейс \Anemone\Contracts\BeCollection
), для этого уже есть \Anemone\Core\Collection\Collection
:
// Удаление через инстанс
/**
* @var \Anemone\Models\Instances\LeadsInstance $leadInstance
*/
$leadInstance = $client->leads;
// получим список
$collect = $leadInstance->find([12345, 67890, 09876, 54321])->get();
$collectFiltered = $collect->filter(function($item) {
return $item->id > 22222;
});
$collectFiltered->each(function($item) {
$item->name = 'Name change by Jarvis';
});
// переключаемся на версию _
$leadInstance->setVersion('_');
// удаление
$status = $leadInstance->delete($collectFiltered);
// Остальные сущности (customer, contact, company, task) удаляются по аналогии
// Удаление из модели
/**
* @var \Anemone\Models\Instances\LeadsInstance $leadInstance
*/
$leadInstance = $client->leads;
// получим список
$collect = $leadInstance->find([12345, 67890, 09876, 54321])->get();
$collectFiltered = $collect->filter(function($item) {
return $item->id > 22222;
});
// переключаемся на версию _
$leadInstance->setVersion('_');
// удаление
$collectFiltered->each(function($item) use ($leadInstance) {
$item->name = 'Name change by Jarvis';
$item->setInstance($leadInstance);
$item->delete();
});
// Остальные сущности (customer, contact, company, task) удаляются по аналогии
Получить количество сущностей (add: 24.10.2019)
Следующие сущности поддерживают получение числа количества сущностей (в некоторых случаях поддерживается фильтр):
\Anemone\Models\Instances\LeadsInstance
\Anemone\Models\Instances\CustomersInstance
\Anemone\Models\Instances\ContactsInstance
\Anemone\Models\Instances\CompaniesInstance
\Anemone\Models\Instances\TasksInstance
$count = $client->leads->count();
$count = $client->customers->count();
$count = $client->contacts->count();
$count = $client->companies->count();
$count = $client->tasks->count();
// пример по с фильтром
$count = $client->leads->find('копия')->count();
поиск производится с автоматическим переключением на версию _
(вручную переключать
надобность отсутствует), после получения количества - версия возвращается в ту которая
была до запроса количества (автоматически).
По этому фильтра будут работать только те которые поддерживает версия _
.
Работа с примечаниями (События) (add: 16.10.2019)
Есть 2 способа работы с примечаниями:
- через чужие инстансы (
\Anemone\Models\Instances\LeadsInstance
, ...) модели которых поддерживают Примечания -СДЕЛКИ
,ПОКУПАТЕЛИ
,КОНТАКТЫ
,КОМПАНИИ
,ЗАДАЧИ
. В этом случае вы будете работать с примечаниями в рамках всех Сделок, Компаний, .... - через конкретную модель (
\Anemone\Models\Lead
, ...) которая поддерживает примечания (см. п.1). В этом случае вы будете работать с примечаниями конкретной сущности (но вы можете это поведение изменить).
Получение примечаний (список):
/** Список всех примечаниий всех сделок
* @var \Anemone\Core\Collection\Collection $collection
* */
$collection = $client->leads->notes()->get();
// то же с фильтрацией
$collection = $client->leads->notes()->entityID(106727)->noteType(4)->limit(10, 50)->get();
// список для конкретной модели
/**
* @var \Anemone\Models\Lead $lead
*/
$lead = $client->leads->get()->first();
$collection = $lead->notes()->get();
// фильтрацию также можно добавить (метод entityID(__id__) сменить id модели)
Создание примечаний:
// инициализируем модель примечания
$note1 = new \Anemone\Models\Note([
'params' => [
'text' => 'notice for Jarvis',
],
'element_id' => 106727,
'note_type' => 'invoice_paid',
]);
$note2 = new \Anemone\Models\Note([
'params' => [
'text' => 'notice for Google',
],
'element_id' => 106733,
'note_type' => 'invoice_paid',
]);
$collect1 = new \Anemone\Core\Collection\Collection([
$note1,
$note2,
]);
// store
$status = $client->leads->notes()->save($collect1);
// для конкретной модели
// инициализируем модель примечания (element_id тут не обязателен)
$note3 = new \Anemone\Models\Note([
'params' => [
'text' => 'notice for Jarvis',
],
'note_type' => 'invoice_paid',
]);
$note4 = new \Anemone\Models\Note([
'params' => [
'text' => 'notice for Google',
],
'note_type' => 'invoice_paid',
]);
$collect2 = new \Anemone\Core\Collection\Collection([
$note3,
$note4,
]);
/**
* @var \Anemone\Models\Lead $lead
*/
$lead = $client->leads->get()->first();
$status = $lead->notes()->save($collect2);
Обновление примечаний:
// получить все
$collect = $client->leads->notes()->noteType(4)->get();
$collect->each(function(\Anemone\Models\Note $item) {
$item->setText($item->getText() . ' (updated)');
});
// update
$status = $client->leads->notes()->save($collect);
// для конкретной модели
/**
* @var \Anemone\Models\Lead $lead
*/
$lead = $client->leads->get()->first();
$collect2 = $lead->notes()->noteType(13)->get();
$collect2->each(function(\Anemone\Models\Note $item) {
// any actions
});
$status = $lead->notes()->save($collect2);
// можно совмещать обновление и создание примечаний (как и в любой другой модели)
$collect3 = $client->leads->notes()->noteType('invoice_paid')->get();
$collect3->each(function(\Anemone\Models\Note $item) {
// any actions
});
$collect3->add(
new \Anemone\Models\Note([
'params' => [
'text' => 'notice for Google',
],
'element_id' => 106733,
'note_type' => 'invoice_paid',
])
);
// update and store
$status = $client->leads->notes()->save($collect3);
Работа с Неразобранное (31.10.2019)
Для работы с Неразобранное есть инстанс \Anemone\Models\Instances\IncomingLeadsInstance
.
Возможности:
- Получить список всех Неразобранное (с необходимыми фильтрами)
- Получить Summary Неразобранное
- Создать Неразобранное (типа
sip
, иform
) - Принятие неразобранных заявок
- Отклонение неразобранных заявок
Получить список всех Неразобранное
/** Список всех Неразобранное
* @var \Anemone\Core\Collection\Collection $collection
* */
$collection = $client->incomingLeads->get();
/** Список всех Неразобранное с фильтров выборки
* @var \Anemone\Core\Collection\Collection $collection
* */
$collection = $client->incomingLeads->categories(['sip', 'mail'])->limit(250)->get();
Получить Summary Неразобранное
/** Summary Неразобранное
* @var array $data
* */
$data = $client->incomingLeads->summary();
/** Summary Неразобранное с периодом
* @var array $data
* */
$data = $client->incomingLeads->summary(1572514534, 1572522193);
Создать Неразобранное (можно через Инстанс или через модель \Anemone\Models\IncomingLead
)
/** Создать Неразобранное через Инстанс
* @var array $data
* */
$IL1 = new \Anemone\Models\IncomingLead($client->incomingLeads, [
'source_name' => 'souu',
'source_uid' => 'source_uidsource_uid',
'metadata' => [
'form_name' => 'form_name',
'form_id' => 'form_id',
'form_page' => 'form_page',
'ip' => '127.0.0.1',
'form_sent_at' => time(),
]
]);
$IL1->created_at = 1455564344;
$IL1->metadata = [
'form_id' => 654321,
'form_page' => 'link_to_two',
];
$IL2 = clone $IL1;
$IL2->metadata = [
'form_id' => 234567,
'form_page' => 'super link',
];
$ILCall = new \Anemone\Models\IncomingLead($client->incomingLeads);
$ILCall->metadata = [
'to' => 123456,
'from' => '0989898999',
'date_call' => 1572514534,
'service_code' => 'binotel',
];
$collect = new \Anemone\Core\Collection\Collection([
$IL1,
$IL2,
$ILCall,
]);
/** Создание
* @var bool $status
* */
$status = $client->incomingLeads->save($collect);
// Создание через модель
$IL3 = new \Anemone\Models\IncomingLead($client->incomingLeads, [
'metadata' => [
'form_id' => 123456,
'form_page' => 'link_to_one',
],
]);
/** Создание
* @var bool $status
* */
$status = $IL3->save();
Принятие неразобранных заявок (через Инстанс (массово) или модель)
/** Список всех Неразобранное с фильтров выборки
* @var \Anemone\Core\Collection\Collection $collection
* */
$collection = $client->incomingLeads->categories(['form'])->get();
/**
* @var array $data результат
* */
// Принятие Через модель
$data = $collection->first()->accept();
// установить пользователя который принял
$data = $collection->first()->accept(12345);
// установить этап воронки
$data = $collection->first()->accept(null, 77665544);
// установить пользователя который принял и этап воронки
$data = $collection->first()->accept(12345, 77665544);
/**
* @var \Anemone\Core\Collection\Collection $data коллекция результатов
* */
// через инстанс
$data = $client->incomingLeads->accept($collection);
// установить пользователя который принял
$data = $client->incomingLeads->accept($collection, 12345);
// установить этап воронки
$data = $client->incomingLeads->accept($collection, null, 77665544);
// установить пользователя который принял и этап воронки
$data = $client->incomingLeads->accept($collection, 12345, 77665544);
Отклонение неразобранных заявок (через Инстанс (массово) или модель)
/** Список всех Неразобранное с фильтров выборки
* @var \Anemone\Core\Collection\Collection $collection
* */
$collection = $client->incomingLeads->categories(['sip'])->get();
/**
* @var array $data результат
* */
// Отклонение Через модель
$data = $collection->first()->decline();
// установить пользователя который отклонил
$data = $collection->first()->decline(12345);
/**
* @var \Anemone\Core\Collection\Collection $data коллекция результатов
* */
// Отклонение через инстанс
$data = $client->incomingLeads->decline($collection);
// установить пользователя который отклонил
$data = $client->incomingLeads->decline($collection, 12345);
Работа с API Телефонии (add 2020-02-05)
Можно только создать звонок
$client->calls->save(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\Call(
null, [
'phone_number' => '380980000001',
'direction' => 'inbound',
'uniq' => 'uniquniquniquniq',
'duration' => '134',
'source' => 'tomato1',
'call_status' => '4',
'call_result' => 'какойто результат звонка',
'link' => 'http://link-to-call',
'responsible_user_id' => '3621055',
'created_by' => '3621055',
]
),
]
)
);
Работа с Событиями (add 2020-02-05)
Доступно только получить список событий
(Коллекция моделей Anemone\Models\Event
)
$collect = $client->events
->limit(1)
->with('contact_name')
->valueAfter(['leads_statuses' => [['pipeline_id' => 2274433, 'status_id' => 31525672]]])
->get();
// типы событий
$collection = $client->events->types();
Работа с WebHooks (add 2020-02-06)
Список WebHooks
$collection = $client->webhooks->get();
Создание/обновление WebHooks (создание и удаление временно недоступно)
$webhook = new \Anemone\Models\Webhook($client->webhooks, [
'url' => 'https://link.for.hook'
]);
$webhook
->addCompany()
->addContact()
->deleteCustomer()
->deleteLead(true)
->deleteCustomer()
->addContact(false);
$webhook->save();
// или несколько штук
$client->webhooks->save(new \Anemone\Core\Collection\Collection([
$webhook,
]));
Удаление WebHooks
$collection = $client->webhooks->get();
$collection->first()->delete();
// или несколько штук
$client->webhooks->delete($collection);
Работа с воронками и этапами воронок
Воронки и этапы существуют только в сделках
// коллекция воронок (моделей Anemone\Models\Pipeline)
$collect = $client->leads->pl();
// создать/обновить воронок
$client->leads->savePL(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\Pipeline(
['name' => 'Gg', 'is_main' => false, 'is_unsorted_on' => true, 'sort' => 3, '_embedded' => []]
),
new \Anemone\Models\Pipeline(['name' => 'New name', 'id' => 3256180]),
]
)
);
// удалить воронки
$client->leads->deletePL(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\Pipeline(
['name' => 'Gg', 'is_main' => false, 'is_unsorted_on' => true, 'sort' => 3]
),
new \Anemone\Models\Pipeline(['name' => 'New name', 'id' => 3313405]),
]
)
);
// первую пропустит, так как нет id
// коллекция этапов воронки (моделей Anemone\Models\StatusPL)
$collect = $client->leads->statusesPL(123456); // id воронки
// создать/обновить этапы
$client->leads->saveStatusesPL(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\StatusPL(
['name' => 'Gg', 'sort' => 3]
),
new \Anemone\Models\StatusPL(['name' => 'New name', 'id' => 32936836]),
]
),
3256180
);
// первый создаст, второй обновит
// удалить этапы
$client->leads->deleteStatusesPL(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\StatusPL(
['name' => 'Gg', 'sort' => 3]
),
new \Anemone\Models\StatusPL(['name' => 'New name', 'id' => 32936836]),
]
),
3256180
);
// первую пропустит
Работа с тегами
Теги представлены так же обьектами \Anemone\Models\Tag
,
получить коллекцию \Anemone\Core\Collection\Collection
методом tags()
Добавить (открепить) тег(и) в (из) сущность (4 способа):
// ...
$lead->attachTags('new tag');
$lead->attachTags(['new tag1', 'new tag2']);
$tag1 = new \Anemone\Models\Tag();
$tag1->name = 'tagByJarvis';
$tag2 = new \Anemone\Models\Tag(['name' => 'tagByJarvisOver']);
$lead->attachTags($tag1);
$lead->attachTags(new \Anemone\Core\Collection\Collection([
$tag1,
$tag2,
]));
// метод detachTags работает точно так же как и attachTags ток открепляет тег(и))
Список всех тегов (add 12.11.2019)
теги можно получить из инстанса которы поддерживает теги
(LeadsInstance
, CustomersInstance
, ContactsInstance
, CompaniesInstance
)
// ...
/**
* @var \Anemone\Core\Collection\Collection<\Anemone\Models\Tag> $collection
*/
$collection = $client->leads->tags()->get();
$collection = $client->customers->tags()->get();
$collection = $client->contacts->tags()->get();
$collection = $client->companies->tags()->get();
Особенность: необходимо для получения списка тегов - переключиться на новую версию амо срм
Создание тега для типа сущностей (не для конкретной сущности)
$client->leads->tags()->save(
new \Anemone\Core\Collection\Collection([
new \Anemone\Models\Tag(['name' => 'yyyy'])]
)
);
Работа с пользователями (2020-06-03)
// список (коллекция моделей Anemone\Models\User)
$collect = $client->users->get();
// сохранить (добавить, изменить)
$client->users->save(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\User(
null,
[
'name' => 'new user',
'email' => 'ddddddfff4R@gmail.com',
'password' => 'ddddddfff4R@gmail.com'
]
),
]
)
);
Работа с кастомными полями
Кастомные поля как и теги так же являются обьектами интерфейса \Anemone\Contracts\BeCustomField
и гранятся в коллекции \Anemone\Core\Collection\Collection
в свойстве custom_fields_values
Получение коллекцию или конкретный кастомное поле:
// коллекция кастомных полей
$collect = $lead->custom_fields_values;
// коллекция кастомных полей с собственной функцией фильтрации
// необязательным феноменом этой функции - можете изменять значения каждого КП (кастомное поле)
// перед сохранением
$collectFiltered = $lead->cf(function(\Anemone\Contracts\BeCustomField $field) {
return $field->id != 12345;
});
// получить КП по ID
$oneCF = $lead->cf(12345);
// получить КП по имени
$oneCF = $lead->cf('jarvis');
Устанавка, изменение значений КП:
// получить КП по ID (для примера)
// логично что он не будет одновременно всеми разновидностями \Anemone\Contracts\BeCustomField
$oneCF = $lead->cf(12345);
/**
* @var \Anemone\Models\CF\UrlCustomField $urlCF
*/
$urlCF = $oneCF;
$urlCF->setValue('https://google.com');
$value = $urlCF->getValue();
/**
* @var \Anemone\Models\CF\TextCustomField $textCF
*/
$textCF = $oneCF;
$textCF->setValue('I Jarvis!');
$value = $textCF->getValue();
/**
* @var \Anemone\Models\CF\TextareaCustomField $textareaCF
*/
$textareaCF = $oneCF;
$textareaCF->setValue('I Long King Jarvis!');
$value = $textareaCF->getValue();
/**
* @var \Anemone\Models\CF\StreetAddressCustomField $streetAddressCF
*/
$streetAddressCF = $oneCF;
$streetAddressCF->setValue('Kyiv city');
$value = $streetAddressCF->getValue();
/**
* @var \Anemone\Models\CF\SelectCustomField $selectCF
*/
$selectCF = $oneCF;
$selectCF->setValue('Jarvis in ENUM');
$value = $selectCF->getValue();
/**
* @var \Anemone\Models\CF\RadiobuttonCustomField $radioCF
*/
$radioCF = $oneCF;
$radioCF->setValue('Jarvis in ENUM');
$value = $radioCF->getValue();
/**
* @var \Anemone\Models\CF\OrgLegalNameCustomField $olnCF
*/
$olnCF = $oneCF;
$olnCF->setValue(['Jarvis org 1', 'Jarvis org 2']);
$value = $olnCF->getValue();
/**
* @var \Anemone\Models\CF\NumericCustomField $numericCF
*/
$numericCF = $oneCF;
$numericCF->setValue(911);
$value = $numericCF->getValue();
/**
* @var \Anemone\Models\CF\MultiTextCustomField $emailOrPhoneCF
*/
$emailOrPhoneCF = $oneCF;
$emailOrPhoneCF->setValue(911, 'WORK'); // 'HOME', 'OTHER' ... то что в АМО (если упустить второй параметр - по умолчанию 'WORK')
$value = $emailOrPhoneCF->getValue();
/**
* @var \Anemone\Models\CF\MultiSelectCustomField $multiselectCF
*/
$multiselectCF = $oneCF;
$multiselectCF->setValue(['Jarvis in ENUM', 'Google in ENUM']);
$value = $multiselectCF->getValue();
/**
* @var \Anemone\Models\CF\DateCustomField $dateCF
*/
$dateCF = $oneCF;
$dateCF->setValue('12-09-2019');
$value = $dateCF->getValue();
/**
* @var \Anemone\Models\CF\CheckboxCustomField $checkboxCF
*/
$checkboxCF = $oneCF;
$checkboxCF->setValue(true);
$value = $checkboxCF->getValue();
/**
* @var \Anemone\Models\CF\BirthdayCustomField $birthdayCF
*/
$birthdayCF = $oneCF;
$birthdayCF->setValue('05-12-2019');
$value = $birthdayCF->getValue();
/**
* @var \Anemone\Models\CF\SmartAddressCustomField $smartAddressCF
*/
$smartAddressCF = $oneCF;
// v1
$smartAddressCF->setValue(function(\Anemone\Models\CF\Helpers\SybSmartAddress $subSmartAddress) {
$subSmartAddress->address_line_1 = 'Line for jarvis';
$subSmartAddress->address_line_2 = 'Line for google';
$subSmartAddress->city = 'Kyiv';
$subSmartAddress->state = 'Other';
$subSmartAddress->zip = 03151;
$subSmartAddress->country = 'UA';
});
// v2
$smartAddressCF->setValue([
'address_line_1' => 'Line for jarvis',
'address_line_2' => 'Line for google',
'city' => 'Kyiv',
'state' => 'Other',
'zip' => 03151,
'country' => 'UA',
]);
// get \Anemone\Models\CF\Helpers\SybSmartAddress
$value = $smartAddressCF->getValue();
// get array
$value = $smartAddressCF->getValue(true);
/**
* @var \Anemone\Models\CF\LegalEntityCustomField $legalCF
*/
$legalCF = $oneCF;
// v1
$legalCF->setValue(function (array $values) {
$newLE = new \Anemone\Models\CF\Helpers\SubLegalEntity();
$newLE->name = 'OOO Google inc.';
$newLE->vat_id = 12345;
$newLE->kpp = 54321;
$values[] = $newLE;
// ++
return $values; // <- required
});
// v2
$legalCF->setValue([
'name' => 'OOO Google inc.',
'vat_id' => 12345,
'kpp' => 54321,
]);
// get array in objects Anemone\Models\CF\Helpers\SubLegalEntity
$value = $legalCF->getValue();
// get arrays
$value = $legalCF->getValue(true);
Список доступных кастомных полей:
// Поля можно получить для каждого типа сущности отдельно
$collect = $leadsInstance->cf(); // для сделок
$collect = $contactsInstance->cf(); // для контактов
$collect = $customersInstance->cf(); // для покупателей
$collect = $companiesInstance->cf(); // для сделоккомпаний
Манипуляции с кастомными полями осуществляются через инстанс сущносты которые поддерживают КП
Добавление нового кастомного поля:
$fieldMultiSelect = new \Anemone\Models\CF\MultiSelectCustomField();
$fieldMultiSelect->name = 'More jarvis';
$fieldMultiSelect->enums = [
[
'value' => 'jarvis',
],
[
'value' => 'google',
],
];
$leadsInstance->saveCF(new \Anemone\Core\Collection\Collection([
new \Anemone\Models\CF\TextCustomField(['name' => 'field by jarvis']),
$fieldMultiSelect,
]));
Удаление существуещего кастомного поля :
// получаем КП относящихся к сделкам (коллекция)
// сначала получили модель Аккаунт, а с нее custom_fields
$leadCFCollect = $leadsInstance->cf();
$leadCFCollectFiltered = $leadCFCollect->filter(function(\Anemone\Contracts\BeCustomField $cf) {
return $cf->type == 'radiobutton'; // все radiobutton
});
$leadsInstance->deleteCF($leadCFCollectFiltered);
Изменение существуещего кастомного поля:
// получаем КП относящихся к сделкам (коллекция)
$leadCFCollect = $leadsInstance->cf();
$leadCFCollect->each(function(\Anemone\Contracts\BeCustomField $cf) {
if ($cf->type == 'radiobutton') { // все radiobutton
$cf->name = 'mega companies';
$cf->enums = [
[
'value' => 'jarvis',
],
[
'value' => 'google',
],
[
'value' => 'adobe',
],
];
}
});
$leadsInstance->saveCF($leadCFCollect);
Добавлена возможность управлять группами кастомных полей
Список групп (Коллекция моделей Anemone\Models\GroupCF
)
$collect = $cl->leads->groupsCF();
// аналогично другие сущности
Создание, обновление, удаление
// создание
$cl->leads->saveGroupCF(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\GroupCF(['name' => 'HH']),
new \Anemone\Models\GroupCF(['name' => 'GG77']),
]
)
);
// обновление
$cl->leads->saveGroupCF(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\GroupCF(['id' => 'leads_81281590768026', 'name' => 'HH']),
new \Anemone\Models\GroupCF(['id' => 'leads_75941590767796', 'name' => 'GG77']),
]
)
);
// удаление
$cl->leads->deleteGroupCF(
new \Anemone\Core\Collection\Collection(
[
new \Anemone\Models\GroupCF(['id' => 'leads_81281590768026', 'name' => 'HH']),
new \Anemone\Models\GroupCF(['id' => 'leads_75941590767796', 'name' => 'GG77']),
]
)
);
Связанные модели
Некоторые модели (Lead, Customer...) могут иметь связь с другими моделями, чтобы их получить необходимо
// получить контакты привязанные к сделке (коллекция Contact)
$collectOfContacts = $lead->contacts();
$idsOfContacts = $lead->contactsId();
$idOfMainContact = $lead->mainContactId();
// получить компанию привязанную к сделке (модель Company)
$company = $lead->company();
// получить сделки привязанные к контакту (коллекция Lead)
$collectOfLeads = $contact->leads();
// получить компании привязанные к контакту (коллекция Customer)
$collectOfCustomers = $contact->customers();
// .. аналогично и в других моделях
Прикрепить модели метод - link
,
Все работают одинаково и имеют по 4 варианта использования
$lead->link($collectOfContacts);
// так же для остальных сущностей
Открепить связанные модели метод - unlink
,
// получить контакты привязанные к сделке (коллекция Contact)
$collectOfContacts = $lead->contacts();
$lead->unlink($collectOfContacts);
// так же для остальных сущностей
// получить задачи привязанные к контакту (аналогично сделке, компании, покупателю) (коллекция Task)
$collectOfTasks = $contact->tasks();
Extensions (Дополнения)
Клиент NotApiClient
В некоторых случаях доступ к определенным методам АМО CRM не доступен по авторизации из API.
Для этих целей появился \Anemone\Extensions\NotApiClient
. На вход конструктора он принимает
массив авторизационных данных:
{
"user_login": "jarvis@google.com",
"user_password": "password_for_jarvis"
}
и вторым параметром - домен.
Получите \Anemone\Extensions\Core\Services\HttpClientService
(если надо) для выполнение
своих нестандартных запросов.
$unClient = new \Anemone\Extensions\NotApiClient([
'user_login' => 'jarvis@google.com',
'user_password' => 'password_for_jarvis',
], 'jarvis.amocrn.ru');
/**
* @var \Anemone\Extensions\Core\Services\HttpClientService $httpClientService
* */
$httpClientService = $unClient->getHttpClientService();
$httpClientService->get(/*...*/);
$httpClientService->post(/*...*/);
$httpClientService->patch(/*...*/);
$httpClientService->delete(/*...*/);
Поддержка сервисов для этого клиента будет увеличиваться по мере....
SERVICE: Partners (Партнерский кабинет)
Сервис Anemone\Extensions\Partners\PartnerService
дает возможность получать (в неких случаях
и создавать) данные из (в) партнерского кабинета.
Для авторизации в партнерском кабинете - пользователь который инициализирует \Anemone\Extensions\NotApiClient
должен быть зарегистрирован в партнерском кабинете. В противном случае - вы не сможете работать с
Anemone\Extensions\Partners\PartnerService
.
Возможности:
- ПОлучить список всех своих партнерских пользователей (аккаунтов).
- Получить конкретного своего партнерского пользователя (аккаунта).
- Получить более детальную информацию о партнерском пользователе (аккаунте).
- Зарегистрировать нового партнерского пользователя (аккаунта).
- Продлить триальный перриод для своего партнерского пользователя (аккаунта).
- Посмотреть подписку для любого пользователя (аккаунта) по ID (Информации не много).
$unClient = new \Anemone\Extensions\NotApiClient([
'user_login' => 'jarvis@google.com',
'user_password' => 'password_for_jarvis',
], 'jarvis.amocrm.ru');
/**
* @var Anemone\Extensions\Partners\PartnerService $partnerService
* */
$partnerService = $unClient->partnerService;
/**
* @var \Illuminate\Support\Collection $collection
* */
// Все партнеры
$collection = $partnerService->partnersList();
// Активные на триальной подписке партнеры
$collection = $partnerService->partnersList('trial');
// НЕАктивные приостановлены партнеры
$collection = $partnerService->partnersList('expired');
// Активные на платной подписке партнеры
$collection = $partnerService->partnersList('paid');
/**
* @var \Anemone\Extensions\Partners\Models\Partner $one
* */
// Модель по ID (с чужими ID работать не будет)
$one = $partnerService->partnerById(123456);
/**
* @var array $tariffData
* */
// Тариф аккаунта по ID (со всеми ID)
$tariffData = $partnerService->tariffData(123456);
// Зарегистрировать партнерского клиента
$partner = new \Anemone\Extensions\Partners\Models\Partner([
'name' => 'newJarvis',
'email' => 'jarvis@google.com',
'phone' => '123456', // optional
], $unClient);
/**
* @var \Anemone\Extensions\Partners\Models\Partner $storedPartner
* */
// Регистрация
$storedPartner = $partner->store(555555); // partner ID
// Продлить триальный перриод
$onePartner = $collection->first();
$changedPartner = $onePartner->prolong(7); // один раз можно продлить
$changedPartner = $onePartner->prolong(14); // один раз можно продлить
// или
$changedPartner = $onePartner->prolong(7)->prolong(14);
// В противном случе -> ловите исключения
SERVICE: Widgets (Работа с виджетами)
Сервис \Anemone\Extensions\Widgets\WidgetsService
Сервис дает возможность:
- Получить список всех виджетов, или с фильтрацией по категориям
'
phone
', 'mail
', 'site
', 'chats
', 'useful
', 'recommended
', 'own_integrations
', - Получить список
ApiWidget
- виджеты которые находятся в разделе API. - Создать новый виджет в аккаунте.
- упаковать в архив виджет.
Получить список всех виджетов, или с фильтрацией по категориям:
// создать любой клиент
$clientAPI = new \Anemone\Client([
"domain" => "jarvis.amocrm.ru",
"login" => "jarvis@google.com",
"secret_key" => "b2f0414de331177268cb09f720a0b36a076fe88e",
]);
// или
$unClient = new \Anemone\Extensions\NotApiClient([
'user_login' => 'jarvis.amocrm.ru',
'user_password' => 'zzfOPa7P',
], 'jarvis.amocrm.ru');
$widgetService = new \Anemone\Extensions\Widgets\WidgetsService($clientAPI); // или $unClient
/**
* @var Illuminate\Support\Collection<\Anemone\Extensions\Widgets\Models\Widget|\Anemone\Extensions\Widgets\Models\Integration> $collection
* */
// все виджеты кроме 'recommended', 'own_integrations'
$collection = $widgetService->all();
// виджеты с фильтрацией
$collection = $widgetService->all('mail');
Получить список ApiWidget
- виджеты которые находятся в разделе API:
// ... $widgetService = new ...
/**
* @var Illuminate\Support\Collection<\Anemone\Extensions\Widgets\Models\ApiWidget> $collection
* */
// все API виджеты
$collection = $widgetService->allApi();
// или
$collection = \Anemone\Extensions\Widgets\Models\ApiWidget::all($clientAPI->getQueryService()); // или $unClient->getQueryService()
Создать новый виджет в аккаунте:
// ... $widgetService = new ...
/**
* @var \Anemone\Extensions\Widgets\Models\ApiWidget $apiWidget
* */
$apiWidget = $widgetService->storeApiWidget('code_new_widget');
// или
$apiWidget = new \Anemone\Extensions\Widgets\Models\ApiWidget(
['code' => 'code_new_widget'],
$clientAPI->getQueryService()
); // или $unClient->getQueryService()
$storedApiWidget = $apiWidget->store();
упаковать в архив виджет:
// ... $widgetService = new ...
/**
* @var string $pathToWidget
* */
$pathToWidget = $widgetService->packWidget('path/to/widget/folder/or/zip', 'code_widget', 'secret_widget');
// или
$pathToWidget = \Anemone\Extensions\Widgets\Models\ApiWidget::pack(
'path/to/widget/folder/or/zip', 'code_widget', 'secret_widget'
);
Дополнительные возможности \Anemone\Extensions\Widgets\Models\ApiWidget
:
// кроме получения коллекции виджето методом all можно получить водин виджет по коду
$one = \Anemone\Extensions\Widgets\Models\ApiWidget::find($clientAPI->getQueryService(), 'code_widget');
// загрузить архив виджета на сервер
$one->upload('path/to/zip'); // return bool
// установить настройки для виджета (те что в разделе интеграций)
$one->setSettings(['backend' => 'https://jarvis.google.com', 'api' => 'jquery']); // return bool
$one->setSettings(['backend' => 'https://jarvis.google.com', 'api' => 'jquery'], true); // активировать виджет
// отдельно включить или отключить виджет
$one->power(false); // return bool
$one->power(true); // return bool
// помимо создания виджета (описано выше), виджет можно удалить
$one->destroy(); // return bool
SERVICE: Widgets (Работа с интеграциями) (2020-03-14)
Интеграции пришли на смену или расширение возможностей виджетов.
Для работы с интеграциями добавлен сервис \Anemone\Extensions\Widgets\IntegrationsService
Возможности:
- Список интеграций
- Поиск интеграции по ее
uuid
- Создание интеграции
- Обновление интеграции
- Обновление секрета интеграции (попытки получить авторизацию по старому секрету будут отклонены)
- Удаление интеграции
- Присоединение к интеграции виджета с архивом
- Загрузка архива виджета и логотипа интеграции (соблюдайте структуру и разрешение лого см. документацию амо)
- Упаковка виджета интеграции по новым требованиям
- Настройка, включение, отключение виджета интеграции
- Получение авторизационных данных (access_token, refresh_token,...), конвертация кода в токен доступа
- Обновление токена по refresh_token, конвертация refresh_token в токен доступа
$service = new \Anemone\Extensions\Widgets\IntegrationsService($client);
// or not api client (from NotApiClient)
$service = $unClient->integrationsService;
Важно:
Создание, обновление, удаление, загрузка архива виджета интеграций используйте
клиент \Anemone\Extensions\NotApiClient
или старый апи токен
клиент
так как (на даный момент) не хватает полномочий в oauth2
клиенте.
// ... $service
/** list of integrations
* @var \Illuminate\Support\Collection<\Anemone\Extensions\Widgets\Models\Integration> $collection
* */
$collection = $service->all();
/** one model
* @var \Anemone\Extensions\Widgets\Models\Integration $model
* */
$model = $service->find('uuid');
/** store
* @var \Anemone\Extensions\Widgets\Models\Integration $model
* */
$model = $service->save(
['ru' => 'ru_name', 'en' => 'en_name'],
['ru' => 'ru description', 'en' => 'en description'],
['crm', 'notifications'],
'https://callback.com'
);
/** update
* @var \Anemone\Extensions\Widgets\Models\Integration $model
* */
$model = $service->save(
['ru' => 'ru_name', 'en' => 'en_name'],
['ru' => 'ru description new', 'en' => 'en description new'],
['crm', 'notifications'],
'https://callback.com',
'f52bfff8-8ace-4229-b661-aaceb1e62c40'
);
// available scopes
$scopes = [
"crm",
"notifications",
"chats",
"integrations_auth",
"integrations_auth_mobile",
"integrations_fb",
"integrations_google",
"integrations_vk",
"mail",
"push_notifications",
"unsorted"
];
/** update secret
* @var \Anemone\Extensions\Widgets\Models\Integration $model
* */
$model = $service->find('be3e8638-771e-4942-aa1b-2373e93bdde5');
$service->refreshSecret($model);
/** delete
* @var bool $status
* */
$status = $service->delete($model); // $model or uuid of model
/** generate widget data (link widget)
* @var array $data (widget code, secret, uuid of integration)
* */
$data = $service->generateIntegrationData($model); // $model or uuid of model
/** upload widget to server
* @var bool $status
* */
$status = $service->upload(
'/link/to/widget.zip',
$data['code'],
$data['secret_key'],
$data['client_uuid']
);
/** upload icon integration
* @var array $resultData
* */
$resultData = $service->uploadLogo('/link/to/logo_main.png', $model); // $model or uuid of model
/** pack widget.zip
* @var string $link
* */
$link = $service->packIntegrationWidget('/path/to/api_widget');
// or
$link = $service->packIntegrationWidget('/path/to/api_widget/widget.zip');
/** set settings and power widget in integration
* @var bool $status
* */
$status = $service->setSettings($model, [ // $model or uuid of model
'backend' => 'https://backend.com',
'token_key' => 'token_key',
// ....
]);
// and set power
$status = $service->setSettings($model, [ // $model or uuid of model
'backend' => 'https://backend.com',
'token_key' => 'token_key',
// ....
], false); // set power
/** convert code to access_token and refresh_token
* @var array $authData
* */
$authData = $service->convertCodeToAccessToken($model);
/** convert refresh_token to new access_token and refresh_token
* @var array $authData
* */
$authData = $service->refreshToken($model, $refresh_token);
SERVICE: Notifications (Работа с нотификациями) (add: 24.10.2019)
Сервис \Anemone\Extensions\Notifications\NotificationService
Сервис дает возможность:
- Получить список всех нотификаций (Ораничение: только используя
\Anemone\Extensions\NotApiClient
) - Создать новые оповещения.
Получить список всех нотификаций:
// создать клиент (только \Anemone\Extensions\NotApiClient)
$unClient = new \Anemone\Extensions\NotApiClient([
'user_login' => 'jarvis.amocrm.ru',
'user_password' => 'zzfOPa7P',
], 'jarvis.amocrm.ru');
$notityService = new \Anemone\Extensions\Notifications\NotificationService($unClient);
/**
* @var \Anemone\Core\Collection\Collection<\Anemone\Extensions\Notifications\Models\ReturnedNotify> $collection
* */
$collection = $notityService->get();
Создать новые оповещения:
// создать любой клиент
$clientAPI = new \Anemone\Client([
"domain" => "jarvis.amocrm.ru",
"login" => "jarvis@google.com",
"secret_key" => "b2f0414de331177268cb09f720a0b36a076fe88e",
]);
// или
$unClient = new \Anemone\Extensions\NotApiClient([
'user_login' => 'jarvis.amocrm.ru',
'user_password' => 'zzfOPa7P',
], 'jarvis.amocrm.ru');
$notityService = new \Anemone\Extensions\Notifications\NotificationService($clientAPI); // или $unClient
$errorNotify = new \Anemone\Extensions\Notifications\Models\ErrorNotify([
"date" => time(),
"message" => "message Text",
"header" => "header Text",
"link" => "/contacts/list/?term=4951234567"
]);
$callNotify1 = new \Anemone\Extensions\Notifications\Models\CallNotify([
"to" => "Смирнов+Алексей",
"from" => "Петрова+Анна",
"duration" => "04:10",
"link" => "https://example.com/dialog.mp3",
"user" => "3621055",
"date" => "1534084300",
"message" => "Звонок+от++7(999)888+55+33",
"element" => [
"id" => 18221265,
"type" => "contact",
"name" => "",
],
]);
$callNotify2 = new \Anemone\Extensions\Notifications\Models\CallNotify([
"to" => "Смирнов+Алексей",
"from" => "Петрова+Анна",
"link" => "https://example.com/dialog.mp3",
"user" => "3621055",
"date" => "1534084400",
"message" => "Звонок+от++7(999)888+55+33",
"click_link" => "/contacts/add/?phone=9191234567",
]);
// сохранение (одиночное)
$notityService->store($errorNotify);
$notityService->store($callNotify1);
// сохранение (массовое)
$notityService->store(new \Anemone\Core\Collection\Collection([
$errorNotify,
$callNotify1,
$callNotify2,
]);
SERVICE: Groups (Работа с группами кастомных полей) (add ..-12-2019)
Помечен как Deprecated
, так как в новой 4 версии добавили методы работы
с группами
Возможность управлять вкладками групп в карточках сущностей
$groupsService = new \Anemone\Extensions\Groups\GroupsService($client);
/**
* @var array $array
* [
* 'leads' => Collection<Group>,
* 'contacts' => Collection<Group>,
* 'companies' => Collection<Group>,
* 'customers' => Collection<Group>,
* ]
* */
$array = $groupsService->all();
// или коллекция для сущности
/**
* @var Collection<Group> $collection
* */
$collection = $groupsService->all('leads');
// создать
$field1 = new \Anemone\Models\CF\TextCustomField(['name' => 'field by jarvis 1', 'element_type' => 2]);
$field2 = new \Anemone\Models\CF\TextCustomField(['name' => 'field by jarvis 2', 'element_type' => 2]);
$client->account->save(new \Anemone\Core\Collection\Collection([
$field1,
$field2,
]));
$group1 = new \Anemone\Extensions\Groups\Models\Group([
'name' => 'group 1',
]);
$group1->fields = new Anemone\Core\Collection\Collection([$field1, $field2]);
// для сделки по умолчанию
$result = $groupsService->store(new \Anemone\Core\Collection\Collection([
$group1,
new \Anemone\Extensions\Groups\Models\Group([
'name' => 'group 2',
]),
]));
// для контакта
$result = $groupsService->store(new \Anemone\Core\Collection\Collection([
$group1,
]), 'contacts');
// после получения списка - можно обновить или удалить группу(ы)
$collect = $groupsService->all('leads');
$collect->each(function (Anemone\Extensions\Groups\Models\Group $group) use ($field1, $field2) {
if ($group->id == 'leads_98451576865910') {
$group->name = 'new name';
$group->fields = new Anemone\Core\Collection\Collection([$field1, $field2]);
}
});
$result = $groupsService->update($collect);
// delete
$collect = $groupsService->all('leads');
$filtered = $collect->filter(function (\Anemone\Extensions\Groups\Models\Group $group) {
return $group->id == 'leads_44281576865561';
});
$result = $groupsService->destroy($filtered);
SERVICE: Distribution (Работа с распределением) (add 22.01.2020)
Поддерживается линейное и случайное распределение (будет больше)
Обект распределения должен реализовать интерфейс \Anemone\Contracts\BeDistribution
,
По умолчанию заложен класс этого интерфейса \Anemone\Extensions\Distribution\Distribution
,
который принимает данные определенной структуры, если у вас имеется своя структура данных -
создайте свой класс от интерфейса (некоторую структуру все же нада будет сохранить)
$distributionService = new \Anemone\Extensions\Distribution\DistributionService($client);
// обязательные свойтства: type, source, data
$config1 = [
'type' => 'linear',
'source' => 'any',
'data' => [
['id' => 5781673, 'config' => []],
],
'excludes' => [],
'default' => 5781670,
];
$config2 = [
'type' => 'linear',
'source' => 'group',
'data' => [
['id' => 0, 'config' => ['data' => [
['id' => 5781673, 'config' => []],
]]],
],
'excludes' => [5781670],
'default' => 5781670,
];
$config3 = [
'type' => 'random',
'source' => 'any',
'data' => [
['id' => 5781673, 'config' => []],
],
'excludes' => [5781670, 5781673, 5776324],
'default' => 5781670,
];
$config4 = [
'type' => 'random',
'source' => 'group',
'data' => [
['id' => 0, 'config' => ['data' => [
['id' => 5781673, 'config' => []],
]]],
],
'excludes' => [],
];
$distribution = new \Anemone\Extensions\Distribution\Distribution($config1);
$distributionService->init($distribution);
echo $distributionService->next();
// следующий
echo $distributionService->next();
// ...
$result = $distributionService->result();
// или
$result = $distribution->result();
// для получения структуры для хранения (актуально для линейного распределения)
Выполнение других запросов
Методы запросов обладают гибкостью добавления параметров для запроса (авторизационные данные добавляются автоматически)
$queryService = $client->getQueryService();
$result = $queryService->get('https://jarvis.amocrm.ru/tra-ta-ta', ['query' => 'value']);
$result = $queryService->post(/*...*/);
$result = $queryService->patch(/*...*/);
$result = $queryService->delete(/*...*/);
Особенности
- при клонировании сущности - сами забодьтесь о датах создания и других данных (полный клон) clone ссылки остаются (tags, custom-fields..) (в будущем возможно изменится поведение)
Глобальные функции хелперы
(врядли понадобятся)
Функции были созданы для работы самой библиотеки, а не для пользовательских решений (все имеют префикс
a*
).
aAppPath(): string
- app path,aLibPath(): string
- anemone lib path,aConfig(string $key.of.config): mixed
- get val in global config (.dot is separate),aEntryData(string $key.of.entry): mixed
- get entry data (ex.: '4.lead')aExtEntryData(string $key.of.entry): mixed
- get entry data for extensions,aEnv(string $key, string $default = ''): mixed
- get env variables,aAvailableVersion(): string[]
- get available versions,aLogger(Closure $closure = null): Monolog\Logger
- get logger instance,