Перейти к содержанию

Обновления в реальном времени

Когда обновления включены, открытая вкладка рабочей области или портала показывает изменения без перезагрузки: новый ответ или заметка появляются в открытой заявке (ваш неотправленный черновик остаётся на месте), списки заявок обновляются, счётчик уведомлений и значок боковой панели следуют за колокольчиком, а клиент, смотрящий на своё обращение, видит приход вашего ответа. Рабочая область также показывает, у кого ещё открыта заявка и пишет ли он в ней.

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

Включение обновлений

Установите и включите плагин Sync. В Helpdesk Pro настраивать нечего. Sync предлагает три способа доставки обновлений, и Helpdesk Pro использует тот, который Sync ставит первым:

Транспорт Что нужно Насколько быстро
Опрос Ничего, кроме плагина Sync. Работает всегда. Каждые 4 секунды, пока кто-то пользуется вкладкой (realtime.poll_idle_ms).
Mercure Плагин Sync Mercure 1.2.2 или новее и хаб Mercure. Сразу.
Ably Плагин Sync Ably и учётная запись Ably. Только рабочая область; портал опрашивает. Сразу.

Важно

Sync Mercure 1.2.2 публикует каждое обновление как приватное и не пускает анонимных подписчиков в хаб. Более старый Sync Mercure публиковал бы обновления Helpdesk Pro публично, поэтому при его наличии Helpdesk Pro вообще ничего ему не передаёт: браузеры переходят на опрос, и отчёт о состоянии сообщает об этом в realtime.reason.

Установите realtime.enabled в false, чтобы отключить обновления, не удаляя Sync.

В рабочей области

  • Открытая заявка заново запрашивает переписку и детали, когда приходит обновление о ней. Редактор сохраняет черновик, а переименовываемая тема остаётся такой, как её набрали.
  • Остальные экраны («Моя работа», «Все заявки», «Уведомления») обновляются после окончания серии обновлений, никогда при наличии несохранённых изменений и никогда в фоновой вкладке.
  • Каждое обновление обновляет счётчики: числа в боковом меню, счётчик уведомлений и значок боковой панели Admin Next.
  • Строка присутствия над редактором называет тех, у кого ещё открыта заявка: «Ben is viewing», «Ben is replying…» (неотправленный текст на вкладке Reply), «Ben is writing a note…» (вкладка Note) и «The client is viewing this request».

В портале

На странице «Your requests» и на одном обращении вошедшие клиенты тоже получают обновления. Обновление об открытом обращении заменяет его заголовок и переписку; поле ответа и всё, что в нём набрано, не затрагиваются, а скринридеры слышат «A new reply arrived.» На странице списка список заменяется свежим, если только человек не печатает в поле поиска.

Страница обращения также отправляет сигнал присутствия, поэтому сотрудники видят «The client is viewing this request». Клиенты никогда не видят присутствие сотрудников.

Присутствие

Открытая заявка отправляет сигнал каждые realtime.presence_heartbeat_seconds (15), а также сразу, когда её редактор начинает или перестаёт содержать неотправленный текст. Вкладка, переставшая отправлять сигналы, исчезает через 45 секунд после последнего. Присутствию не нужен плагин Sync: каждый сигнал возвращает других смотрящих заявку. Push-транспорт только делает это быстрее.

  • Присутствие доступно сотрудникам, работающим с проектом заявки. Клиент всегда только «смотрит», никогда не видит никого другого и не получает обновлений присутствия.
  • Сотрудники видят клиента только как «The client is viewing this request».
  • Один человек с несколькими открытыми вкладками показывается один раз, с самым сильным состоянием (отвечает, затем пишет заметку, затем смотрит).
  • Присутствие — предупреждение, а не блокировка. Именно защита от конфликтов останавливает перекрёстные ответы.

Как это работает

У каждого человека есть один приватный канал — его входящий канал. Подписаться на него может только сам человек, и никто не может публиковать в него из браузера. Имена каналов несут тег HMAC под секретом, который хранит сайт, поэтому их нельзя угадать.

Когда в заявке что-то происходит, Helpdesk Pro определяет, кто может об этом услышать, по тем же правилам доступа, что и остальной плагин, оставляет только людей с открытой живой вкладкой и отправляет каждому небольшой кадр в его входящий канал. Вкладка слушает один канал, сколько бы заявок и списков она ни показывала, поэтому опрос стоит одного запроса каждые несколько секунд на открытую вкладку.

