Bitrix24

Локальные приложения

APIStend играет роль портала Bitrix24: выдаёт OAuth-токены, отдаёт BX24.js и открывает приложение во фрейме — с обработчиком на localhost.

На этой странице · 4

Боевой Bitrix24 обращается к приложению со своей стороны, поэтому требует адрес, доступный ему из внешней сети, по HTTPS и с разрешённым фреймингом. Отсюда обычный цикл разработки: поднять туннель, вписать выданный адрес в карточку приложения, переустановить, повторить после каждого перезапуска туннеля — адрес сменился, а в карточке остался прежний.

APIStend снимает ровно это. Портал живёт на той же машине, что и приложение, фрейм открывает браузер разработчика, http://localhost:3210/handler — законный адрес обработчика. Всё остальное совпадает с боевым: набор полей POST-запроса во фрейм, конверт OAuth, коды ошибок, правило «до installFinish событий и виджетов нет».

Что делает портал

  • Выдаёт токены. Сервер авторизации на /oauth/authorize/ и /oauth/token/ отвечает тем же конвертом, что боевой oauth.bitrix.info.
  • Отдаёт BX24.js. Библиотека лежит на /api/v1/ — том же пути, что у боевого //api.bitrix24.tech/api/v1/, отличается только хост.
  • Открывает приложение во фрейме. Раздел «Локальные приложения» кабинета показывает демонстрационный портал: левое меню, карточка сделки, слайдер. Приложение открывается там же, где откроется в бою.
  • Отвечает на методы состояния. app.info, scope, placement.bind, placement.get, event.bind, event.get отвечают про это конкретное приложение, а не примером из спецификации.

Всё, чего нет в этом списке, уходит в общий движок моков: crm.deal.list, вызванный с токеном приложения, вернёт тот же ответ, что и с ключом песочницы.

Одна строка подмены

- <script src="//api.bitrix24.tech/api/v1/"></script>
+ <script src="http://localhost:8080/api/v1/"></script>
ЧтоБоевой адресАдрес APIStend
REST порталаhttps://<портал>.bitrix24.ru/rest/http://localhost:8080/rest/
Выдача и обновление токеновhttps://oauth.bitrix.info/oauth/token/http://localhost:8080/oauth/token/
Авторизация пользователяhttps://<портал>.bitrix24.ru/oauth/authorize/http://localhost:8080/oauth/authorize/
Библиотека BX24.js//api.bitrix24.tech/api/v1/http://localhost:8080/api/v1/

Хост берётся из APISTEND_PUBLIC_ORIGIN; всё, что портал сообщает приложению — DOMAIN, client_endpoint, server_endpoint, адрес библиотеки — собирается из него.

Приложению, собранному правильно, подменять нечего

SERVER_ENDPOINT приходит в теле POST при открытии фрейма, client_endpoint — в ответе сервера авторизации, хост библиотеки складывается из DOMAIN и PROTOCOL. Приложение, которое читает эти поля, а не зашивает адреса, работает и здесь, и в бою без правок.

REST принимает токен там же, где боевой портал

Метод вызывается по /rest/<метод>, токен кладётся в поле auth тела запроса. Суффикс .json и префикс входящего вебхука /rest/{user_id}/{code}/ отрезаются до маршрутизации, поэтому оба варианта пути работают.

curl -s -X POST http://localhost:8080/rest/app.info \
  -d "auth=$ACCESS_TOKEN"
{
  "result": {
    "ID": 565,
    "CODE": "docprobe",
    "VERSION": 1,
    "STATUS": "L",
    "INSTALLED": true,
    "PAYMENT_EXPIRED": "N",
    "DAYS": null,
    "LANGUAGE_ID": "ru",
    "LICENSE": "ru_demo",
    "LICENSE_TYPE": "demo",
    "LICENSE_FAMILY": "demo"
  },
  "time": { "start": 1788948933.472, "finish": 1788948933.473, "duration": 0.001, "processing": 0, "date_start": "2026-09-09T10:15:33+00:00", "date_finish": "2026-09-09T10:15:33+00:00", "operating": 0 }
}

Ответ в контексте приложения помечен заголовками X-APIStend-Source: app-context и X-APIStend-App с client_id приложения — по ним видно, что отвечал портал, а не движок моков. Обычные методы каталога отвечают как всегда, с X-APIStend-Source: example.

Чего APIStend не воспроизводит

HTTPS. У localhost его нет, и портал честно сообщает PROTOCOL=0. Приложение, которое зашило https://, здесь сломается — и это полезная поломка: она обнаружится на несколько шагов раньше.

Проверку фрейминга. Её делает браузер, а не портал. Если приложение отдаёт X-Frame-Options: SAMEORIGIN или CSP без нужного frame-ancestors, на месте виджета останется пустая область, и портал об этом не узнает — ровно как в бою.

Секретность client_secret. В карточке приложения он показан открыто и копируется кнопкой: это демонстрационный портал, смысл экрана в том, чтобы секрет было видно.

Полный перечень точек встраивания. Боевой список зависит от установленных модулей. APIStend знает подмножество — те точки, у которых есть видимое место в демонстрационном портале. На код вне списка placement.bind отвечает ERROR_PLACEMENT_NOT_FOUND, как и боевой портал.

Связность данных между list и get. Ответы каталога отдаются ярусом «пример из спецификации», поэтому crm.deal.get вернёт сделку из документации, а не ту, что пришла в crm.deal.list. Это свойство всего каталога, а не раздела приложений; контекст вызова при этом настоящий — ID в PLACEMENT_OPTIONS соответствует открытой карточке.

Экран входа и согласия. /oauth/authorize/ выдаёт код сразу, без формы логина: портал демонстрационный, и выбирать, кем войти, нужно в его шапке, а не в OAuth.