Разработка серверных приложений Битрикс24
Когда задача — автоматически создавать сделки в Битрикс24 при поступлении заказа из внешнего магазина, синхронизировать контакты с почтовым сервисом или запускать роботов по расписанию — нужно серверное приложение. Оно работает без участия пользователя: никакого интерфейса, никакого iframe, только REST API и правильно настроенный OAuth.
Чем серверное приложение отличается от webhook
Вебхуки в Битрикс24 — это входящие URL, куда Битрикс24 шлёт события. Они удобны для простых сценариев, но имеют ограничения: привязаны к конкретному пользователю, не поддерживают OAuth, не могут быть тиражными. Серверное приложение (тип server) — полноценный OAuth-клиент, который:
- Авторизуется от имени установившего пользователя с сохранением токенов
- Может работать в фоне (демон, очередь задач, cron)
- Поддерживает многопортальность (одно приложение — много клиентов)
- Имеет собственный обработчик событий через
event.bind
OAuth 2.0 в контексте Битрикс24
Битрикс24 использует стандартный Authorization Code Flow:
1. Редирект пользователя на:
https://company.bitrix24.ru/oauth/authorize/
?client_id=YOUR_CLIENT_ID
&response_type=code
&state=RANDOM_STRING
2. После разрешения — редирект на redirect_uri с `code`
3. Обмен кода на токены:
POST https://oauth.bitrix.info/oauth/token/
grant_type=authorization_code
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_SECRET
&code=RECEIVED_CODE
&redirect_uri=https://your-app.com/oauth/callback
4. Ответ:
{
"access_token": "...",
"expires_in": 3600,
"token_type": "bearer",
"scope": "crm,task,user",
"refresh_token": "...",
"member_id": "portal_hash"
}
Критично: токены храните в защищённом хранилище (база данных, AWS Secrets Manager, Vault). member_id — уникальный идентификатор портала, используйте его как ключ в multi-tenant архитектуре.
Хранение токенов и refresh-логика
В production-системе токены хранятся примерно так:
CREATE TABLE bitrix_tokens (
id SERIAL PRIMARY KEY,
member_id VARCHAR(64) UNIQUE NOT NULL,
domain VARCHAR(255) NOT NULL,
access_token TEXT NOT NULL,
refresh_token TEXT NOT NULL,
expires_at TIMESTAMPTZ NOT NULL,
scope TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
Refresh при истечении токена:
def get_valid_token(member_id: str) -> str:
token = db.get_token(member_id)
if token.expires_at < datetime.now() + timedelta(minutes=5):
response = requests.post(
'https://oauth.bitrix.info/oauth/token/',
data={
'grant_type': 'refresh_token',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'refresh_token': token.refresh_token,
}
)
new_token = response.json()
db.update_token(member_id, new_token)
return new_token['access_token']
return token.access_token
Добавляйте 5-минутный буфер (timedelta(minutes=5)) — иначе токен может истечь между проверкой и фактическим запросом.
Подписка на события портала
Серверное приложение может подписываться на события Битрикс24 через REST:
POST /rest/event.bind
{
"event": "ONCRMDEALADD",
"handler": "https://your-app.com/webhooks/bitrix/deal-add",
"auth_type": 0
}
При срабатывании события Битрикс24 отправит POST на handler с данными о событии и токеном. Поддерживаемые события для CRM: ONCRMDEALADD, ONCRMDEALUPDATE, ONCRMDEAIDELETED, ONCRM* — аналогично для лидов, контактов, компаний.
Важный нюанс: handler должен отвечать 200 OK в течение 3 секунд. Если ваша обработка занимает больше — немедленно возвращайте 200 и кладите задачу в очередь (RabbitMQ, Redis Streams, SQS):
@app.route('/webhooks/bitrix/deal-add', methods=['POST'])
def handle_deal_add():
data = request.json
task_queue.enqueue(process_new_deal, data) # Async processing
return jsonify({'status': 'accepted'}), 200
Работа с батч-запросами
REST API Битрикс24 имеет лимит 2 запроса в секунду на портал (50 запросов в секунду для платных тарифов). При массовых операциях используйте батч:
POST /rest/batch
{
"halt": 0,
"cmd": {
"get_deal": "crm.deal.get?id=42",
"get_contact": "crm.contact.get?id=17",
"get_company": "crm.company.get?id=5"
}
}
В одном батч-запросе — до 50 команд. При halt=1 выполнение останавливается на первой ошибке.
Многопортальная архитектура
Если приложение обслуживает несколько порталов, структура должна поддерживать изоляцию данных:
/api/v1/{member_id}/sync — синхронизация данных портала
/webhooks/{member_id}/event — приём событий от конкретного портала
Использование member_id в URL — удобный паттерн, но убедитесь, что нет IDOR-уязвимостей: проверяйте подпись запроса или авторизацию перед обработкой.
Сроки разработки
| Тип серверного приложения | Срок |
|---|---|
| Простая интеграция (однонаправленная синхронизация) | 3–7 дней |
| Двусторонняя синхронизация с одной внешней системой | 2–4 недели |
| Многопортальное приложение с Маркетом | 1–3 месяца |
| Enterprise-интеграция (несколько систем, очереди, мониторинг) | 2–6 месяцев |
Основная сложность серверных приложений — не сам REST API, а надёжность: правильная обработка повторных запросов (idempotency), retry-логика при временной недоступности портала, мониторинг истёкших токенов. Эти аспекты занимают 40–60% времени разработки.







