Realtime Services API

Realtime Services API (RTS API) — это один из наших API, который позволяет в реальном времени получать обновления, происходящие в Carrot quest. Этот API используется (в том числе) в наших официальных клиентах и приложениях.

Введение

Realtime Services API использует протокол WebSocket, чтобы доставлять сообщения в реальном времени.

Когда в Carrot quest происходит какая-то активность (например, новое сообщение в диалоге, начало нового диалога пользователем, совершение определенного события и т.д.), мы отправляем уведомление (сообщение) об этом. Таких сообщений может быть достаточно много. Чтобы иметь возможность получать только нужные сообщения, они сгруппированы в каналы.

При подключении нужно указать каналы, на которые вы хотите подписаться. Например, можно подписаться только на канал с уведомлениями о совершении определенного события и/или канал с уведомлениями о новых диалогах.

Подключение

URL для подключения выглядит следующим образом:

wss://realtime-services.carrotquest.io/websocket/channel1/channel2
  • wss - защищенный протокол WebSocket (WS secure). Также можно использовать (но мы не рекомендуем так делать) незащищенный протокол ws.
  • realtime-services.carrotquest.io/websocket - базовая точка доступа
  • channel1, channel2 - каналы, на которые вы хотите подписаться. В одном соединении можно указать не более 50 каналов.
  • Можно добавить дополнительные параметры tag и time (см. раздел переподключение).

Как и другие запросы к API, Realtime Services API требует авторизации. Поддерживаются те же виды авторизации, которые доступны в Web API.

В случае успешного подключения, вы получите HTTP-код 101 в ответ на запрос и в него начнут приходить сообщения.

Ошибки

В случае неуспешного подключения будет возвращен Http-код ответа отличный от 101. Также ошибка может быть дополнительно детализирована первым сообщением в сокете.

Наиболее частые ошибки

Код ошибки Описание
1xxx Отключение сокета, вызванное нарушением соединения, протокола или иной "браузерной" причиной
3401 Токен доступа не указан, невалиден, отозван или истек
3403 Указанный токен доступа не дает прав на получение сообщений из каких-то запрошенных каналов
3500 Внутренняя ошибка сервера
3503 / 503 / 3502 / 502 Сервер временно недоступен или перегружен. Повторите зпрос спустя разумное время
3429 / 429 Слишком высокая частота запросов к серверу

Отслеживание живости WebSocket. Ping

Чтобы отслеживать, что сокет работает без нарушений, мы используем специальные сообщения ping.

Эти сообщения отправляются в сокет, если в него не приходило иных сообщений более 20 секунд. Если сообщения приходили, ping дополнительно не отправляется. В некоторых случаях, ping сообщение может приходить чаще. Мы рекомендуем отслеживать наличие сообщений в сокете, и переподключаться, если дольше 1-2 минут в сокете не было никаких сообщений.

В наших клиентах и приложениях мы показываем уведомление "возможно, интернет-соединение было потеряно", если в течение 2 минут не получали никаких сообщений из сокета.

Важно: Вы должны всегда обрабатывать ping сообщения корректно, даже если вы явно не подписываетесь на канал ping. Мы можем присылать их без подписки на канал.

Сообщения

После успешного подключения вы будете получать сообщения. Все сообщения обернуты в специальный "конверт":

{
    "id": "1234567-0",
    "channel": "user_presence_changed.100",
    "channels": ["user_presence_changed.100"],
    "message": { ... },
    "tag": "1234567-0",
    "time": "Sat, 14 Nov 2015 15:51:54 GMT"
}
  • id: строка или число - содержит уникальный идентификатор сообщения.
  • channel: строка - содержит канал, в который пришло это сообщение.
  • channels: Array[строк] - содержит список каналов, в который изначально было отправлено сообщение.
  • message: Dict - контент сообщения. Все id объектов внутри контента приходят как строки, чтобы решить проблему id_as_string
  • tag: строка или число и time: строка - нужны для корректного переподключения.

Каналы

Каналы, на которые вы можете подписаться, используя Realtime Services API.

Канал Описание
ping Для контроля целостности соединения
user_presence_changed.{app_id} Изменился статус пользователя
admin_presence_changed.{app_id} Изменился статус администратора
conversation.{app_id} Начат новый диалог с пользователем
conversation.{app_id}.{user_id} Начат новый диалог с пользователем
conversation_started_user.{app_id} Пользователь начал новый диалог
conversation_reply.{app_id} Новое сообщение в диалоге
conversation_reply.{app_id}.{user_id} Новое сообщение в диалоге с пользователем
conversation_typing.{app_id} Кто-то печатает в диалоге
conversation_typing.{app_id}.{user_id} Кто-то печатает в диалоге с пользователем
conversation_read.{app_id} Пользователь прочел диалог
conversation_read.{app_id}.{user_id} Пользователь {user_id} прочел диалог
conversation_assigned.{app_id} Диалог был назначен
conversation_closed.{app_id} Диалог был закрыт
conversation_tag_added.{app_id} К диалогу добавлен тег
conversation_tag_deleted.{app_id} У диалога удален тег
user_props_changed.{app_id}.{user_id} Обновились свойства пользователя
event.{app_id}.{user_id} Пользователь {user_id} совершил событие

Переподключение

Подключение не получится держать постоянно. Иногда его разрывает сервер (например, для обновления или переключения на резервную систему), иногда - клиент (если считает, что соединение "подвисло" или произошла сетевая ошибка, или по другой причине).

С момента отключения и до момента следующего подключения пройдет некоторое время. В этот промежуток времени тоже могут прийти сообщения. Чтобы не потерять их, при следующем подключении нужно добавить GET-параметры tag и time.

Эти параметры берутся из последнего сообщения.

Например, если вы получили сообщение с параметрами tag и time из примера выше, то следующий запрос будет:

wss://realtime-services.carrotquest.io/websocket/channel1/channel2?auth_token=XXX&tag=1234567-0&time=Sat%2C%2014%20Nov%202015%2015%3A51%3A54%20GMT

Обратите внимание, что параметры tag и time должны быть URL-кодированы.

Если подключиться не удалось, повторную попытку стоит делать, выдержав небольшой таймаут (20-30 секунд), чтобы не создавать "снежный ком" из запросов, в случае отказа сервера.

Примечание: сервер хранит историю сообщений за последние 3 минуты, что обычно позволяет восстановить соединение без потерь. В случае, если соединение не получало данные более 3 минут, рекомендуем запросить необходимые данные, используя Web API.