Кадры несут идентификаторы, а не содержимое:

{"e": "message.created", "t": 1042, "m": 9981, "at": 1790000000}
Поле Значение
e Событие, например ticket.updated, ticket.status_changed, message.created или attachment.added, либо notification и presence
t id заявки
m id сообщения для событий сообщений и вложений
at Когда произошло (секунды эпохи)
a, v Только для кадров сотрудников: кто это сделал и было ли это public или internal

Затем браузер читает изменения через обычные маршруты с проверкой прав, поэтому кадр, ушедший не туда, не несёт ничего, что стоило бы читать.

Что может передавать канал клиента

Входящий канал клиента несёт кадры только для публичных событий: ответ, публичная веха статуса (решено, открыто снова, закрыто), публичное вложение, новое обращение, в котором он участвует. Внутреннее событие вообще не создаёт кадр для клиента: ни заметка, ни изменение или удаление заметки, ни файл в заметке, ни смена исполнителя или приоритета. Кадр клиента содержит ровно e, t, at и, для ответа, m.

Кто получает кадры

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

При опросе вкладка спрашивает каждые 4 секунды, пока кто-то ею пользуется, каждые 1,5 секунды в течение полуминуты после отправки, постепенно реже (до раза в 15 секунд), когда страницу не трогали две минуты, и каждые 30 секунд в фоне. Оборвавшееся push-соединение возвращается к опросу, пока не переподключится.

Проверка

В отчёте о состоянии (bin/plugin helpdesk-pro status, Operations → System или GET /helpdesk-pro/status) есть блок realtime: enabled, используемый transport, reason, когда его нет (Sync отсутствует или отключён, realtime.enabled выключен, Sync Mercure слишком старый), сколько людей держат открытую живую вкладку (live_listeners) и сколько вкладок прямо сейчас держат открытую заявку (presence_rows).

При опросе можно наблюдать за собственным входящим каналом через curl с токеном рабочей области:

TOKEN=...   # из POST /api/v1/auth/token
curl -s https://example.test/api/v1/helpdesk-pro/live-config -H "X-API-Token: $TOKEN"
curl -s "https://example.test/api/v1/sync/channels/pull?id=<channel>&since=<serverTimeMs>" -H "X-API-Token: $TOKEN"

Настройки

На вкладке Live Updates настроек плагина:

Ключ По умолчанию Что делает
realtime.enabled true Отправлять обновления через плагин Sync, когда он установлен и включён. Присутствие работает в любом случае.
realtime.poll_idle_ms 4000 При опросе — как часто открытая вкладка спрашивает новости, пока кто-то ею пользуется (не менее 1000).
realtime.presence_heartbeat_seconds 15 Как часто открытая заявка отправляет сигнал присутствия (от 5 до 40).

Маршруты

Ни у одного маршрута рабочей области нет инструмента MCP: оба имеют смысл только для открытой вкладки браузера.

Маршрут Право Что делает
GET /helpdesk-pro/live-config desk Живая конфигурация для вашего входящего канала: enabled, channel, transport (polling, mercure или ably), pullUrl, pullPath, mercure, ably, serverTimeMs, pollIdleMs, heartbeatSeconds, refreshSeconds и presencePath. Когда обновления выключены: {enabled: false, reason, …}.
POST /helpdesk-pro/tickets/{id}/presence desk {client_id, state}: собственный случайный id вкладки и viewing, replying, noting или leave. Отвечает {peers: [{person, kind, state, age}]}.
GET {mount}/_live/config Вошедший клиент Та же живая конфигурация для входящего канала посетителя, никогда с Ably, плюс presenceUrl и nonce формы.
POST {mount}/_live/presence Вошедший клиент Сигнал присутствия страницы обращения: ticket_id, client_id, state и nonce helpdesk-portal. Клиент всегда записывается как смотрящий, а ответ всегда {peers: []}.

Портал опрашивает эндпоинт pull-канала Sync (GET /api/v1/sync/channels/pull) напрямую с сессионной cookie сайта; проверка доступа канала позволяет вошедшему клиенту забирать только свой входящий канал.