sliva-name / bitrix24-laravel
Laravel integration package for Bitrix24 CRM with OAuth and Webhook support
Installs: 20
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/sliva-name/bitrix24-laravel
Requires
- php: ^8.2
- bitrix24/b24phpsdk: ^1.7
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0
README
Полнофункциональный, гибкий и расширяемый пакет для интеграции Laravel с Bitrix24 CRM.
Поддерживает OAuth и Webhook аутентификацию, предоставляет чистый API для работы с CRM, задачами, пользователями и кастомными списками. Спроектирован с учетом принципов SOLID и максимальной расширяемости.
📋 Содержание
- Возможности
- Требования
- Установка
- Быстрый старт
- Конфигурация
- Базовое использование
- Продвинутые возможности
- Расширение пакета
- API Reference
- События
- Middleware
- Тестирование
- Миграция
- FAQ
- Поддержка
✨ Возможности
🔐 Аутентификация
- ✅ OAuth 2.0 с автоматическим обновлением токенов
- ✅ Webhook для серверных интеграций
- ✅ Управление токенами с поддержкой мультитенантности
- ✅ Кеширование токенов для производительности
🎯 CRM клиенты
- ✅ Лиды (Leads)
- ✅ Сделки (Deals)
- ✅ Контакты (Contacts)
- ✅ Компании (Companies)
- ✅ Задачи (Tasks)
- ✅ Пользователи (Users)
- ✅ Пользовательские списки (Lists)
- ✅ Универсальный CRM клиент для любых сущностей
🔧 Расширяемость
- ✅ Макросы (Macroable) - динамическое добавление методов
- ✅ События (Events) - перехват API вызовов
- ✅ Traits - кеширование и rate limiting из коробки
- ✅ Интерфейсы - для всех клиентов (DI ready)
- ✅ Регистрация клиентов - переопределение и создание новых
- ✅ Batch операции - пакетные запросы к API
🏗️ Архитектура
- ✅ SOLID принципы - чистая архитектура
- ✅ Repository Pattern - абстракция работы с данными
- ✅ Service Layer - инкапсуляция бизнес-логики
- ✅ PSR-12 - стандарты кодирования
- ✅ Type Safety - строгая типизация PHP 8.2+
- ✅ Полная поддержка Dependency Injection
📦 Дополнительно
- ✅ Готовые контроллеры и маршруты
- ✅ Middleware для защиты роутов
- ✅ API Resources для JSON responses
- ✅ Логирование всех операций
- ✅ Обработка ошибок и retry logic
- ✅ Подробная документация с примерами
📋 Требования
- PHP: 8.2 или выше
- Laravel: 10.x, 11.x или 12.x
- База данных: PostgreSQL (рекомендуется), MySQL, SQLite
- Extensions:
ext-json,ext-curl
📦 Установка
Шаг 1: Установка через Composer
composer require sliva-name/bitrix24-laravel
Шаг 2: Публикация ресурсов
# Публикация конфигурации php artisan vendor:publish --tag=bitrix24-config # Публикация миграций php artisan vendor:publish --tag=bitrix24-migrations
Шаг 3: Запуск миграций
php artisan migrate
Шаг 4: Настройка окружения
Добавьте переменные в файл .env:
Для OAuth:
BITRIX24_AUTH_TYPE=oauth BITRIX24_DOMAIN=your-domain.bitrix24.ru BITRIX24_CLIENT_ID=local.xxxxxxxx.yyyyyyyy BITRIX24_CLIENT_SECRET=your_client_secret BITRIX24_REDIRECT_URI=${APP_URL}/api/bitrix24/auth/callback
Для Webhook:
BITRIX24_AUTH_TYPE=webhook BITRIX24_WEBHOOK_URL=https://your-domain.bitrix24.ru/rest/123/your_webhook_key/
🚀 Быстрый старт
OAuth аутентификация
use Leko\Bitrix24\Facades\Bitrix24; // 1. Получить URL для авторизации $authUrl = Bitrix24::getAuthorizationUrl(); return redirect($authUrl); // 2. Обработать callback после авторизации Route::get('/bitrix24/callback', function (Request $request) { $result = Bitrix24::handleCallback($request->input('code')); return response()->json([ 'success' => true, 'token_id' => $result['token_id'], ]); }); // 3. Использовать API $leads = Bitrix24::leads()->list();
Работа с лидами
use Leko\Bitrix24\Facades\Bitrix24; // Получить все лиды $leads = Bitrix24::leads()->list(); // Фильтрация и сортировка $hotLeads = Bitrix24::leads()->list( filter: ['STATUS_ID' => 'NEW', 'OPPORTUNITY' => ['>=', 100000]], select: ['ID', 'TITLE', 'NAME', 'OPPORTUNITY'], order: ['OPPORTUNITY' => 'DESC'] ); // Создать лид $leadId = Bitrix24::leads()->add([ 'TITLE' => 'Новый клиент', 'NAME' => 'Иван', 'LAST_NAME' => 'Иванов', 'EMAIL' => [['VALUE' => 'ivan@example.com', 'VALUE_TYPE' => 'WORK']], 'PHONE' => [['VALUE' => '+79001234567', 'VALUE_TYPE' => 'MOBILE']], 'OPPORTUNITY' => 50000, ]); // Обновить лид Bitrix24::leads()->update($leadId, [ 'STATUS_ID' => 'IN_PROCESS', 'ASSIGNED_BY_ID' => 1, ]); // Удалить лид Bitrix24::leads()->delete($leadId);
⚙️ Конфигурация
Файл конфигурации
После публикации, файл config/bitrix24.php содержит все настройки:
return [ // Тип аутентификации: 'oauth' или 'webhook' 'default_connection' => env('BITRIX24_DEFAULT_CONNECTION', 'main'), 'connections' => [ 'main' => [ 'type' => env('BITRIX24_AUTH_TYPE', 'oauth'), 'domain' => env('BITRIX24_DOMAIN'), // OAuth настройки 'client_id' => env('BITRIX24_CLIENT_ID'), 'client_secret' => env('BITRIX24_CLIENT_SECRET'), 'redirect_uri' => env('BITRIX24_REDIRECT_URI'), // Webhook настройки 'webhook_url' => env('BITRIX24_WEBHOOK_URL'), ], // Дополнительные подключения 'secondary' => [ // ... ], ], // Хранение токенов 'token_storage' => env('BITRIX24_TOKEN_STORAGE', 'database'), // Кеширование 'cache' => [ 'enabled' => env('BITRIX24_CACHE_ENABLED', true), 'store' => env('BITRIX24_CACHE_STORE', 'redis'), 'ttl' => env('BITRIX24_CACHE_TTL', 3600), ], // Логирование 'logging' => [ 'enabled' => env('BITRIX24_LOGGING_ENABLED', false), 'channel' => env('BITRIX24_LOG_CHANNEL', 'daily'), ], // Таймауты и retry 'api' => [ 'timeout' => env('BITRIX24_API_TIMEOUT', 30), 'retry_times' => env('BITRIX24_RETRY_TIMES', 3), 'retry_sleep' => env('BITRIX24_RETRY_SLEEP', 1000), ], ];
Мультитенантность
// Разные подключения для разных клиентов $leads1 = Bitrix24::setConnection('tenant_1')->leads()->list(); $leads2 = Bitrix24::setConnection('tenant_2')->leads()->list(); // Работа с токенами конкретного пользователя $leads = Bitrix24::setUserId(auth()->id())->leads()->list();
💻 Базовое использование
Работа с CRM
Лиды (Leads)
// Список с пагинацией $leads = Bitrix24::leads()->list( filter: ['STATUS_ID' => 'NEW'], select: ['ID', 'TITLE', 'NAME'], order: ['ID' => 'DESC'], start: 0 ); // Получить по ID $lead = Bitrix24::leads()->get(123); // CRUD операции $id = Bitrix24::leads()->add([...]); $success = Bitrix24::leads()->update($id, [...]); $deleted = Bitrix24::leads()->delete($id); // Получить доступные поля $fields = Bitrix24::leads()->fields();
Сделки (Deals)
$deals = Bitrix24::deals()->list([ 'STAGE_ID' => 'NEW', 'OPPORTUNITY' => ['>=', 10000], ]); $deal = Bitrix24::deals()->add([ 'TITLE' => 'Крупная сделка', 'OPPORTUNITY' => 500000, 'CURRENCY_ID' => 'RUB', 'CONTACT_ID' => 123, 'COMPANY_ID' => 456, ]);
Контакты (Contacts)
$contacts = Bitrix24::contacts()->list(); $contact = Bitrix24::contacts()->add([ 'NAME' => 'Иван', 'LAST_NAME' => 'Петров', 'EMAIL' => [['VALUE' => 'ivan@example.com', 'VALUE_TYPE' => 'WORK']], 'PHONE' => [['VALUE' => '+79001234567', 'VALUE_TYPE' => 'MOBILE']], ]);
Компании (Companies)
$companies = Bitrix24::companies()->list(); $company = Bitrix24::companies()->add([ 'TITLE' => 'ООО "Рога и Копыта"', 'COMPANY_TYPE' => 'CUSTOMER', 'INDUSTRY' => 'IT', ]);
Работа с задачами
// Получить все задачи $tasks = Bitrix24::tasks()->list(); // Создать задачу $taskId = Bitrix24::tasks()->add([ 'TITLE' => 'Позвонить клиенту', 'DESCRIPTION' => 'Обсудить условия сделки', 'RESPONSIBLE_ID' => 1, 'DEADLINE' => now()->addDays(3)->toDateTimeString(), ]); // Обновить задачу Bitrix24::tasks()->update($taskId, [ 'STATUS' => 5, // Завершена ]);
Работа с пользователями
// Получить всех пользователей $users = Bitrix24::users()->list(); // Текущий пользователь $currentUser = Bitrix24::users()->current(); // Поиск пользователей $found = Bitrix24::users()->search('Иван');
Работа с пользовательскими списками
$lists = Bitrix24::lists(); // Получить все списки $allLists = $lists->getAllLists(); // Получить элементы списка $items = $lists->list($listId, [ 'PROPERTY_STATUS' => 'active' ]); // Добавить элемент $elementId = $lists->add($listId, [ 'NAME' => 'Новый элемент', 'PROPERTY_VALUE' => 'test', ]);
Универсальный CRM клиент
$crm = Bitrix24::crm(); // Работа с любой сущностью $items = $crm->getList('lead', ['STATUS_ID' => 'NEW']); $fields = $crm->getFields('deal'); $id = $crm->add('contact', [...]);
🔥 Продвинутые возможности
1. Макросы (Macroable)
Добавляйте методы динамически без наследования:
use Leko\Bitrix24\Clients\LeadClient; // В AppServiceProvider::boot() LeadClient::macro('getHotLeads', function () { return $this->list([ 'OPPORTUNITY' => ['>=', 100000], 'STATUS_ID' => 'NEW', ]); }); // Использование $hotLeads = Bitrix24::leads()->getHotLeads();
Mixin - добавление класса методов
class LeadAnalyticsMixin { public function calculateConversion() { return function () { $all = count($this->list()); $converted = count($this->list(['STATUS_ID' => 'CONVERTED'])); return $all > 0 ? ($converted / $all * 100) : 0; }; } } LeadClient::mixin(new LeadAnalyticsMixin()); $conversion = Bitrix24::leads()->calculateConversion();
2. События (Events)
Перехватывайте и обрабатывайте API вызовы:
use Leko\Bitrix24\Events\ApiCallEvent; use Leko\Bitrix24\Events\ApiCallFailedEvent; // В EventServiceProvider protected $listen = [ ApiCallEvent::class => [ LogBitrix24ApiCall::class, ], ApiCallFailedEvent::class => [ NotifyOnBitrix24ApiFailure::class, ], ]; // Listener class LogBitrix24ApiCall { public function handle(ApiCallEvent $event): void { Log::info('Bitrix24 API Call', [ 'method' => $event->method, 'duration' => $event->duration, 'is_webhook' => $event->isWebhook, ]); } }
3. Traits для расширения
HasCaching - кеширование запросов
use Leko\Bitrix24\Clients\LeadClient; use Leko\Bitrix24\Support\Traits\HasCaching; class CachedLeadClient extends LeadClient { use HasCaching; public function listCached(array $filter = []): array { $key = 'leads:' . md5(json_encode($filter)); return $this->cached($key, function () use ($filter) { return $this->list($filter); }, 600); // 10 минут } }
HasRateLimiting - защита от лимитов
use Leko\Bitrix24\Support\Traits\HasRateLimiting; class RateLimitedDealClient extends DealClient { use HasRateLimiting; public function __construct($serviceBuilder) { parent::__construct($serviceBuilder); $this->rateLimit(50, 60); // 50 запросов в минуту } public function list(...): array { return $this->rateLimited('deals:list', function () { return parent::list(...); }); } }
4. Batch операции
use Leko\Bitrix24\Support\BatchRequest; $batch = new BatchRequest(Bitrix24::leads()); $batch ->add('lead1', 'crm.lead.add', ['fields' => ['TITLE' => 'Лид 1']]) ->add('lead2', 'crm.lead.add', ['fields' => ['TITLE' => 'Лид 2']]) ->add('lead3', 'crm.lead.add', ['fields' => ['TITLE' => 'Лид 3']]); $results = $batch->execute();
5. Dependency Injection
Все клиенты имеют интерфейсы для внедрения зависимостей:
use Leko\Bitrix24\Contracts\LeadClientInterface; use Leko\Bitrix24\Contracts\DealClientInterface; class SalesService { public function __construct( private LeadClientInterface $leads, private DealClientInterface $deals ) {} public function convertLeadToDeal(int $leadId): ?int { $lead = $this->leads->get($leadId); return $this->deals->add([ 'TITLE' => $lead['TITLE'], 'CONTACT_ID' => $lead['CONTACT_ID'], ]); } } // Laravel автоматически внедрит зависимости $service = app(SalesService::class);
🎨 Расширение пакета
Создание кастомного клиента
namespace App\Services\Bitrix24; use Leko\Bitrix24\Clients\BaseClient; class AnalyticsClient extends BaseClient { public function getSalesReport(string $period): array { return $this->callMethod('crm.analytics.report', [ 'period' => $period, ]) ?? []; } }
Регистрация клиента
// В AppServiceProvider use Leko\Bitrix24\Bitrix24Service; public function boot(): void { // Регистрация нового клиента Bitrix24Service::registerClient('analytics', AnalyticsClient::class); // Переопределение существующего Bitrix24Service::registerClient('leads', MyCustomLeadClient::class); } // Использование $report = Bitrix24::client('analytics')->getSalesReport('month'); $leads = Bitrix24::leads(); // Вернёт MyCustomLeadClient
📖 Подробнее: EXTENSIBILITY.md, ADVANCED_USAGE.md
📚 API Reference
Bitrix24 Facade
Bitrix24::leads() // LeadClientInterface Bitrix24::deals() // DealClientInterface Bitrix24::contacts() // ContactClientInterface Bitrix24::companies() // CompanyClientInterface Bitrix24::tasks() // TaskClientInterface Bitrix24::users() // UserClientInterface Bitrix24::lists() // ListClientInterface Bitrix24::crm() // CrmClientInterface // Утилиты Bitrix24::setConnection(string $name) Bitrix24::setUserId(?int $id) Bitrix24::getAuthorizationUrl(array $scopes = []) Bitrix24::handleCallback(string $code) Bitrix24::hasValidToken(?int $userId = null) Bitrix24::client(string $name) // Кастомный клиент
Методы клиентов
Все CRM клиенты (Leads, Deals, Contacts, Companies) имеют одинаковый интерфейс:
list(array $filter = [], array $select = ['*'], array $order = ['ID' => 'DESC'], int $start = 0): array get(int $id): mixed add(array $fields): ?int update(int $id, array $fields): bool delete(int $id): bool fields(): array
📡 События
Пакет генерирует следующие события:
ApiCallEvent
Вызывается при успешном API запросе:
public readonly string $method; // Метод API public readonly array $params; // Параметры запроса public readonly mixed $result; // Результат public readonly float $duration; // Длительность в секундах public readonly bool $isWebhook; // Webhook или OAuth
ApiCallFailedEvent
Вызывается при ошибке API запроса:
public readonly string $method; // Метод API public readonly array $params; // Параметры запроса public readonly Throwable $exception;// Исключение public readonly float $duration; // Длительность в секундах
🛡️ Middleware
EnsureBitrix24Token
Проверяет наличие валидного токена:
Route::middleware(['auth', 'bitrix24.token'])->group(function () { Route::get('/leads', [LeadController::class, 'index']); });
Регистрация в app/Http/Kernel.php:
protected $middlewareAliases = [ 'bitrix24.token' => \Leko\Bitrix24\Http\Middleware\EnsureBitrix24Token::class, ];
🧪 Тестирование
# Запуск всех тестов composer test # С покрытием кода composer test:coverage # Статический анализ composer phpstan # Code style composer cs:check composer cs:fix
Моки для тестирования
use Leko\Bitrix24\Contracts\LeadClientInterface; public function test_lead_creation(): void { $mock = Mockery::mock(LeadClientInterface::class); $mock->shouldReceive('add') ->once() ->with(['TITLE' => 'Test Lead']) ->andReturn(123); $this->app->instance(LeadClientInterface::class, $mock); // Ваш тест }
🔄 Миграция
С версии 1.x на 2.x
См. MIGRATION_GUIDE.md для подробных инструкций.
Основные изменения:
- Добавлены интерфейсы для всех клиентов
- Новая система событий
- Макросы и traits
- Batch операции
❓ FAQ
Как работать с несколькими Bitrix24 аккаунтами?
// В config/bitrix24.php добавьте подключения 'connections' => [ 'account1' => [...], 'account2' => [...], ], // Используйте $leads1 = Bitrix24::setConnection('account1')->leads()->list(); $leads2 = Bitrix24::setConnection('account2')->leads()->list();
Как обработать ошибки API?
try { $leads = Bitrix24::leads()->list(); } catch (\Throwable $e) { Log::error('Bitrix24 Error', [ 'message' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); }
Как добавить кеширование?
Используйте trait HasCaching:
use Leko\Bitrix24\Support\Traits\HasCaching; class CachedClient extends LeadClient { use HasCaching; public function listCached(): array { return $this->cached('leads', fn() => $this->list(), 600); } }
Как работать с пагинацией?
$start = 0; $perPage = 50; $allLeads = []; do { $leads = Bitrix24::leads()->list(start: $start); $allLeads = array_merge($allLeads, $leads); $start += $perPage; } while (count($leads) === $perPage);
📖 Документация
- EXTENSIBILITY.md - Полное руководство по расширению пакета
- ADVANCED_USAGE.md - Продвинутые примеры использования
- FLEXIBILITY_SUMMARY.md - Резюме гибкости архитектуры
- MIGRATION_GUIDE.md - Руководство по миграции
- CHANGELOG.md - История изменений
- CONTRIBUTING.md - Правила контрибуции
🤝 Поддержка
- 📧 Email: lucy@leko.team
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
🙏 Благодарности
- Bitrix24 PHP SDK - за основу работы с API
- Laravel Framework - за отличный фреймворк
- Всем контрибьюторам проекта
📄 Лицензия
Этот пакет является открытым ПО, лицензированным под MIT license.
🌟 Вклад в проект
Мы приветствуем вклад! Пожалуйста:
- Fork репозитория
- Создайте feature branch (
git checkout -b feature/amazing-feature) - Commit изменений (
git commit -m 'Add amazing feature') - Push в branch (
git push origin feature/amazing-feature) - Откройте Pull Request
См. CONTRIBUTING.md для подробностей.
Сделано с ❤️ командой Leko Team