Аларм сценарии
Аларм-сценарии (или "алармы") — это архитектурный паттерн, позволяющий динамически изменять логику работы всего проекта или его частей в ответ на нештатные ситуации, такие как технические сбои, пиковы
Основная идея — централизованное управление состоянием проекта через глобальный аларм-флаг. В зависимости от этого флага, сценарии могут переключаться со стандартной логики на альтернативную (аларм-ветку).
Ключевые компоненты
Аларм-флаг: Глобальная переменная, хранящая текущий статус аларма. Например,
ALARM_PAYMENT_SYSTEM: true
.Управляющий сниппет: Специальный сниппет для установки и снятия аларм-флагов. Это единая точка управления алармами.
Проверяющий сниппет: Сниппет, который выполняется в начале ключевых сценариев, читает состояние аларм-флага и записывает его в контекст текущего пользователя.
Реакция «Условие»: Блок, который проверяет флаг в контексте и направляет пользователя по стандартной или аларм-ветке.
Паттерн реализации
1. Управление аларм-флагами
Создайте отдельный сниппет (например, setAlarm
), который будет использоваться для включения или выключения алармов. Его можно запускать вручную через тестовый чат для управления состоянием.
// snippet: setAlarm
async function snippet(core, context, projectStorage) {
// Для включения аларма передайте в фактах: { "alarm_payment": true }
// Для выключения: { "alarm_payment": false }
const alarmStatus = context.get('alarm_payment');
if (typeof alarmStatus === 'boolean') {
// Устанавливаем флаг в projectStorage с TTL (Time To Live) в 1 день (86400 секунд)
await projectStorage.set('ALARM_PAYMENT_SYSTEM', alarmStatus, 86400);
core.sendText(`Статус аларма платежной системы установлен в: ${alarmStatus}`);
} else {
core.sendText('Некорректный статус аларма. Передайте true или false в факте alarm_payment.');
}
}
2. Проверка аларм-флага в сценариях
В начале каждого сценария, который должен реагировать на аларм (например, в сценарии «Старт» или перед переводом на оператора), добавьте сниппет, который проверяет projectStorage
.
// snippet: checkAlarm
async function snippet(core, context, projectStorage) {
// Читаем флаг из projectStorage. Если его нет, считаем, что аларма нет (false).
const isAlarmActive = await projectStorage.get('ALARM_PAYMENT_SYSTEM') || false;
// Записываем статус в контекст текущего пользователя.
context.set('payment_alarm_active', isAlarmActive);
}
3. Ветвление логики
Сразу после сниппета checkAlarm
поставьте реакцию «Условие», которая будет проверять флаг в контексте.
Параметр:
payment_alarm_active
Оператор:
Равен
Значение:
true
Ветка «Выполнено» ведет на аларм-логику (например, сообщение «В данный момент наблюдаются проблемы с оплатой. Мы уже работаем над решением.»).
Ветка «Не выполнено» (или
else
) ведет на стандартную логику сценария.
Примеры использования
Сценарий 1: Сбой платежной системы
Проблема: Перестали проходить платежи.
Действие: Вручную запускается сниппет
setAlarm
с флагомalarm_payment: true
.Результат:
В сценарии «Старт» все новые пользователи видят сообщение о проблеме.
В сценарии оплаты бот не предлагает провести платеж, а сразу сообщает о временных трудностях.
Сценарий 2: Пиковая нагрузка на операторов
Проблема: Количество обращений резко возросло, время ожидания оператора увеличилось.
Действие: Активируется аларм-флаг
HIGH_LOAD_OPERATORS
.Результат: Перед блоком перевода на оператора бот отправляет сообщение: «Внимание! Время ожидания ответа оператора увеличено до 30 минут. Вы уверены, что хотите продолжить?», предлагая кнопки «Да, ждать» и «Нет, вернуться».
Управление несколькими алармами
В сложных проектах может потребоваться управлять несколькими независимыми алармами (например, один для платежей, другой для службы доставки). Паттерн остается тем же, но управляющий сниппет модифицируется для работы с разными аларм-флагами.
Шаг 1: Создание универсального управляющего сниппета.
Этот сниппет сможет устанавливать или снимать любой аларм, имя которого передается в фактах.
// snippet: alarmManager
async function snippet(core, context, projectStorage) {
// Ожидаемые факты: { "alarmName": "ALARM_DELIVERY", "alarmStatus": true }
const { alarmName, alarmStatus } = context.get_all();
if (alarmName && typeof alarmStatus === 'boolean') {
// Устанавливаем флаг в projectStorage с TTL в 1 день
await projectStorage.set(alarmName, alarmStatus, 86400);
core.sendText(`Статус аларма '${alarmName}' установлен в: ${alarmStatus}`);
} else {
core.sendText('Ошибка: передайте { "alarmName": "...", "alarmStatus": true/false } в фактах.');
}
}
Шаг 2: Проверка конкретного аларма в сценарии.
В нужном сценарии (например, в сценарии отслеживания доставки) вы используете проверяющий сниппет, который читает только нужный флаг.
// snippet: checkDeliveryAlarm
async function snippet(core, context, projectStorage) {
const isDeliveryAlarm = await projectStorage.get('ALARM_DELIVERY') || false;
context.set('delivery_alarm_active', isDeliveryAlarm);
}
После этого реакция «Условие» проверяет факт delivery_alarm_active
и направляет пользователя по соответствующей ветке. Такой подход обеспечивает изоляцию и гибкое управление каждым алармом в проекте.
Практический пример: Полная реализация аларм-сценария
Рассмотрим полную реализацию аларм-сценария, состоящую из трех основных компонентов.
Компонент 1: Настройка переменных в личном кабинете
В личном кабинете устанавливаются следующие переменные:
Переменные состояния алармов (boolean):
alarm1
— состояние первого аларма (true/false)alarm2
— состояние второго аларма (true/false)alarm3
— состояние третьего аларма (true/false)
Переменные текстовок:
alarm1text
— текст сообщения для первого алармаalarm2text
— текст сообщения для второго алармаalarm3text
— текст сообщения для третьего аларма
Компонент 2: Два сниппета
Сниппет 1: Отправка текстовок (sendAlarm)
Этот сниппет проверяет состояние алармов и отправляет соответствующие текстовки пользователю:
async function snippet(core = new Core(), context = new Context(), projectStorage = new ProjectStorage()) {
// Инициализируем флаги отправки
context.set('alarm1WasSent', false);
context.set('alarm2WasSent', false);
context.set('alarm3WasSent', false);
// Проверяем и отправляем текстовки для активных алармов
if (context.alarm1) {
core.sendText(context.alarm1text);
context.set('alarm1WasSent', true);
}
if (context.alarm2) {
core.sendText(context.alarm2text);
context.set('alarm2WasSent', true);
}
if (context.alarm3) {
core.sendText(context.alarm3text);
context.set('alarm3WasSent', true);
}
}
Сниппет 2: Изменение состояния (changeAlarmStatus)
Этот сниппет проверяет, были ли отправлены какие-либо аларм-сообщения, и генерирует ошибку для перенаправления в соответствующую ветку:
async function snippet(core = new Core(), context = new Context(), projectStorage = new ProjectStorage()) {
// Если хотя бы один аларм был отправлен, генерируем ошибку
if (context.alarm1WasSent || context.alarm2WasSent || context.alarm3WasSent) {
throw new Error();
}
}
Компонент 3: Структура сценария
Сценарий строится по следующей схеме:
Логика работы:
Стартовый триггер запускает первый сниппет
sendAlarm
Первый сниппет проверяет активные алармы и отправляет текстовки:
Успех: Переходит ко второму сниппету
Ошибка: Обработка выполнения сниппета
Второй сниппет
changeAlarmStatus
проверяет флаги отправки:Успех: Ни один аларм не был отправлен → продолжение обычного сценария
Ошибка: Хотя бы один аларм был отправлен → переход в ветку «Ошибка»
Преимущества такого подхода:
Централизованное управление алармами через переменные личного кабинета
Гибкость в настройке текстовок без изменения кода
Четкое разделение логики проверки и отправки
Возможность обработки множественных алармов одновременно
Последнее обновление