Интеграция с СЭД и CRM

EasyDocs позволяет настроить интеграции с системами электронного документооборота (СЭД) или системами управления клиентами (CRM). Основные сценарии интеграции - это получение документа из СЭД или CRM на подпись в EasyDocs, где документ проходит согласование и подписание в соответствии с установленным маршрутом и, после завершения документооборота, возвращает в СЭД или CRM статус с результатом подписания.

Интеграция EasyDocs с 1С: Документооборот

Используя документацию API разработчики 1С могут настроить интеграцию с 1С Документооборот.

  1. Внутри документа 1С будет доступна отправка печатной формы в EasyDocs
  2. Получатель документа определится автоматически по контрагенту, указанному в документе 1С
  3. При отправке печатной формы потребуется заполнить маршрут Если выбран маршрут «… с подписантом», дополнительно потребуется заполнить поле «Подписант» (генеральный директор, индивидуальный предприниматель или дополнительные подписанты)
  4. Если маршрут документооборота завершен, подписанный pdf будет прикреплен «под скрепку» к документу 1С, из которого осуществлялась его отправка

Интеграция EasyDocs с Битрикс24

1. Предварительные требования

1.1 Битрикс24

1.2 EasyDocs

1.3 Middleware

2. Настройка Битрикс24

2.1 Создание входящего вебхука

Входящий вебхук используется Middleware для вызова методов REST API Битрикс24 (скачать файл, загрузить подписанный файл, отправить уведомление).

https://<your-portal>.bitrix24.ru/rest/<user_id>/<webhook_code>/

⚠ Примечание: Webhook URL является конфиденциальным. Храните его в переменных окружения, не в исходном коде.

2.2 Создание исходящего вебхука

Исходящий вебхук отправляет POST-запрос на ваш сервер при наступлении события в Битрикс24 (например, загрузка нового файла на Диск, смена статуса сделки и т.п.).

Пример тела запроса, который Битрикс24 пришлёт на ваш обработчик:

{

"event": "ONDISKFILEADD",

"data": { "FIELDS": { "ID": "9043" } },

"auth": {

"domain": "your-portal.bitrix24.ru",

"client_endpoint": "https://your-portal.bitrix24.ru/rest/",

"application_token": "xxx"

}

}

3. Настройка EasyDocs

3.1 Параметры подключения


Base URL https://internal-api.easydocs.ru/ Документация (Swagger) https://internal-api.easydocs.ru/docs/tech.html Аутентификация API-ключ в заголовке Authorization Content-Type application/json


Заголовок авторизации для всех запросов к EasyDocs:

Authorization: Bearer <your_easydocs_api_key>

Content-Type: application/json

3.2 Настройка callback-URL

В настройках интеграции EasyDocs укажите URL вашего Middleware, на который EasyDocs будет отправлять POST-уведомления о смене статуса документа:

https://<your-middleware>/easydocs/callback

⚠ Примечание: Точное место настройки callback URL уточните в документации EasyDocs (раздел Webhooks / Интеграции) или в поддержке EasyDocs.

4. Реализация интеграции

4.1 Шаг 1: Получение файла из Битрикс24

После получения события (исходящий вебхук) Middleware получает ID файла и запрашивает его параметры методом disk.file.get.

Метод: disk.file.get

POST https://<portal>.bitrix24.ru/rest/<uid>/<webhook>/disk.file.get

{

"id": 9043

}

Ответ содержит DOWNLOAD_URL --- временную ссылку для скачивания файла:

{

"result": {

"ID": "9043",

"NAME": "contract.pdf",

"SIZE": "102400",

"PARENT_ID": "8996",

"STORAGE_ID": "1357",

"DOWNLOAD_URL": "https://<portal>.bitrix24.ru/rest/download.json?auth=...&token=..."

}

}

Скачайте файл с DOWNLOAD_URL (GET-запрос, токен действует ограниченное время):

# Python-пример

import requests

def download_from_bitrix(download_url: str) -> bytes:

resp = requests.get(download_url, timeout=60)

