Интеграция с локерами: протокол обмена с системой замков
Документ описывает, как UnSpot обменивается данными с внешней системой управления электронными замками локеров. Он адресован интеграторам и поставщикам оборудования: чтобы замки заработали с локерами UnSpot, система замков должна предоставить четыре эндпоинта в описанном ниже формате. Как подключить уже готовую систему из интерфейса администратора, описано в статье «Настройка интеграции с локерами: Pocket Lock».
Как устроен обмен
Обмен односторонний: инициатор всегда UnSpot. Система замков только отвечает на запросы — обратных вызовов, вебхуков и подписок на события в этой интеграции нет. Запросы отправляет сервер приложения UnSpot, а не браузер администратора, поэтому доступность адреса нужно проверять именно с серверов UnSpot.

Базовый адрес — значение, введённое администратором в поле «Хост» при подключении интеграции; UnSpot дописывает к нему путь эндпоинта. Ни схема, ни порт, ни версия пути не подставляются автоматически — адрес используется ровно в том виде, в каком он сохранён, за вычетом завершающего слэша.
| Что происходит в UnSpot | Какой запрос уходит |
|---|---|
| Администратор сохраняет настройки подключения | GET /api/v1/status — так проверяются адрес и токен |
| Администратор открывает редактор карты локера | GET /api/v1/status — из ответа строится список ячеек для привязки |
| Администратор сохраняет карту локера, назначив ячейке ячейку системы замков | GET /api/v1/status — обновление сохранённых состояний, фоновой задачей и потому с небольшой задержкой |
| Сотрудник нажимает «Открыть ячейку» | POST /api/v1/pulse |
| Служебная команда unspot:sync-external-locker-cell-states и сценарии обслуживания | POST /api/v1/open, POST /api/v1/close |
Что учитывать. Фонового опроса по расписанию нет: между перечисленными событиями UnSpot к системе замков не обращается и сохранённые состояния ячеек не обновляет.
Аутентификация
Токен, введённый администратором в поле «Токен авторизации», передаётся в каждом запросе одним заголовком:
Authorization: Bearer <token>HTTPS- схема одна — Bearer. Basic-аутентификация, ключ в строке запроса, взаимный TLS и получение токена отдельным запросом не поддерживаются;
- токен один на всё рабочее пространство: отдельных токенов на офис, локер или ячейку нет;
- длина значения — до 255 символов. Для поля «Хост» интерфейс требует не менее 4 символов, серверная проверка — не менее 2;
- ротация токена на стороне системы замков требует переподключения интеграции в интерфейсе UnSpot: старое значение перестанет работать сразу, а обновить его иначе как переподключением нельзя.
Запросы, которые отправляет UnSpot
Всего запросов четыре. Для работы интеграции обязательны два — status и pulse: именно они обслуживают подключение, список ячеек и открытие замка из интерфейса. Ещё два, open и close, входят в контракт, но текущим интерфейсом не вызываются.
Состояния ячеек — GET /api/v1/status
Единственный запрос на чтение. Возвращает все ячейки системы замков вместе с их состоянием. UnSpot использует его сразу в трёх ролях: как проверку подключения, как источник списка ячеек для привязки и как способ обновить сохранённые состояния.
GET /api/v1/status
Host: lockers.example.com
Authorization: Bearer <token>HTTPSОжидаемый ответ:
{
"id": {
"101": { "status": false },
"102": { "status": true },
"103": { "status": "offline" }
}
}JSON| Поле | Тип | Что означает |
|---|---|---|
| id | объект | Обязательный корневой ключ. Ключи вложенного объекта — идентификаторы ячеек, значения — состояние каждой из них |
| ключ внутри id | число | Идентификатор ячейки в системе замков. Должен быть числовым — нечисловые значения приводят к ошибке при создании ячейки, а не к понятному сообщению валидации |
| status | true, false или строка offline | true — замок открыт; false — замок закрыт; offline — контроллер этой ячейки недоступен |
Что UnSpot делает с ответом:
- показывает в форме ячейки локера только те идентификаторы, которые ещё не привязаны к другим ячейкам UnSpot;
- сохраняет у привязанной ячейки два признака — «открыта» и «замок недоступен»;
- если ранее привязанного идентификатора в ответе больше нет, привязка сохраняется, но состояние такой ячейки перестаёт обновляться, а в журнал сервера UnSpot пишется предупреждение.
Что учитывать. Отсутствие корневого ключа id UnSpot считает ошибкой протокола, а не пустым списком: подключение в этом случае не состоится. Пустой список ячеек передаётся явно — “id”: {}.
Импульс на открытие — POST /api/v1/pulse
Основной рабочий сценарий: замок открывается и через указанное время запирается сам. Именно этот запрос уходит, когда сотрудник нажимает «Открыть ячейку» на странице «Локеры» или в разделе «Мои бронирования».
POST /api/v1/pulse
Host: lockers.example.com
Authorization: Bearer <token>
Content-Type: application/json
{
"id": 101,
"time_ms": 10000
}HTTPS| Поле | Тип | Что содержит |
|---|---|---|
| id | число | Идентификатор ячейки — из ответа GET /api/v1/status |
| time_ms | число | Длительность открытия в миллисекундах. UnSpot всегда передаёт 10000, то есть 10 секунд; в интерфейсе это значение не настраивается |
Система замков должна открыть замок и самостоятельно закрыть его по истечении time_ms. Отдельной команды на закрытие после импульса UnSpot не отправляет.
Открыть и закрыть — POST /api/v1/open, POST /api/v1/close
Две парные команды: первая снимает блокировку и оставляет замок открытым, вторая возвращает блокировку. Тело у обеих одинаковое.
POST /api/v1/open
Host: lockers.example.com
Authorization: Bearer <token>
Content-Type: application/json
{
"id": 101
}HTTPSЧто учитывать. В текущей версии интерфейса UnSpot нет кнопок, которые вызывали бы эти две команды: сотрудникам и администраторам доступен только импульс. Тем не менее оба эндпоинта входят в контракт и проверяются при интеграции — реализовать их нужно.
Требования к системе замков
| Требование | Подробности |
|---|---|
| Четыре эндпоинта | status, pulse, open, close — по путям и методам, указанным выше. Без status и pulse интеграция не работает вовсе; open и close нужны для полноты контракта |
| Bearer-токен | Проверка заголовка Authorization со схемой Bearer. Другие схемы аутентификации UnSpot не отправляет |
| Ответ всегда JSON | Непустое тело, декодируемое в объект или массив, — для всех четырёх запросов, включая open, close и pulse. Ответ без тела (например, 204 или 200 с пустым телом) UnSpot трактует как ошибку и показывает её пользователю |
| Код 2xx на успех | Любой ответ 4xx или 5xx считается ошибкой запроса |
| Числовые идентификаторы | Идентификатор ячейки должен быть числом. Строковые и составные идентификаторы UnSpot корректно не обработает |
| Стабильные идентификаторы | Идентификатор физической ячейки не должен меняться со временем: привязка в UnSpot хранит именно его. Исчезнувший из ответа идентификатор считается потерянной ячейкой |
| Сетевая доступность | Адрес должен быть доступен с серверов приложения UnSpot. Для системы, развёрнутой в сети заказчика, это отдельная задача сетевого администратора |
| Действительный сертификат | При работе по HTTPS сертификат проходит обычную проверку. Самоподписанный сертификат приведёт к ошибке подключения, отключить проверку в UnSpot нельзя |
| Время ответа | Ответ должен укладываться в стандартный таймаут исходящих запросов сервера UnSpot. Долгие ответы выглядят для администратора и сотрудника как недоступность системы |
Чего от системы замков не требуется:
- отправлять события в UnSpot — входящих эндпоинтов для системы замков в UnSpot нет;
- поддерживать пагинацию, фильтры или запрос состояния одной ячейки — список всегда забирается целиком;
- выдавать токен отдельным запросом — токен вводится администратором вручную;
- сообщать, кем занята ячейка, — брони ведутся на стороне UnSpot и системе замков не передаются.
Поведение при сбоях
- Повторов нет. Неудачный запрос не переотправляется: одна ошибка сети сразу превращается в ошибку для пользователя;
- Причина ошибки подключения не детализируется. Недоступный адрес, неверный токен, просроченный сертификат и ответ в неожиданном формате дают администратору один и тот же текст «Удаленный сервер не отвечает. Проверьте правильность введенных данных.» Точную причину видно в журнале сервера UnSpot;
- Сотрудник видит общее сообщение. Если команда не дошла до замка, появляется «Что-то пошло не так. Повторите попытку позднее»;
- Признак «замок недоступен» в интерфейсе не показывается. UnSpot сохраняет его из ответа status, но в списке ячеек для привязки офлайновые ячейки выглядят так же, как рабочие.