Перейти к основному содержимому

POST /api/messenger/conferences/{conferenceId}/media-token — Обновить токен входа в конференцию

Активный участник запрашивает свежий дескриптор входа в медиа-комнату конференции: короткоживущий AccessToken истекает по ходу длинной встречи, и клиент обновляет его заранее либо после реконнекта. Возвращает MediaJoinModel (дом — messenger-hub.md) без изменения состояния сессии.

Назначение

Продлить присутствие участника в идущей конференции, не заводя новую строку ростера: выдать новый токен доступа и актуальные параметры входа (SignalingUrl, IceServers, ExpiresAt). Нужен для длинных встреч (истечение TTL) и сетевых реконнектов. Owning-сервис — messenger, feature group conferences. Аналог для 1:1 — ../calls/media-token.md.

Metadata

ПолеЗначение
Сервис/контекстmessenger
API areaconferences
Feature groupconferences
Статусdraft
Документdocs/06-services/messenger/api/conferences/conference-media-token.md

Актор и доступ

ПроверкаЗначение
Actor typeUser — активный участник конференции (State = Joined)
Auth policy / Permissionspermission messenger.conferences.use
Scope (RBAC)не применяется — доступ по членству в чате
Record-levelактивная строка ростера актора (Joined) и членство в Deal-чате (INV-CHAT-4)
Tenant isolationне применяется (кросс-tenant); срез — по членству
Auditвыдача токена доступа (Sensitive) — факт выпуска логируется без значения токена

HTTP-контракт

ПолеЗначение
MethodPOST
Route/api/messenger/conferences/{conferenceId}/media-token
Success status200 (OK)
Idempotency headerне применяется — каждый вызов минтит новый короткоживущий токен (состояние сессии не меняется)
Correlationсквозной trace через traceparent

Входные данные / параметры запроса

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
ConferenceIdrouteGuidДа!= Empty; конференция в Active, актор — активный участник (шаги 3–4)
ActorUserIdidentity claimsGuidДаиз JWT; строка ростера актора со State = Joined

Тела запроса нет.

Модель ответа MediaTokenModel

Обёртка над дескриптором входа: единственное поле Room (тип MediaJoinModel, дом — messenger-hub.md).

ПолеТипОбязательностьИсточникMaskingОписание
RoomMediaJoinModelДавычисляетсяSensitive: AccessToken/TURN-креды не логируютсяСвежий дескриптор: RoomName, AccessToken (короткий TTL), SignalingUrl, MediaDomain, IceServers, ExpiresAt.

RoomName/MediaDomain берутся из персистентного MediaRoom; AccessToken/TURN-креды — эфемерные, минтятся на запрос и в БД не хранятся (INV-CONF-7).

Предусловия и постусловия

Предусловия. Актор авторизован и имеет messenger.conferences.use; флаг CONFERENCE_CALLS_ENABLED включён. Конференция существует и в статусе Active (INV-CONF-4). Актор — активный участник Deal-чата (INV-CHAT-4) и имеет строку ростера со State = Joined (уже вошёл через join-conference.md).

Постусловия. Состояние сессии и ростер не изменены (чтение + выпуск токена). Актору выдан новый эфемерный MediaJoinModel со свежим AccessToken/TURN-кредами и ExpiresAt; токен в БД/realtime_outbox не сохранён и в логи не попадает (INV-CONF-7). Realtime-push и Kafka-события не порождаются.

Алгоритм

  1. Контекст и доступ. Операцию выполняет активный участник конференции (User); ActorUserId — из JWT; требуется право messenger.conferences.use. Конференции включены флагом CONFERENCE_CALLS_ENABLED, иначе — MSG_CONFERENCES_DISABLED.
  2. Проверка входа. ConferenceId непустой; иначе ошибка валидации.
  3. Загрузка сессии и доступ. Конференция по ConferenceId; нет → MSG_CONFERENCE_NOT_FOUND. Актор — активный участник Deal-чата (INV-CHAT-4); иначе MSG_CHAT_ACCESS_DENIED. Актор — активный участник самой конференции (строка ростера State = Joined); иначе MSG_CONFERENCE_FORBIDDEN (для первого входа — join-conference.md).
  4. Состояние. Конференция должна быть Active (INV-CONF-4); прочие статусы → MSG_CONFERENCE_NOT_ACTIVE.
  5. Выпуск токена. Минтится новый MediaJoinModel из персистентного MediaRoom (тот же RoomName) со свежим AccessToken/TURN-кредами и ExpiresAt. Состояние сессии и ростер не меняются (чтение + выпуск токена).
  6. Результат. MediaTokenModel { Room } → HTTP 200 OK. Токен эфемерный, не персистится, в логи не пишется.

Побочные эффекты

ТипДетали
Integration eventsnone
Realtime push (hub)none — токен возвращается синхронно в ответе
Токены доступановый Room.AccessToken/TURN-креды минтятся на запрос, в БД/realtime_outbox не хранятся, не логируются
External callsвыпуск токена доступа к медиа-комнате в media-стеке (SFU)

Ошибки и failure modes

КодHTTP statusУсловиеСообщениеRetry
VALIDATION_FAILED400ConferenceId = Empty«Проверьте параметры запроса»no retry
MSG_CONFERENCE_NOT_FOUND404конференции нет«Конференция не найдена»no retry
MSG_CHAT_ACCESS_DENIED403актор не участник Deal-чата«Нет доступа к конференции»no retry
MSG_CONFERENCE_FORBIDDEN403актор не активный участник конференции (не вошёл)«Сначала присоединитесь к конференции»no retry (join)
MSG_CONFERENCE_NOT_ACTIVE409статус не Active«Конференция уже завершена»no retry (перечитать)
MSG_CONFERENCES_DISABLED503CONFERENCE_CALLS_ENABLED = false«Конференции временно недоступны»retry позже

Acceptance Criteria

  • Обновление токена (happy). Дано: актор — активный участник (State = Joined) идущей Active-конференции. Когда запрашивает media-token. Тогда 200 с новым Room.AccessToken и ExpiresAt в будущем; предыдущий токен не отзывается сервером (истечёт по TTL), строка ростера не меняется.
  • Реконнект. Дано: у актора истёк AccessToken после разрыва сети, строка ростера ещё Joined. Когда запрашивает media-token. Тогда 200 со свежим дескриптором — без повторного join (новой строки ростера не заводится).
  • Ещё не вошёл. Дано: актор — участник Deal-чата, но строки ростера Joined у него нет. Когда запрашивает media-token. Тогда 403 MSG_CONFERENCE_FORBIDDEN (сначала join).
  • Не участник чата. Дано: актор не активный участник Deal-чата. Когда запрашивает media-token. Тогда 403 MSG_CHAT_ACCESS_DENIED.
  • Конференция завершена. Дано: конференция в Ended/Failed. Когда актор запрашивает media-token. Тогда 409 MSG_CONFERENCE_NOT_ACTIVE.
  • Флаг выключен. Дано: CONFERENCE_CALLS_ENABLED = false. Когда актор запрашивает media-token. Тогда 503 MSG_CONFERENCES_DISABLED.

Совместимость и наблюдаемость

  • Новые optional поля дескриптора — additive; смена маршрута/семантики — breaking. Kafka-контракта нет.
  • Logs: conference media-token issued (ConferenceId, ActorUserId, ExpiresAt; сам токен — никогда в логи); metrics: messenger_conference_media_token_total{result}, latency p95; traces — сквозной trace (traceparent); dashboard pin-messenger.

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные документы