resp.raise_for_status()

return resp.content

⚠ Примечание: DOWNLOAD_URL содержит токен с ограниченным сроком действия. Скачивайте файл сразу после получения ссылки, не кэшируйте URL.

4.2 Шаг 2: Отправка файла в EasyDocs на подпись

Передайте содержимое файла в EasyDocs API. Файл кодируется в Base64 и включается в тело запроса (либо загружается multipart/form-data --- уточните по Swagger).

Эндпоинт: POST /api/v1/documents (уточнить по Swagger)

POST https://internal-api.easydocs.ru/api/v1/documents

Authorization: Bearer <api_key>

Content-Type: application/json

{

"name": "contract.pdf",

"file_content": "<base64-encoded-content>",

"file_name": "contract.pdf",

"route_id": "<signing_route_id>",

"external_id": "b24-file-9043",

"callback_url": "https://<your-middleware>/easydocs/callback"

}

Ответ EasyDocs содержит идентификатор документа:

{

"id": "ed-doc-uuid-1234",

"status": "pending",

"name": "contract.pdf",

"created_at": "2025-06-01T10:00:00Z"

}

Сохраните маппинг в БД:

# Псевдокод

db.save({

"easydocs_doc_id": "ed-doc-uuid-1234",

"bitrix_file_id": 9043,

"bitrix_folder_id": 8996,

"bitrix_file_name": "contract.pdf",

"status": "pending",

"created_at": datetime.utcnow()

})

Параметры запроса к EasyDocs


Параметр Тип Описание name string Имя документа (отображается в EasyDocs) file_content string (base64) Содержимое файла, закодированное в Base64 file_name string Имя файла с расширением (например, contract.pdf) route_id string ID маршрута согласования/подписания в EasyDocs external_id string Ваш внешний идентификатор (для связи с Битрикс24) callback_url string URL Middleware для получения уведомлений о статусе


⚠ Примечание: Точные названия полей уточните в Swagger-документации EasyDocs по адресу https://internal-api.easydocs.ru/docs/tech.html

4.3 Шаг 3: Обработка callback от EasyDocs

EasyDocs отправляет POST-запрос на callback_url при каждой смене статуса документа. Middleware должен обработать два конечных статуса:

Пример callback-запроса от EasyDocs:

POST https://<your-middleware>/easydocs/callback

Content-Type: application/json

X-EasyDocs-Signature: <hmac_signature>

{

"event": "document.status_changed",

"document_id": "ed-doc-uuid-1234",

"external_id": "b24-file-9043",

"status": "signed",

"signed_file_url": "https://internal-api.easydocs.ru/documents/ed-doc-uuid-1234/download",

"timestamp": "2025-06-01T12:30:00Z"

}

Callback-обработчик должен:

# Python / FastAPI --- пример обработчика

@app.post('/easydocs/callback')

async def easydocs_callback(request: Request):

body = await request.json()

# 1. Верификация подписи

verify_signature(request.headers, body)

# 2. Немедленный ответ 200

task_queue.enqueue(process_easydocs_event, body)

return {'ok': True}

4.4 Шаг 4a: Загрузка подписанного файла в Битрикс24

Если статус signed: скачайте подписанный файл из EasyDocs и загрузите его на Диск Битрикс24 методом disk.folder.uploadfile.

4a.1 --- Скачать подписанный файл из EasyDocs

GET https://internal-api.easydocs.ru/documents/<doc_id>/download

Authorization: Bearer <api_key>

→ Бинарное содержимое файла (PDF)

4a.2 --- Загрузить в Битрикс24 (disk.folder.uploadfile)

Загрузка через Base64 (для файлов до ~10 МБ):

POST https://<portal>.bitrix24.ru/rest/<uid>/<webhook>/disk.folder.uploadfile

{

"id": 8996,

"data": { "NAME": "contract_signed.pdf" },

"fileContent": [

"contract_signed.pdf",

"<base64-encoded-signed-file>"

],

"generateUniqueName": true

}

