An open API service indexing awesome lists of open source software.

https://github.com/ufee/amoapi-v4

amoCRM/Kommo API v4 PHP Client
https://github.com/ufee/amoapi-v4

amocrm api kommo php

Last synced: 4 months ago
JSON representation

amoCRM/Kommo API v4 PHP Client

Awesome Lists containing this project

README

          

# πŸš€ amoCRM/Kommo PHP API (v4) Client

ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ OAuth 2.0, ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΏΠ°Π³ΠΈΠ½Π°Ρ†ΠΈΡŽ, события, автоматичСскоС ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ошибок ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρƒ с Π»ΡŽΠ±Ρ‹ΠΌΠΈ сущностями (сдСлки, ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚Ρ‹, ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ, Π·Π°Π΄Π°Ρ‡ΠΈ, Π·Π°ΠΌΠ΅Ρ‚ΠΊΠΈ ΠΈ Π΄Ρ€.).

---

## βœ… ВозмоТности

- βœ… ΠŸΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° [amoCRM/Kommo API v4](https://www.amocrm.ru/developers/content/crm_platform/platform-abilities)
- βœ… OAuth 2.0 с Π°Π²Ρ‚ΠΎΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²
- βœ… Π₯Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²: Ρ„Π°ΠΉΠ»Ρ‹, Redis, MongoDB + долгосрочныС Ρ‚ΠΎΠΊΠ΅Π½Ρ‹
- βœ… ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ справочников Π² Ρ„Π°ΠΉΠ»Π°Ρ… ΠΈ Redis: ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ, поля, Ρ‚ΠΈΠΏΡ‹ Π·Π°Π΄Π°Ρ‡ ΠΈ Ρ‚.Π΄.
- βœ… ΠŸΠΎΡΡ‚Ρ€Π°Π½ΠΈΡ‡Π½ΠΎΠ΅ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ сущностСй Ρ‡Π΅Ρ€Π΅Π· `foreach` ΠΈ `do-while`
- βœ… ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° событий Ρ‡Π΅Ρ€Π΅Π· `callbacks`: ΠΎΡ‚Π»Π°Π΄ΠΊΠ°, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ
- βœ… ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ частоты запросов
- βœ… ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° массовых ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ
- βœ… ΠœΡƒΠ»ΡŒΡ‚ΠΈΠ°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π½ΠΎΡΡ‚ΡŒ

---

## πŸ“¦ Установка

```bash
composer require ufee/amoapi-v4
```

## βš™οΈ Быстрый старт
```php
$api = \Ufee\AmoV4\ApiClient::setInstance([...]);
$leads = $api->leads()->get();
foreach ($leads as $lead) {
echo $lead->name . "\n";
}
```

### ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
```php
$api = \Ufee\AmoV4\ApiClient::setInstance([
'domain' => 'yourdomain', // Π΄ΠΎΠΌΠ΅Π½ (Π±Π΅Π· .amocrm.ru)
'client_id' => '8a8135d4-31ca-47...', // ID ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ
'client_secret' => 'zMZFNnho8FozhrDzxrbA9xuR9...',
'redirect_uri' => 'https://yoursite.com/auth/callback',
'zone' => 'ru', // или 'com' для Kommo
]);
```

### Настройка ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ)
```php
$api->setParam('query_delay', 0.15); // Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΌΠ΅ΠΆΠ΄Ρƒ запросами (сСк)
$api->setParam('query_retries', 3); // ΠΊΠΎΠ»-Π²ΠΎ ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ ΠΏΡ€ΠΈ ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… 429
$api->setParam('lang', 'ru'); // язык Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°
```

### Π₯Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Oauth
Π€Π°ΠΉΠ»ΠΎΠ²ΠΎΠ΅ Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ OAuth-Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²
Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: `/src/Temp/{domain}/{client_id}.json`
```php
$api->oauth->setStorageFiles('/path/to/oauth/storage');
```
**Долгосрочный Ρ‚ΠΎΠΊΠ΅Π½**
```php
$api->oauth->setLongToken($long_token);
```
**Redis**
ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° [phpredis](https://github.com/phpredis/phpredis)
```php
$redis = new \Redis();
$redis->connect('127.0.0.1');
$redis->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_PHP); // ΠΈΠ»ΠΈ \Redis::SERIALIZER_IGBINARY
$redis->select(4);

$api->oauth->setStorageRedis($redis);
```
**Mongodb**
ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° [mongo-php-library](https://github.com/mongodb/mongo-php-library)
```php
$mongo = new \MongoDB\Client('mongodb://127.0.0.1');
$collection = $mongo->selectCollection('amo', 'oauth');

$api->oauth->setStorageMongo($mongo);
```

### ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…
ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ справочников ΠΈ ΠΎΠ±Ρ‰ΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°
ВрСмя ΠΆΠΈΠ·Π½ΠΈ для кэша / ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
```php
$api->cache->setTtl([
'account' => 60, // 3600
'users' => 60, // 1800
'pipelines' => 60, // 3600
'userGroups' => 60, // 3600
'customFields' => 60, // 1800
'taskTypes' => 60, // 3600
'eventTypes' => 60 // 86400
]);
```
Π€Π°ΠΉΠ»ΠΎΠ²ΠΎΠ΅ Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ кэша
Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: `/src/Temp/{domain}/{client_id}.{key}.cache`
```php
$api->cache->setStorageFiles('/path/to/cache/storage', [
'serialize' => 'igbinary_serialize', // рСкомСндуСтся вмСсто serialize
'unserialize' => 'igbinary_unserialize' // рСкомСндуСтся вмСсто unserialize
]);
```
ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° кСша
```php
$api->cache->clear('account');
$api->cache->clear('customFields');
$api->cache->clear('taskTypes');
```
**Redis**
ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° [phpredis](https://github.com/phpredis/phpredis)
```php
$redis = new \Redis();
redis->connect('127.0.0.1');
$redis->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_PHP); // ΠΈΠ»ΠΈ \Redis::SERIALIZER_IGBINARY
$redis->select(4);

$api->cache->setStorageRedis($redis);
```

### πŸ”” Бобытия (Callbacks)
ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ запросов, Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ
```php
$api->callbacks->on($event, function($payload) {
// подписка Π½Π° события
});
```
```php
$api->callbacks->off($event, function($payload) {
// отписка ΠΎΡ‚ событий
});
```
ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ события
Бобытия ΠΏΠΎ query Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π½ΠΈΠΆΠ΅
```php
$api->callbacks->off('query.delay')->on('query.delay', function($query) {
// ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ прописана Π»ΠΎΠ³ΠΈΠΊΠ° Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ Π½Π° основС $query->instance->getParam('query_delay')
// ΠΏΠ°ΡƒΠ·Π° ΠΌΠ΅ΠΆΠ΄Ρƒ запросами вычисляСтся автоматичСски
sleep(1); // кастомная Π»ΠΎΠ³ΠΈΠΊΠ° Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ ΠΌΠ΅ΠΆΠ΄Ρƒ запросами
});

$api->callbacks->on('query.request.before', function($query) {
// вызываСтся ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ запроса
echo '['.$query->method.'] '.$query->getUrl();
});

$api->callbacks->on('query.response.code', function($code, $query) {
// вызываСтся послС выполнСния запроса
// ΠΏΠΎΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ присутствуСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΊΠΎΠ΄ΠΎΠ²:
// 429 - ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹Π΅ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ
// 401 - повторная ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° с ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΎΠΊΠ΅Π½Π° ΠΈΠ· Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°
// 502,504 - ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½Ρ‹ΠΉ ΠΏΠΎΠ²Ρ‚ΠΎΡ€
// return false; ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π΅Ρ‚ Π΄Π°Π»ΡŒΠ½Π΅ΠΉΡˆΡƒΡŽ Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ
});

$api->callbacks->on('query.response.fail', function($query, $code) {
// вызываСтся послС Π½Π΅ΡƒΠ΄Π°Ρ‡Π½ΠΎΠ³ΠΎ выполнСния запроса
// всС ΠΊΠΎΠ΄Ρ‹ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΊΡ€ΠΎΠΌΠ΅ 200,204
if ($code === 0) {
echo 'Error: '.$query->response->getError()."\n\n";
} else {
echo "Response:\n".$query->endDate().' - ['.$code.'] '.$query->response->getData()."\n\n";
}
});

$api->callbacks->on('query.response.after', function($query, $code) {
// вызываСтся всСгда послС выполнСния запроса
if ($code === 0) {
echo 'Error: '.$query->response->getError()."\n\n";
} else {
echo "Response:\n".$query->endDate().' - ['.$code.'] '.$query->response->getData()."\n\n";
}
});

$api->callbacks->on('oauth.token.fetch', function($oauth, $query, $response) {
// вызываСтся послС извлСчСния Ρ‚ΠΎΠΊΠ΅Π½Π°
});

$api->callbacks->on('oauth.token.refresh', function($oauth, $query, $response) {
// вызываСтся послС обновлСния Ρ‚ΠΎΠΊΠ΅Π½Π°
});

$api->callbacks->on('oauth.token.refresh.error', function($exc, $query = null, $response = null) {
// вызываСтся послС Π½Π΅ΡƒΠ΄Π°Ρ‡Π½ΠΎΠ³ΠΎ обновлСния Ρ‚ΠΎΠΊΠ΅Π½Π°
});
```
### πŸ” ΠŸΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ OAuth-Ρ‚ΠΎΠΊΠ΅Π½Π°
```php
$api->oauth->fetchToken($code); // Ρ‚ΠΎΠΊΠ΅Π½ сохранится Π² Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΌ storage
```
### ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ API запросы
```php
$query = $api->query('GET','/api/v4/leads/'.$lead_id);
$query->execute();
$raw = $query->response->validated();
print_r($raw); // object of lead
echo $raw->name;
```
### πŸ“₯ Π Π°Π±ΠΎΡ‚Π° с сущностями
ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· сСрвисы:
```php
// ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ экзСмпляра сСрвиса
$service = $api->account();
$api->users();
$api->customFields($entity_type);
$api->pipelines();
$api->pipelineStatuses($pipeline_id);
$api->leads();
$api->contacts();
$api->companies();
$api->links();
$api->tasks();
$api->notes($entity_type);
$api->events();
$api->widgets();
$api->webhooks();
```
Установка ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²
```php
$service->maxPageRows($value);
$service->orderBy($field, $direction = 'asc')
$service->with($values);
$service->setQueryArg($key, $value);
$service->setQueryArgs($args = []);

```
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сущностСй
```php
$model = $service->find($elem_id, $with = []);
$collection = $service->get($with = null);
$paginate = $service->paginate($with = null);
$paginate = $service->filter($conditions, $with = []);
$paginate = $service->search($phrase, $with = []);

```
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅/ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ сущностСй Ρ‡Π΅Ρ€Π΅Π· сырыС Π΄Π°Π½Π½Ρ‹Π΅
$raw_data ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ массивом ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²
На ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ Π½Π΅ примСняСтся, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ дСйствиС производится Ρ‡Π΅Ρ€Π΅Π· модСль
```php
$raw_response = $service->add($raw_data);
$raw_response = $service->update($raw_data);
```
#### МодСль сущности
Поля ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ динамичСскиС, Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Ρ‡Π΅Ρ€Π΅Π· Π³Π΅Ρ‚Ρ‚Π΅Ρ€Ρ‹ ΠΈ сСттСры
```php
$model = $service->create(['field1' => 'value', 'field2' => 'value', ...]);
// ΠΈΠ»ΠΈ
$model = $service->find(123567);

$model->name = 'Name';
$model->price = 100;
$model->save(); // созданиС ΠΈΠ»ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ сущности ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ
$model->toArray();
```
#### ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ сущностСй
```php
$models = $service->createCollection([
['field1' => 'value', 'field2' => 'value', ...],
['field1' => 'value', 'field2' => 'value', ...],
]);
// ΠΈΠ»ΠΈ
$models = $service->get();

foreach($models as $model) {
$model->attachTag('AmoV4');
}
$models->save(); // массовоС созданиС ΠΈΠ»ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ сущностСй ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ
$models->toArray();
```
#### ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сущностСй ΠΏΠΎ ID
```php
$lead = $api->leads()->find(30013961);
$contact = $api->contacts()->find(45968927);
$company = $api->companies()->find(55968943);

$leads = $api->leads()->find([30013961,30013962,30013963]);
```
#### ΠŸΠΎΡΡ‚Ρ€Π°Π½ΠΈΡ‡Π½ΠΎΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅
ΠžΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΠ΅Ρ‚ΡΡ Π½Π° основании `_links->next->href` ΠΈΠ· ΠΎΡ‚Π²Π΅Ρ‚Π°
```php
$paginate = $api->leads()->paginate();
$paginate->maxPages(10); // максимальноС ΠΊΠΎΠ»-Π²ΠΎ страниц
$paginate->maxRows(100); // максимальноС ΠΊΠΎΠ»-Π²ΠΎ сущностСй Π½Π° страницС

do {
$leads = $paginate->fetchPage();
echo "\nPage ".$paginate->page."\n";
print_r($leads); // collection
} while(
$paginate->nextPage();
);

// ΠΈΠ»ΠΈ Ρ‚Π°ΠΊ
foreach($paginate as $page_num=>$leads) {
echo "\nPage ".$page_num."\n";
print_r($leads); // collection
}
```
Π’ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… случаях `_links->next->href` отсутствуСт Π² ΠΎΡ‚Π²Π΅Ρ‚Π΅, Π½ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ страницы ΠΏΡ€ΠΈ этом ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚, Π² Ρ‚Π°ΠΊΠΎΠΌ случаС ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ всС страницы, ΠΊΠ°ΠΊ это дСлаСтся Π² `$paginate->fetchAll();`
```php
$paginate->maxPages(10);
while (
$paginate->valid() && ($leads = $paginate->fetchPage()) && $leads->count()
) {
echo "\nPage ".$paginate->page."\n";
print_r($leads); // collection
$paginate->setPageNum($paginate->page+1);
}

// ΠΈΠ»ΠΈ Ρ‚Π°ΠΊ
$leads = $paginate->fetchAll($max_pages);
```
#### Π€ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ сущностСй
```php
$paginate = $api->leads()->filter([
'price' => ['from' => 0, 'to' => 100500]
]);
foreach($paginate as $page_num=>$leads) {
echo "\nPage ".$page_num."\n";
print_r($leads); // collection
}
```
#### Поиск сущностСй
```php
$leads = $service->searchByCustomField(string $query, string $field, int $page_limit = 0, array $with = []);
$contacts = $service->searchByPhone(string $phone, int $page_limit = 0, array $with = []);
$contacts = $service->searchByEmail(string $email, int $page_limit = 0, array $with = []);
$companies = $service->searchByName(string $name, int $page_limit = 0, array $with = []);

$paginate = $leads->search('query', ['source_id','source']);
```
#### Аккаунт
```php
$account = $api->account()->get();
// ΠΈΠ»ΠΈ
$account = $api->account;
// или из кСша
$account = $api->cache->account();

// модСль Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°
echo $account->id;
echo $account->name;

$userGroups = $account->userGroups; // collection
$taskTypes = $account->taskTypes; // collection

// или из кСша
$userGroups = $api->cache->userGroups();
$taskTypes = $api->cache->taskTypes();
$eventTypes = $api->cache->eventTypes($lang = null); // Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ язык ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ

// очистка кСша
$api->cache->clear('account');
```
#### ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°
```php
$users = $api->users()->get();
// или из кСша
$users = $api->cache->users();
// ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΠΎ id
$user = $api->cache->user(128737);
```
#### Π’ΠΎΡ€ΠΎΠ½ΠΊΠΈ сдСлок
```php
$pipelines = $api->pipelines()->get();
$pipeline = $api->pipelines()->find($pipeline_id);
// или из кСша
$pipelines = $api->cache->pipelines();
$pipeline = $api->cache->pipeline($pipeline_id);
// ΠΈΠ»ΠΈ новая Π²ΠΎΡ€ΠΎΠ½ΠΊΠ°
$pipeline = $api->pipelines()->create(['name' => 'Π Π΅ΠΊΠ»Π°ΠΌΠ°Ρ†ΠΈΠΈ']);

$pipeline->sort = 20;
$pipeline->is_main = false;
$pipeline->is_unsorted_on = false;
$pipeline->_embedded = [];
$pipeline->save();

// этапы Π²ΠΎΡ€ΠΎΠ½ΠΊΠΈ
$statuses = $pipeline->statuses(); // collection
// ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π²ΠΎΡ€ΠΎΠ½ΠΊΠΈ
$pipeline->delete();
```
#### Π­Ρ‚Π°ΠΏΡ‹ Π²ΠΎΡ€ΠΎΠ½ΠΎΠΊ
```php
$statuses = $api->pipelineStatuses($pipeline_id)->with(['descriptions'])->get();
$status = $api->pipelineStatuses($pipeline_id)->find($status_id, ['descriptions']);
// ΠΈΠ»ΠΈ Π½ΠΎΠ²Ρ‹ΠΉ этап
$status = $api->pipelineStatuses($pipeline_id)->create(['name' => 'Π”ΠΎΠ³ΠΎΠ²ΠΎΡ€ подписан']);

$status->sort = 50;
$status->save();

// ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ этапа
$status->delete();
```
#### ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Ρ‹Π΅ поля Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°
```php
$service = $api->customFields('contacts');
$service = $api->customFields('catalogs', $catalog_id);
$service->maxPageRows(10);
$service->orderBy('sort', 'desc');

// ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ
$cfields = $service->get();
// или из кСша
$cfields = $api->cache->customFields('contacts');
$cfields = $api->cache->customFields('catalogs', $catalog_id);
```
БозданиС поля
```php
$service = $api->customFields('contacts');
$cf = $service->create(['name' => 'Π’Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ ΠΎΠΏΠ»Π°Ρ‚Ρ‹']);
$cf->type = 'multiselect';
$cf->enums = [
['value' => 'Онлайн', 'sort' => 0],
['value' => 'ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ', 'sort' => 1],
['value' => 'Π‘Π‘ΠŸ', 'sort' => 2]
];
$cf->save();
```
#### ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Ρ‹Π΅ поля сущности
```php
$lead = $api->leads()->find($lead_id);

$cf = $lead->cf('Π’Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ ΠΎΠΏΠ»Π°Ρ‚Ρ‹');
$cf->reset();
$cf->setValues(['Онлайн','ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ']);
$cf->setEnums([845234,945431]);
$values = $cf->getValues();

// полС по названию
$cf = $lead->cf('Π“ΠΎΡ€ΠΎΠ΄');
// ΠΏΠΎΠ»Π΅ ΠΏΠΎ id
$cf = $lead->cf(3745829);

$cf->setValue('Москва');
$cf->setEnum(546710);
$value = $cf->getValue();

$field = $cf->field;
$enum_values = $field->getEnums();
$enum_ids = $field->getEnumIds();
$values = $field->getValues();
$bool = $field->hasEnum(568345);
$bool = $field->hasValue('ЧСбоксары');

$cf = $lead->cf()->byName('Π“ΠΎΡ€ΠΎΠ΄');
$cf = $lead->cf()->byId(3745829);
$cf = $lead->cf()->byCode('PHONE');
$cf = $lead->cf()->byType('radiobutton');

$cfields = $lead->cf()->all();
foreach($cfs as $cf) {
print_r($cf->getValue());
echo "\n";
}
```
#### Π‘Π΄Π΅Π»ΠΊΠΈ
```php
$leads = $api->leads()->get();
$leads = $api->leads;
$leads = $api->leads()->with(['source_id','source']))->get();
$leads = $api->leads()->searchByCustomField('Москва', 'Π“ΠΎΡ€ΠΎΠ΄', 1); // 1 page (250 rows max)
$leads = $api->leads()->searchByName('Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ПО', 1, ['source_id','source']); // 1 page with source

$paginate = $api->leads()
->orderBy('updated_at', 'desc')
->with(['source_id','source','loss_reason'])
->paginate();

$paginate = $api->leads()->filter($conditions = [], $with = []);
$paginate = $api->leads()->search('VIP');

$lead = $api->leads()->find($lead_id);
$lead = $api->leads()->find($lead_ids, ['source_id','source']);
$lead = $api->leads()->create(['name' => 'Новая сдСлка']);

$lead->price = 100;
$lead->status_id = 21776227;
$lead->cf('ΠŸΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚')->setValue('Высокий'); // set value name by cf name
$lead->cf(123678)->setEnum(83565); // set enum id by cf id

$lead->attachTag('Tag1');
$lead->attachTag(['name' => 'Π¦Π²Π΅Ρ‚Π½ΠΎΠΉ', 'color' => 'FF8F92']);
$lead->detachTag('Tag3');
$tags = $lead->getTags();

// replace all existing tags
$lead->setTags($tags); // ids or names
$lead->resetTags(); // replace with none

$paginate = $lead->getTasks($filter = []);
$tasks = $lead->getTasks($filter = [])->fetchAll();
$task = $lead->findTask($task_id);
$task = $lead->createTask($type = 1);

$paginate = $lead->getNotes($filter = []);
$notes = $lead->getNotes($filter = [])->fetchAll();
$note = $lead->findTask($task_id);
$note = $lead->createNote($type = 'common');

```

#### Π’ΠΈΠ΄ΠΆΠ΅Ρ‚Ρ‹
```php
$paginate = $api->widgets()->paginate();
$paginate->maxRows(100)->maxPages(10);

// пагинация Π½Π° основС next link
foreach($paginate as $page_num=>$widgets) {
echo "\nPage ".$page_num." loaded ".$widgets->count()."\n\n";
print_r($widgets); // collection
}
// ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ пагинация Π½Π° основании наличия Π΄Π°Π½Π½Ρ‹Ρ…
while (
$paginate->valid() && ($widgets = $paginate->fetchPage()) && $widgets->count()
) {
echo "\nPage ".$paginate->page." loaded ".$widgets->count()."\n\n";
$paginate->setPageNum($paginate->page+1);
}

// ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ всСх страниц Π² Π²ΠΈΠ΄Π΅ ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ
$widgets = $api->widgets()->get();
$widgets = $api->widgets()->paginate()->fetchAll($max_pages);

$widget = $widgets->where('id', 972)->first();
// ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ запросом ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ
$widget = $api->widgets()->find('amo_asterisk');

// установка Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π°, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ модСль
$installed = $api->widgets()->install('amo_asterisk', $settings);
// ΠΈΠ»ΠΈ Ρ‡Π΅Ρ€Π΅Π· модСль
$installed = $widget->install([
'login' => 'example',
'password' => 'eXaMp1E',
'phones' => [
1234 => '8927047',
5678 => '8906000',
],
'script_path'=> 'https://site.ru/'
]);

// ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ установки Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π°
$bool = $api->widgets()->uninstall('amo_asterisk');
// ΠΈΠ»ΠΈ Ρ‡Π΅Ρ€Π΅Π· модСль
$bool = $widget->uninstall();
```

#### Π’Π΅Π±Ρ…ΡƒΠΊΠΈ
```php
// ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ всСх Π²Π΅Π±Ρ…ΡƒΠΊΠΎΠ²
$webhooks = $this->crm->webhooks()->get();
// ΠΈΠ»ΠΈ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… ΠΏΠΎ url
$webhooks = $this->crm->webhooks()->get($some_url);

foreach($webhooks as $webhook) {
// отписка
$webhook->unsubscribe();
}
// подписка Π½Π° Π²Π΅Π±Ρ…ΡƒΠΊ
$webhook = $this->crm->webhooks()->subscribe($some_url, ['note_lead','note_contact','...']);
// отписка
$result = $this->crm->webhooks()->unsubscribe($some_url);
```