Сервисы в чате
Формы, подписки, поддержка и запись. Для запросов нужен токен вашего бота.
Идемпотентно отправить текст, карточку, форму или клавиатуруPOST /v1/bot/send
Пример запроса
// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/send", process.env.REG15_API_ROOT);
const response = await fetch(url, {
method: 'POST',
headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN, 'Content-Type': 'application/json'},
body: JSON.stringify({
"conversationId": "30000000-0000-4000-8000-000000000003",
"requestId": "50000000-0000-4000-8000-000000000005",
"text": "Выберите уведомления",
"botPayload": {
"version": 1,
"revision": "events-1",
"buttons": [
{
"id": "subscribe",
"text": "Подписаться",
"subscription": {
"topic": "events",
"enabled": true
}
}
]
}
}),
signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.Основные поля ответа
{
"message": {
"id": "40000000-0000-4000-8000-000000000004",
"conversationId": "30000000-0000-4000-8000-000000000003",
"sequence": 2,
"text": "Выберите уведомления"
}
}Схема и правила повтора
Действующий Bearer-токен своего приложения; доступ ограничен его диалогами и явно разрешёнными сообществами.
Сохраните requestId до отправки. Повтор с тем же содержимым возвращает прежнее сообщение; изменённое содержимое конфликтует. После отзыва прав сохранённый успех не открывает диалог.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"conversationId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 4096
},
"requestId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"botPayload": {
"type": "object",
"properties": {
"version": {
"type": "number",
"const": 1
},
"revision": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"entities": {
"maxItems": 100,
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"bold",
"italic",
"underline",
"strikethrough",
"code",
"pre",
"text_link"
]
},
"offset": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"length": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"url": {
"type": "string",
"format": "uri"
}
},
"required": [
"type",
"offset",
"length"
],
"additionalProperties": false
}
},
"expiresAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"buttons": {
"maxItems": 30,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"subscription": {
"type": "object",
"properties": {
"topic": {
"type": "string",
"pattern": "^[a-z0-9_.-]{1,100}$"
},
"enabled": {
"type": "boolean"
}
},
"required": [
"topic",
"enabled"
],
"additionalProperties": false
},
"url": {
"type": "string",
"format": "uri"
}
},
"required": [
"id",
"text"
],
"additionalProperties": false
}
},
"keyboard": {
"maxItems": 30,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"subscription": {
"type": "object",
"properties": {
"topic": {
"type": "string",
"pattern": "^[a-z0-9_.-]{1,100}$"
},
"enabled": {
"type": "boolean"
}
},
"required": [
"topic",
"enabled"
],
"additionalProperties": false
},
"url": {
"type": "string",
"format": "uri"
}
},
"required": [
"id",
"text"
],
"additionalProperties": false
}
},
"card": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"product",
"service",
"event"
]
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"description": {
"type": "string",
"maxLength": 3000
},
"imageUrl": {
"type": "string",
"format": "uri"
},
"priceMinor": {
"type": "integer",
"minimum": 0,
"maximum": 10000000000
},
"currency": {
"type": "string",
"const": "RUB"
},
"startsAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"timeZone": {
"type": "string",
"maxLength": 80
}
},
"required": [
"kind",
"title"
],
"additionalProperties": false
},
"form": {
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"fields": {
"minItems": 1,
"maxItems": 20,
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z][a-zA-Z0-9_]{0,63}$"
},
"label": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"type": {
"type": "string",
"enum": [
"text",
"number",
"select",
"date",
"time",
"file",
"consent"
]
},
"required": {
"type": "boolean"
},
"options": {
"maxItems": 50,
"type": "array",
"items": {
"type": "object",
"properties": {
"value": {
"type": "string",
"maxLength": 128
},
"label": {
"type": "string",
"maxLength": 120
}
},
"required": [
"value",
"label"
],
"additionalProperties": false
}
},
"min": {
"type": "number"
},
"max": {
"type": "number"
}
},
"required": [
"name",
"label",
"type"
],
"additionalProperties": false
}
}
},
"required": [
"title",
"fields"
],
"additionalProperties": false
}
},
"required": [
"version",
"revision"
],
"additionalProperties": false
},
"topic": {
"type": "string",
"pattern": "^[a-z0-9_.-]{1,100}$"
}
},
"required": [
"conversationId",
"text",
"requestId"
],
"additionalProperties": false
}Получить и подтвердить собственные события 15RegGET /v1/bot/events
Пример запроса
// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/events", process.env.REG15_API_ROOT);
url.search = new URLSearchParams({"offset":0,"limit":100,"timeout":10}).toString();
const response = await fetch(url, {
method: 'GET',
headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN},
signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.Основные поля ответа
{
"items": [],
"nextOffset": 0
}Схема и правила повтора
Действующий Bearer-токен своего приложения; доступ ограничен его диалогами и явно разрешёнными сообществами.
Чередуйте с getUpdates в одном процессе. offset подтверждает только события этого потока. Сохраняйте offset после обработки; пустой ответ не подтверждает новую работу.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"offset": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"limit": {
"default": 100,
"type": "integer",
"minimum": 1,
"maximum": 100
},
"timeout": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 45
}
},
"required": [
"offset",
"limit",
"timeout"
],
"additionalProperties": false
}Получить UUID доступного диалога по совместимому числовому chat.idGET /v1/bot/chats/{chatId}
Пример запроса
// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/chats/100", process.env.REG15_API_ROOT);
const response = await fetch(url, {
method: 'GET',
headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN},
signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.Основные поля ответа
{
"conversationId": "30000000-0000-4000-8000-000000000003"
}Схема и правила повтора
Действующий Bearer-токен своего приложения; доступ ограничен его диалогами и явно разрешёнными сообществами.
Чтение можно повторить; каждый запрос заново проверяет доступ.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"chatId": {
"type": "string",
"pattern": "^\\d{1,16}$"
}
},
"required": [
"chatId"
],
"additionalProperties": false
}Передать доступный диалог сотруднику приложенияPOST /v1/bot/handoffs
Пример запроса
// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/handoffs", process.env.REG15_API_ROOT);
const response = await fetch(url, {
method: 'POST',
headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN, 'Content-Type': 'application/json'},
body: JSON.stringify({
"conversationId": "30000000-0000-4000-8000-000000000003"
}),
signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.Основные поля ответа
{
"caseId": "50000000-0000-4000-8000-000000000005",
"state": "open"
}Схема и правила повтора
Действующий Bearer-токен своего приложения; доступ ограничен его диалогами и явно разрешёнными сообществами.
Пока прежнее обращение открыто, повтор возвращает его caseId. После закрытия создаётся новое обращение. Ответ сотрудника идёт через его сессию в кабинете.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"conversationId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [
"conversationId"
],
"additionalProperties": false
}Показать подтверждаемое предложение записи с ценой и временемPOST /v1/bot/booking-offers
Пример запроса
// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/booking-offers", process.env.REG15_API_ROOT);
const response = await fetch(url, {
method: 'POST',
headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN, 'Content-Type': 'application/json'},
body: JSON.stringify({
"conversationId": "30000000-0000-4000-8000-000000000003",
"communitySlug": "example",
"requestId": "50000000-0000-4000-8000-000000000005",
"booking": {
"serviceId": "60000000-0000-4000-8000-000000000006",
"resourceIds": [
"70000000-0000-4000-8000-000000000007"
],
"guests": 1,
"startsAt": "2030-01-20T10:00:00+03:00",
"durationMinutes": 60,
"requestKey": "50000000-0000-4000-8000-000000000005"
}
}),
signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.Основные поля ответа
{
"offerId": "50000000-0000-4000-8000-000000000005",
"messageId": "40000000-0000-4000-8000-000000000004",
"expiresAt": "2030-01-01T10:15:00Z"
}Схема и правила повтора
Действующий токен; запущенный доступный диалог; владелец приложения управляет выбранным заведением.
Повторяйте прежний requestId с прежними параметрами. Изменение параметров требует нового запроса и подтверждения. Предложение действует 15 минут; оно ещё не является бронью.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"conversationId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"communitySlug": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"booking": {
"type": "object",
"properties": {
"resourceIds": {
"minItems": 1,
"maxItems": 8,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"startsAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"durationMinutes": {
"type": "integer",
"minimum": 15,
"maximum": 720
},
"guests": {
"type": "integer",
"minimum": 1,
"maximum": 100
},
"serviceId": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"requestKey": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [
"resourceIds",
"startsAt",
"durationMinutes",
"guests",
"serviceId",
"requestKey"
],
"additionalProperties": false
},
"requestId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [
"conversationId",
"communitySlug",
"booking",
"requestId"
],
"additionalProperties": false
}Создать бронь только после действительного согласия пользователяPOST /v1/bot/booking-offers/{offerId}/confirm
Пример запроса
// Node.js 24. Подставьте ID из своего тестового диалога.
const url = new URL("/v1/bot/booking-offers/OFFER_ID/confirm", process.env.REG15_API_ROOT);
const response = await fetch(url, {
method: 'POST',
headers: {Authorization: 'Bearer ' + process.env.REG15_BOT_TOKEN, 'Content-Type': 'application/json'},
body: JSON.stringify({
"submissionId": "50000000-0000-4000-8000-000000000005"
}),
signal: AbortSignal.timeout(45000)
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code ?? 'REQUEST_FAILED');
// Используйте result. Не записывайте токен и чужие данные в журнал.Основные поля ответа
{
"bookingId": "80000000-0000-4000-8000-000000000008",
"requestId": "50000000-0000-4000-8000-000000000005",
"booking": {
"state": "pending"
}
}Схема и правила повтора
Действующий токен; запущенный доступный диалог; владелец приложения управляет выбранным заведением.
submissionId берите из form.submitted.v1, offerId — из предложения. Сервер повторно проверяет цену, срок и доступность. Повтор завершённой операции возвращает ту же бронь; изменившиеся условия требуют нового предложения.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"submissionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [
"submissionId"
],
"additionalProperties": false
}