Для файлов более ~10 МБ используйте двухэтапную загрузку через UploadUrl:

# Шаг 1: получить UploadUrl

POST .../disk.folder.uploadfile

{ "id": 8996 }

→ { "result": { "uploadUrl": "https://...", "field": "file" } }

# Шаг 2: загрузить файл multipart/form-data на uploadUrl

POST <uploadUrl>

Content-Type: multipart/form-data

file=@contract_signed.pdf

Ответ disk.folder.uploadfile содержит ID нового файла на Диске:

{

"result": {

"ID": 9100,

"NAME": "contract_signed.pdf",

"DOWNLOAD_URL": "https://...",

"DETAIL_URL": "https://..."

}

}

4.5 Шаг 4b: Уведомление об отклонении

Если статус rejected --- отправьте уведомление в Битрикс24. Варианты:

Вариант 1: Уведомление через im.notify

POST .../im.notify

{

"to": <user_id>,

"message": "Документ contract.pdf отклонён в EasyDocs.",

"type": "SYSTEM"

}

Вариант 2: Комментарий в таймлайне CRM (crm.timeline.comment.add)

POST .../crm.timeline.comment.add

{

"fields": {

"ENTITY_TYPE": "deal",

"ENTITY_ID": <deal_id>,

"COMMENT": "Документ contract.pdf отклонён в EasyDocs."

}

}

⚠ Примечание: Сохраните связь между файлом Битрикс24 и сущностью CRM (сделка, контакт и т.п.) на момент отправки, чтобы корректно добавить комментарий.

5. Полный цикл --- псевдокод

# === ШАГ 1: обработка вебхука от Битрикс24 ===

def handle_bitrix_webhook(event_data):

file_id = event_data['data']['FIELDS']['ID']

# 2. Получить параметры файла

file_info = bitrix_call('disk.file.get', {'id': file_id})

download_url = file_info['DOWNLOAD_URL']

file_name = file_info['NAME']

folder_id = file_info['PARENT_ID']

# 3. Скачать файл

file_bytes = requests.get(download_url).content

file_b64 = base64.b64encode(file_bytes).decode()

# 4. Отправить в EasyDocs

ed_doc = easydocs_post('/api/v1/documents', {

'name': file_name,

'file_content': file_b64,

'file_name': file_name,

'route_id': ROUTE_ID,

'external_id': f'b24-{file_id}',

'callback_url': CALLBACK_URL

})

# 5. Сохранить маппинг

db.save(easydocs_id=ed_doc['id'], bitrix_file_id=file_id,

folder_id=folder_id, file_name=file_name)

# === ШАГ 2: обработка callback от EasyDocs ===

def process_easydocs_event(event):

mapping = db.get(easydocs_id=event['document_id'])

if event['status'] == 'signed':

# Скачать подписанный файл

signed_bytes = easydocs_get(event['signed_file_url'])

signed_b64 = base64.b64encode(signed_bytes).decode()

signed_name = mapping.file_name.replace('.pdf', '_signed.pdf')

# Загрузить в Битрикс24

bitrix_call('disk.folder.uploadfile', {

'id': mapping.folder_id,

'data': {'NAME': signed_name},

'fileContent': [signed_name, signed_b64],

'generateUniqueName': True

})

db.update(easydocs_id=event['document_id'], status='signed')

elif event['status'] in ('rejected', 'declined'):

# Уведомить ответственного

bitrix_call('im.notify', {

'to': mapping.responsible_user_id,

'message': f"{mapping.file_name} отклонён в EasyDocs.",

'type': 'SYSTEM'

})

db.update(easydocs_id=event['document_id'], status='rejected')

6. Справочник используемых методов Битрикс24


Метод Scope Назначение disk.file.get disk Получить параметры файла, в т.ч. DOWNLOAD_URL disk.folder.uploadfile disk Загрузить файл в папку (Base64 или multipart) disk.storage.getchildren disk Получить список файлов в хранилище disk.folder.getchildren disk Получить список файлов в папке im.notify im Отправить уведомление пользователю crm.timeline.comment.add crm Добавить комментарий в таймлайн CRM event.bind --- Подписаться на событие программно (в приложении)


