Модуль для Апостол CRM.
- WebSocket API предоставляет возможность подключения к API системы по протоколу WebSocket.
Следуйте указаниям по сборке и установке Апостол CRM
Чтобы установить с сервером соединение WebSocket, клиентское приложение должно выполнить «Рукопожатие» («Opening Handshake»), как описано в RFC6455 раздел 4.
Сервер накладывает дополнительные ограничения на URL-адрес и подпротокол WebSocket, подробно описанные ниже.
Чтобы инициировать соединение WebSocket, клиенту требуется URL-адрес RFC3986 для подключения (URL подключения).
Взаимодействие с системой происходит в рамках ранее созданной сессии. Сессия создается после успешной аутентификации пользователя в системе. Результатом которой является получение маркера доступа, идентификатора сессии и секретного ключа.
URL подключения содержит в себе код сессии и идентификатор сеанса связи.
Формат URL подключения:
ws[s]://[ws.]exemple.com/session/<code>[/<identity>]
- Где:
<code>
- Обязательный. Код сессии (40 символов);<identity>
- Необязательный. Идентификатор сеанса связи в рамках сессии. Используется для установки нескольких соединений к одной сессии.
Пример:
wss://ws.exemple.com/session/c83b2f85321f95341707624546ca6ac4fa6d1115
wss://ws.exemple.com/session/c83b2f85321f95341707624546ca6ac4fa6d1115/user1
Протокол WebSocket сам по себе не дает возможности отправлять сообщения в режиме запрос/ответ. Чтобы обеспечить эту возможность был создан небольшой RPC протокол поверх WebSocket в формате JSON.
Ключ | Расшифровка | Тип данных | Назначение, примечания |
---|---|---|---|
t | MessageTypeId | INTEGER | Тип сообщения. Описание ниже. |
u | UniqueId | UUID | Уникальный идентификатор сообщения. Если сообщение от сервера является ответом на запрос от клиента, то UniqueId будет одинаковым. |
a | Action | STRING | Действие (маршрут к конечной точке API). |
c | ErrorCode | INTEGER | Код ошибки. |
m | ErrorMessage | STRING | Сообщение об ошибке. |
p | Payload | JSON | Полезная нагрузка. |
Тип сообщения | Номер типа сообщения | Направление | Описание |
---|---|---|---|
OPEN | 0 | Клиент -> Сервер | Авторизация. Открытие ранее созданной сессии. |
CLOSE | 1 | Клиент -> Сервер | Закрытие сессии (выход из системы). |
CALL | 2 | Клиент <-> Сервер | Запрос. |
CALLRESULT | 3 | Сервер -> Клиент | Ответ на запрос. |
CALLERROR | 4 | Сервер -> Клиент | Ответ на запрос с ошибкой. |
- После подключения клиенты нужно авторизоваться.
Авторизация может быть выполнена в автоматическом режиме при условии, если в момент установки связи были указаны соответствующие HTTP-заголовки:
Authorization: Bearer <token>
Или:
Session: <session>
Secret: <secret>
Если заполнение HTTP-заголовков блокируется на стороне используемого, клиентским приложением, фрейворком, то авторизация выполняется путем отправки пакета OPEN
с данными авторизации (которые выдал сервер авторизации) это может быть или маркер доступа (token
) или секретный код сессии secret
.
После успешной авторизации Вы сможете отправлять API запросы с типом сообщения CALL
. Где маршрут к конечной точке API указывается в ключе Action
, а JSON тело запроса в ключе Payload
.
Попытка отправить запрос до выполнения успешной процедуры авторизации приведет к ответу с типом сообщения CALLERROR
:
Пример:
Если код сессии указан не верно или сессия была закрыта то ответ будет с типом сообщения CALLERROR
:
{"t":4,"u":"<uuid>","c":400,"m":"Код сессии не найден."}
Авторизация по секретному коду сессии:
{"t":0,"u":"<uuid>","p":{"secret": "MWCJ14k/RJyiHskQB8DoVbliiwDeNGKsgsAMugp3OZt+M0Zj44hDykwRuFoWEwuG"}}
Положительный ответ:
{"t":3,"u":"<uuid>","p":{"authorized": true, "code": "amAJmzkxvDE+ad7KwkRtZU1qkUod+3XuycBbxRqHOOjBdeOkkR+lSExI4L8LAcb+", "message": "Успешно."}}
- Где:
code
- Новый код авторизации на получение маркера доступа (не путать с секретным кодом сессии).
Отрицательный ответ:
{"t":4,"u":"<uuid>","c":401,"m":"Выход из системы. Секретный код сессии не прошёл проверку."}
ВНИМАНИЕ: При передаче неверных данных авторизации сессия будет закрыта, но не соединение.
Авторизация по маркеру доступа:
{"t":0,"u":"<uuid>","p":{"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiIDogImFjY291bnRzLnBsdWdtZS5ydSIsICJhdWQiIDogInNlcnZpY2UtcGx1Z21lLnJ1IiwgInN1YiIgOiAiYzgzYjJmODUzMjFmOTUzNDE3MDc2MjQ1NDZjYTZhYzRmYTZkMTExNSIsICJpYXQiIDogMTYwNjIxMDcwNiwgImV4cCIgOiAxNjA2MjE0MzA2fQ.ZI82FKXAgA1CZm3gx9XCpgpq_WyZJvwqYI4nOdccVts"}}
ВНИМАНИЕ: Не забывайте, что маркер доступа имеет ограниченный срок жизни.
Положительный ответ:
{"t":3,"u":"<uuid>","p":{"authorized": true, "message": "Успешно."}}
Отрицательный ответ:
{"t":4,"u":"<uuid>","c":403,"m":"Verification failed: Token expired."}
Предусмотрена возможность отправки произвольных данных клиентскому приложению подключенному по WebSocket.
Для этого нужно отправить на сервер REST API запрос:
POST /ws/<code>[/<identity>]
<anydata>
- Где:
<code>
- Обязательный. Код сессии WebSocket соединения на которое необходимо передать данные;<identity>
- Необязательный. Идентификатор сеанса связи в рамках сессии (при наличии);<anydata>
- Необязательный. Любые данные в произвольном формате.
Данные будут отправлены запросом с типом сообщения CALL
в Action
будет указано значение /ws
в Payload
будут произвольные данные из REST API запроса.
Пример:
POST /ws/8c98085f34c83a0eea5f40791218fbf80f1858d3 HTTP/1.1
Host: localhost:8080
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.[...].9GI82ffkIhbUeWR8if3a8q78nfXAL4AFOMp3kWDTHOA
Content-Type: application/json
{"anydata":null}
Положительный ответ:
{"sent": true, "status": "Success"}
Отрицательный ответ:
{"sent": false, "status": "Session not found"}
-
Для того чтобы получать данные от сервера без предварительных запросов со стороны клиентского приложения нужно подписаться на события.
-
Для того чтобы подписаться на события нужно выбрать издателя и настроить слушателя (установить фильтр и параметры).
Издатель notify
предоставляет возможность подписаться на системные события, которые возникают каждый раз, когда пользователь системы взаимодействует с тем или иным объектом.
Представление JSON для фильтра отбора событий:
{
"entities": enum (string),
"classes": enum (string),
"actions": enum (string),
"methods": enum (string),
"objects": enum (numeric)
}
Поле | Тип | Значение | Описание |
---|---|---|---|
entities | JSON array | Коды | Необязательный. Сущность. Массив кодов. |
classes | JSON array | Коды | Необязательный. Класс. Массив кодов. |
actions | JSON array | Коды | Необязательный. Действие. Массив кодов. |
methods | JSON array | Коды | Необязательный. Метод. Массив кодов. |
objects | JSON array | Идентификаторы | Необязательный. Объекты. Массив идентификаторов. |
ВАЖНО: Фильтр по полям работает по условию И
, по значением в поле по условию ИЛИ
.
ВАЖНО: Поля в которых не заданы значения игнорируются.
Представление JSON параметров:
{
"type": string,
"hook": Hook
}
Поле | Тип | Значение | Описание |
---|---|---|---|
type | STRING | notify, object, mixed, hook | Необязательный. Тип ответа. |
hook | JSON | Hook | Обязательный для типа hook. Ловушка. |
- Если указать
notify
, то в ответ будут приходить сами уведомления. - Если указать
object
, то в ответ будут приходить данные объекта в формате /get запроса. - Если указать
mixed
, то в ответ будут приходить и сами уведомления и данные объекта в формате /get запроса. - Если указать
hook
, то ответом будет результат выполнения API запроса изHook
.
Ловушка задает параметры выполнения запроса API. При каждом выполнении условий подписки ответом будут данные из запроса ловушки.
{
"method": string,
"path": string,
"payload": json
}
Поле | Тип | Значение | Описание |
---|---|---|---|
method | STRING | POST, GET | Необязательный. HTTP-метод. |
path | STRING | Обязательный. REST API путь к конечной точке. | |
payload | JSON | Hook | Вариативный. Полезная нагрузка. Зависит от запроса. |
Издатель notice
предоставляет возможность подписаться на системные извещения.
Представление JSON для фильтра отбора событий:
{
"categories": enum (string)
}
Поле | Тип | Значение | Описание |
---|---|---|---|
categories | JSON array | Коды (строка) | Необязательный. Категория. |
ВАЖНО: Фильтр по полям работает по условию И
, по значением в поле по условию ИЛИ
.
ВАЖНО: Поля в которых не заданы значения игнорируются.
Представление JSON параметров:
{
"type": string
}
Поле | Тип | Значение | Описание |
---|---|---|---|
type | STRING | notify | Необязательный. Тип ответа. |
Издатель message
предоставляет возможность подписаться на входящие и исходящие сообщения.
Представление JSON для фильтра отбора событий:
{
"classes": enum (string)
"types": enum (string)
"agents": enum (string)
"codes": enum (string)
"profiles": enum (string)
"addresses": enum (string)
"subjects": enum (string)
}
Поле | Тип | Значение | Описание |
---|---|---|---|
classes | JSON array | inbox, outbox | Необязательный. Класс сообщения (входящее или исходящее). |
types | JSON array | Коды (строка) | Необязательный. Код типа агента. |
agents | JSON array | Коды (строка) | Необязательный. Код агента. |
codes | JSON array | Коды (строка) | Необязательный. Код сообщения. |
profiles | JSON array | Необязательный. Профиль настроек. Используется для определения профиля настроек сообщения или адреса отправителя. | |
addresses | JSON array | Необязательный. Адрес получателя. Для API запросов - это маршрут REST API. | |
subjects | JSON array | Необязательный. Тема сообщения. |
ВАЖНО: Фильтр по полям работает по условию И
, по значением в поле по условию ИЛИ
.
ВАЖНО: Поля в которых не заданы значения игнорируются.
Представление JSON параметров:
{
"type": string
}
Поле | Тип | Значение | Описание |
---|---|---|---|
type | STRING | notify | Необязательный. Тип ответа. |
Издатель log
предоставляет возможность подписаться на журнал событий.
Представление JSON для фильтра отбора событий:
{
"types": enum (string),
"codes": enum (integer),
"categories": enum (string)
}
Поле | Тип | Значение | Описание |
---|---|---|---|
types | JSON array | M, W, E, D | Необязательный. Тип: Message, Warning, Error, Debug. |
codes | JSON array | Коды (число) | Необязательный. Код. Натуральное число. |
categories | JSON array | Коды (строка) | Необязательный. Категория. |
ВАЖНО: Фильтр по полям работает по условию И
, по значением в поле по условию ИЛИ
.
ВАЖНО: Поля в которых не заданы значения игнорируются.
Представление JSON параметров:
{
"type": string
}
Поле | Тип | Значение | Описание |
---|---|---|---|
type | STRING | notify | Необязательный. Тип ответа. |
Издатель geo
предоставляет возможность подписаться на поступающие данные геолокации.
Представление JSON для фильтра отбора данных:
{
"codes": enum (string),
"objects": enum (numeric)
}
Поле | Тип | Значение | Описание |
---|---|---|---|
codes | JSON array | Коды (строка) | Необязательный. Коды групп координат (мест положений). По умолчанию default . |
objects | JSON array | Идентификаторы | Необязательный. Объекты. Массив идентификаторов. |
ВАЖНО: Фильтр по полям работает по условию И
, по значением в поле по условию ИЛИ
.
ВАЖНО: Поля в которых не заданы значения игнорируются.
Представление JSON параметров:
{
"type": string
}
Поле | Тип | Значение | Описание |
---|---|---|---|
type | STRING | notify | Необязательный. Тип ответа. |
POST /api/v1/observer/subscribe
Подписаться на события издателя.
Параметры запроса:
Поле | Тип | Значение | Описание |
---|---|---|---|
publisher | STRING | notify, log, geo | Обязательный. Код издателя. |
filter | JSON | Необязательный. Фильтр отбора событий издателя. | |
params | JSON | Необязательный. Параметры слушателя. |
Примеры запроса:
Подписаться на все события издателя с кодом notify
.
{"t":2,"u":"<uuid>","a":"/observer/subscribe","p":{"publisher":"notify"}}
Подписаться на события издателя с кодом notify
с учётом фильтра:
{"t":2,"u":"<uuid>","a":"/observer/subscribe","p":{"publisher":"notify","filter":{"classes":["client", "device"]},"params":{"type":"object"}}}
Где фильтр:
- Классы (
classes
): client, device
Параметры:
- Тип (
type
): object (в ответ будут приходить данные объекта в формате /get запроса).
Подписаться на все входящие сообщения:
{"t":2,"u":"observer","a":"/observer/subscribe","p":{"publisher":"notify", "filter": {"entities": ["message"], "classes": ["inbox"], "actions": ["create"]}, "params": {"type": "object"}}}
Отловить создание нового клиента и получить данные в виде списка клиентов:
{"t":2,"u":"<uuid>","a":"/observer/subscribe","p":{"publisher":"notify","filter":{"classes":["client"],"actions":["create"]},"params":{"type":"hook","hook":{"path": "/api/v1/client/list", "payload": {}}}}}
POST /api/v1/observer/unsubscribe
Отписаться от событий издателя.
Параметры запроса:
Поле | Тип | Значение | Описание |
---|---|---|---|
publisher | STRING | notify, log, geo | Обязательный. Код издателя. |
Пример запроса:
{"t":2,"u":"<uuid>","a":"/observer/unsubscribe","p":{"publisher":"notify"}}
POST /api/v1/observer/publisher
Получить данные издателя.
Параметры запроса:
Поле | Тип | Значение | Описание |
---|---|---|---|
code | STRING | notify, log, geo | Обязательный. Код издателя. |
fields | JSON array | Необязательный. Массив JSON string полей в таблице, если не указано то запрос вернет все поля. |
POST /api/v1/observer/publisher/get
Получить данные издателя.
Параметры запроса:
Поле | Тип | Значение | Описание |
---|---|---|---|
code | STRING | notify, log, geo | Обязательный. Код издателя. |
fields | JSON array | Необязательный. Массив JSON string полей в таблице, если не указано то запрос вернет все поля. |
POST /api/v1/observer/publisher/count
Количество издателей с возможностью указания фильтра отбора данных.
Параметры запроса: Общие параметры запроса для списка
POST /api/v1/observer/publisher/list
Список издателей с возможностью указания фильтра отбора.
Параметры запроса: Общие параметры запроса для списка
POST /api/v1/observer/listener
Получить данные слушателя по коду издателя.
Параметры запроса:
Поле | Тип | Значение | Описание |
---|---|---|---|
publisher | STRING | notify | Обязательный. Код издателя. |
session | STRING | Необязательный. Код сессии. | |
fields | JSON array | Необязательный. Массив JSON string полей в таблице, если не указано то запрос вернет все поля. |
POST /api/v1/observer/listener/set
Установить данные слушателя.
Параметры запроса:
Поле | Тип | Значение | Описание |
---|---|---|---|
publisher | STRING | Обязательный. Идентификатор издателя. | |
session | STRING | Необязательный. Код сессии. | |
filter | JSON | Необязательный. Фильтр отбора событий издателя. | |
params | JSON | Необязательный. Параметры слушателя. |
POST /api/v1/observer/listener/get
Получить данные слушателя.
Параметры запроса:
Поле | Тип | Значение | Описание |
---|---|---|---|
publisher | STRING | Обязательный. Код издателя. | |
session | STRING | Необязательный. Код сессии. | |
fields | JSON array | Необязательный. Массив JSON string полей в таблице, если не указано то запрос вернет все поля. |
POST /api/v1/observer/listener/count
Количество слушателей с возможностью указания фильтра отбора данных.
Параметры запроса: Общие параметры запроса для списка
POST /api/v1/observer/listener/list
Список слушателей с возможностью указания фильтра отбора.
Параметры запроса: Общие параметры запроса для списка
Запрос "Кто я":
{"t":2,"u":"<uuid>","a":"/whoami"}
Запросить:
Сущности:
{"t":2,"u":"<uuid>","a":"/entity","p":{"fields": ["id", "code", "name"]}}
Классы:
{"t":2,"u":"<uuid>","a":"/class","p":{"fields": ["id", "entity", "entitycode", "entityname", "code", "label"]}}
Действия:
{"t":2,"u":"<uuid>","a":"/action","p":{"fields": ["id", "code", "name"]}}
Методы:
{"t":2,"u":"<uuid>","a":"/method","p":{"fields": ["id", "class", "classcode", "classlabel", "action", "actioncode", "actionname", "code", "label"]}}