Перейти к содержимому
Разделы

Руководства

Снимок и билет гостевого наблюдения

Получите снимок ресурса и реальный курсор, затем запросите отдельный билет. Нативная проверка WebSocket ещё не завершена.

Начните с ресурса, принадлежащего гостю

Baseline и ticket issuance принимают PREORDER, RESERVATION, WAITLIST и TABLE_SESSION. Сначала получите точный нативный UUID и текущую READ capability в собственном сценарии ресурса. PREORDER указывает на принятый ASAP или scheduled fulfillment. Для QR нужны выданное membership и настоящая сессия. Публичные handles, drafts, join tokens и аккаунт не дают этого READ-доступа.

Канонические исходники содержат HTTP-метод начального снимка, отдельную выдачу билета и описанный здесь протокол public-guest. Нативная проверка WebSocket ещё не завершена. Пример подготавливает данные допуска и кадр сессии; он не открывает WebSocket и не показывает событие из действующего потока.

Получите начальный снимок, затем отдельный билет

Передайте kind, resourceId и действующий приватный capability прямо в теле POST-команды начального снимка. Сервер проверяет фактический Origin браузера, фиксирует реальную позицию журнала, затем повторно проверяет права ресурса перед чтением безопасного текущего снимка. Браузерный код использует credentials: 'omit' и позволяет браузеру передать Origin. Cookie учётной записи, заголовки Authorization и ключи устройства не предоставляют запасную авторизацию.

Входные значения ниже вымышлены. Оба HTTP-ответа должны прийти от вашего действующего авторизованного сервера: код не создаёт подставные cursor, snapshot, ticket или scopeBinding. Он хранит ответы в локальной памяти, не отправляет запрос со страницы документации и подготавливает только кадр протокола, пока нативная проверка WebSocket не завершена.

  1. Получите UUID одного из четырёх поддерживаемых ресурсов Hallify и действующий ключ READ в пределах разрешённого Origin представления.
  2. Сначала прочитайте начальный снимок. Сохраните вместе snapshot, streamId public-guest, точный возвращённый cursor и scopeBinding; выбирайте сгенерированную схему ответа по snapshot.kind.
  3. Выдайте отдельный билет для того же ресурса и ключа. Начальный снимок не выдаёт билет или новый ключ ресурса.
  4. Потребуйте совпадение scopeBinding билета и начального снимка. При изменении прав остановитесь и получите новый снимок, не объединяя разные ответы.
  5. Подготовьте кадр сессии с тем же курсором public-guest и scopeKey из совпавшей привязки, ':' и клиентского контекста длиной от 1 до 128 символов. Для публичного перехода исходного протокола передавайте билет отдельно вместе с hallify.socket.v1.
  6. Храните снимок, курсор и приватный билет в памяти соответствующего сценария. Завершите нативную проверку WebSocket перед признанием исходного протокола проверенным сценарием наблюдения в реальном времени.
Примеры запросов
const resource = {
  kind: 'PREORDER',
  resourceId: '00000000-0000-4000-8000-000000000001',
  capability: 'synthetic-read-capability-for-example-only',
};
const requestOptions = {
  method: 'POST',
  credentials: 'omit',
  cache: 'no-store',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(resource),
} satisfies RequestInit;

const baselineResponse = await fetch(
  'https://api.hallify.co/public/guest-observers/baseline',
  requestOptions
);

if (!baselineResponse.ok) {
  throw new Error(`HTTP ${baselineResponse.status}`);
}

const baseline = await baselineResponse.json();
const validBaseline =
  baseline.streamId === 'public-guest' &&
  typeof baseline.cursor === 'string' &&
  baseline.cursor.length > 0 &&
  typeof baseline.scopeBinding === 'string' &&
  baseline.scopeBinding.length > 0 &&
  baseline.snapshot?.kind === resource.kind;

if (!validBaseline) {
  throw new Error('A current native observer baseline is required.');
}

const snapshot = baseline.snapshot;

const ticketResponse = await fetch(
  'https://api.hallify.co/public/guest-observers/tickets',
  requestOptions
);

if (!ticketResponse.ok) {
  throw new Error(`HTTP ${ticketResponse.status}`);
}

const ticket = await ticketResponse.json();

if (ticket.scopeBinding !== baseline.scopeBinding) {
  throw new Error('Observer authority changed; request a fresh baseline.');
}

const clientContext = 'example-panel';
const upgradeProtocols = ['hallify.socket.v1', ticket.ticket];
const sessionFrame = {
  v: 1,
  kind: 'session',
  scopeKey: `${baseline.scopeBinding}:${clientContext}`,
  streams: [baseline.streamId],
  cursors: { [baseline.streamId]: baseline.cursor },
};

Соблюдайте сроки допуска и права ресурса

Начальный снимок содержит безопасное текущее состояние и не заменяет бизнес-ключ ресурса. PREORDER предоставляет разрешённые статус и расписание исполнения, RESERVATION — статус бронирования, число гостей и время, WAITLIST — статус и необязательное окно принятия, TABLE_SESSION — разрешённое участие, подписи слота и эпохи доступа. Другие бизнес-данные остаются у методов соответствующего домена.

Путь перехода в исходниках — /socket/public. Передавайте ровно hallify.socket.v1 и отдельный приватный билет gpot1_; сервер выбирает только стабильный протокол. После ready кадр сессии подписывается только на public-guest и передаёт неизменённый курсор начального снимка под тем же ключом потока. cursor и scopeBinding определяют контекст ресурса и прав; сами они не предоставляют доступ. Руководство не исполняет WebSocket и не содержит примера действующего события.

База данных задаёт expiresAt билета не более чем на 30 секунд и не позднее текущих сроков ресурса или представления. Это срок одноразового допуска, а не текущего разрешения на наблюдение. Использованный или просроченный билет не разрешает ещё одно подключение. Не создавайте очередь или предварительный запас: для одного ключа допускается не более шести ожидающих билетов, а при 429 нужно соблюдать Retry-After.

Если начальный снимок возвращает 503, остановитесь без подставного курсора. При resyncRequired или изменении прав ресурса получите новый снимок; для нового перехода нужен отдельный совпадающий билет. Не переносите курсор между ресурсами и ключами. Отозванные, заменённые, удалённые, предназначенные только для повтора и неклассифицированные источники не восстанавливают права старым снимком. Билет не разрешает команды бронирования, заказа, решения сотрудника или оплаты.

Храните ключи внутри гостевого сценария

Не помещайте ключи ресурсов и билеты в URL, cookie, Redux, журналы, аналитику и содержимое ошибок. Приватные снимки и курсоры должны оставаться в контексте соответствующего ресурса. Оба HTTP-ответа используют Cache-Control: no-store. Храните курсор вместе с точными ресурсом, снимком и scopeBinding; не декодируйте, не создавайте и не исправляйте его самостоятельно. Начальный выбор представления использует x-hallify-connection-id только в методах, где он объявлен; команды наблюдения используют права, уже зафиксированные в доступе ресурса.

JOIN не является observer resource. SDK раскрывает HTTP baseline/ticket methods без вымышленного автоматического WebSocket client или polling loop. Виджет использует тот же сохранённый нативный READ-доступ; observer traffic не даёт финансовых прав. Native WebSocket, browser/live и production-квалификации отделены от HTTP helpers и source-поставки.

Hallify использует обязательные cookies и опциональную аналитику.

Обязательные cookies поддерживают вход, язык и тему. Аналитика выключена, пока вы явно ее не разрешите.