6.1 Входящий вебхук --- формат URL

https://<portal>.bitrix24.ru/rest/<user_id>/<webhook_code>/<method>

Пример:

https://mycompany.bitrix24.ru/rest/1/abc123xyz/disk.file.get

6.2 Авторизация через OAuth (для приложения)

Если интеграция реализуется как полноценное приложение Битрикс24, используйте OAuth 2.0 вместо вебхука --- для поддержки refresh_token и работы на нескольких порталах. Подробности: https://apidocs.bitrix24.ru/settings/oauth/

7. Обработка ошибок и повторные попытки

7.1 Ошибки Битрикс24


Код ошибки HTTP Рекомендация QUERY_LIMIT_EXCEEDED 503 Пауза 10 сек, повторить запрос (exponential backoff) OPERATION_TIME_LIMIT 429 Пауза 10 мин (автоснятие блокировки) ACCESS_DENIED 403 Проверить scope вебхука и права пользователя ERROR_NOT_FOUND 400 Файл не найден --- проверить ID файла NO_AUTH_FOUND 401 Неверный вебхук-код или истёк access_token expired_token 401 Обновить access_token через refresh_token (OAuth)


7.2 Ошибки EasyDocs

Для ошибок EasyDocs API реализуйте:

7.3 Идемпотентность callback

EasyDocs может прислать один callback несколько раз (at-least-once delivery). Проверяйте статус документа в БД перед обработкой:

def process_easydocs_event(event):

mapping = db.get(easydocs_id=event['document_id'])

if mapping.status in ('signed', 'rejected'):

return # уже обработано, пропустить

# ... основная логика ...

8. Безопасность


Угроза Меры защиты Реализация Перехват вебхука Битрикс24 HTTPS + верификация application_token Проверять auth.application_token в заголовке Поддельный callback от EasyDocs HMAC-подпись (X-EasyDocs-Signature) Сверять подпись с секретом; отклонять невалидные Утечка credentials Переменные окружения, secrets manager Не хранить ключи в коде/репозитории DOWNLOAD_URL кэширование Использовать сразу после получения URL содержит одноразовый токен с TTL Переполнение очереди Rate limiting на callback-эндпоинте Nginx/API Gateway: max 100 req/min


9. Тестирование

9.1 Проверка вебхуков Битрикс24

Воспользуйтесь встроенным инструментом в разделе Разработчикам → Входящий вебхук → Выполнить, или используйте curl:

curl -X POST \

-H "Content-Type: application/json" \

-d '{"id": 9043}' \

https://<portal>.bitrix24.ru/rest/<uid>/<webhook>/disk.file.get

9.2 Симуляция callback от EasyDocs

Для локального тестирования используйте ngrok для проброса порта и симулируйте callback вручную:

curl -X POST https://<ngrok-url>/easydocs/callback \

-H "Content-Type: application/json" \

-H "X-EasyDocs-Signature: <test_signature>" \

-d '{

"event": "document.status_changed",

"document_id": "ed-doc-uuid-1234",

"status": "signed",

"signed_file_url": "https://..."

}'

9.3 Чеклист перед запуском

10. Ссылки


EasyDocs API (Swagger) https://internal-api.easydocs.ru/docs/tech.html Битрикс24 REST API https://apidocs.bitrix24.ru/ disk.file.get https://apidocs.bitrix24.ru/api-reference/disk/file/disk-file-get.html disk.folder.uploadfile https://apidocs.bitrix24.ru/api-reference/disk/folder/disk-folder-upload-file.html Как загрузить файлы https://apidocs.bitrix24.ru/api-reference/files/how-to-upload-files.html Вебхуки Битрикс24 https://apidocs.bitrix24.ru/local-integrations/local-webhooks.html Лимиты REST API Битрикс24 https://apidocs.bitrix24.ru/limits.html im.notify https://apidocs.bitrix24.ru/api-reference/chats/