В процессе разработки корпоративных информационных систем на базе 1С часто возникает задача оперативного оповещения ответственных лиц. Например, руководство должно мгновенно узнавать о появлении новых документов, созданных подчиненными, чтобы оперативно проверять и согласовывать их. Развертывание тяжелого и требовательного к ресурсам Сервера взаимодействия (Системы взаимодействия) ради простой самописной конфигурации часто нецелесообразно.
В этой статье мы подробно разберем четыре практических и надежных способа реализации системы уведомлений: от классического регистра сведений с обработчиком ожидания до революционного механизма, появившегося в платформе версии 8.3.26, а также интеграции с мессенджером Telegram без сторонних библиотек.
Начиная с версии платформы 8.3.26, фирма «1С» добавила встроенный функционал, позволяющий отправлять сообщения с сервера напрямую в сеансы клиентов без развертывания Системы взаимодействия и без циклического опроса базы данных. Этот механизм называется МенеджерУведомленийКлиента.
Рассмотрим, как реализовать эту схему по шагам. Нам потребуется подключить обработчик на стороне клиента при старте системы и вызывать отправку сообщения на сервере при создании или изменении статуса документа.
Шаг 1. Настройка на стороне клиента
В модуле управляемого приложения в процедуре ПриНачалеРаботыСистемы подключаем обработчик уведомлений:
Процедура ПриНачалеРаботыСистемы()
#Если Клиент Тогда
// Подключаем прослушивание определенного ключа оповещения
УведомленияКлиента.ПодключитьОбработчик("НовыеДокументыНаСогласование", "ОбработатьНовоеОповещение");
#КонецЕсли
КонецПроцедуры
Там же, в модуле управляемого приложения, создаем экспортную процедуру, которая будет принимать данные от сервера и выводить их пользователю на экран:
Процедура ОбработатьНовоеОповещение(ИмяСобытия, ДанныеУведомления) Экспорт
// Формируем навигационную ссылку для быстрого открытия документа
АдресСсылки = ПолучитьНавигационнуюСсылку(ДанныеУведомления.Ссылка);
// Выводим стандартное всплывающее окно 1С
ПоказатьОповещениеПользователя(
"Новый документ на согласование!",
АдресСсылки,
ДанныеУведомления.ПредставлениеДокумента,
БиблиотекаКартинок.Информация
);
КонецПроцедуры
Шаг 2. Отправка уведомления с сервера
В модуле документа (например, в обработчике события ПриЗаписи или при переводе документа в статус «На согласовании») мы определяем список получателей, находим их активные сеансы и отправляем пуш-уведомление:
Процедура ОтправитьУведомлениеРуководству(СсылкаНаДокумент, МассивРуководителей) Экспорт
// Собираем данные для передачи на клиент
ДанныеУведомления = Новый Структура;
ДанныеУведомления.Вставить("Ссылка", СсылкаНаДокумент);
ДанныеУведомления.Вставить("ПредставлениеДокумента", Строка(СсылкаНаДокумент));
// Находим номера активных сеансов нужных пользователей
МассивСеансов = Новый Массив;
АктивныеСеансы = ПолучитьСоединенияИнформационнойБазы();
Для Каждого Сеанс Из АктивныеСеансы Цикл
Если МассивРуководителей.Найти(Сеанс.Пользователь) <> Неопределено Тогда
МассивСеансов.Добавить(Сеанс.НомерСеанса);
КонецЕсли;
КонецЦикла;
// Если найдены активные сеансы, отправляем уведомление напрямую в клиентские приложения
Если МассивСеансов.Количество() > 0 Тогда
УведомленияКлиента.ОтправитьУведомление("НовыеДокументыНаСогласование", ДанныеУведомления, МассивСеансов);
КонецЕсли;
КонецПроцедуры
Этот метод идеален: он работает мгновенно, не создает нагрузку постоянными SQL-запросами к базе данных и не требует стороннего софта.
Если ваша база работает на платформе версии ниже 8.3.26, классическим и наиболее надежным решением будет использование структуры «Регистр сведений + Обработчик ожидания». Главное достоинство этого метода — гарантированная доставка. Даже если руководитель был оффлайн, при входе в систему программа считает непрочитанные записи из регистра и покажет их.
Разберем детально создание и оптимизацию этой схемы, чтобы минимизировать нагрузку на СУБД.
Шаг 1. Создание регистра сведений
Создадим в конфигураторе новый непериодический независимый регистр сведений ОчередьУведомлений со следующей структурой:
Пользователь (Тип: СправочникСсылка.Пользователи).Документ (Тип: ЛюбаяСсылка - или ссылки на конкретные документы).Просмотрено (Тип: Булево).ДатаСоздания (Тип: Дата, состав даты: Время, дата). Потребуется для сортировки и последующей очистки старых записей.Важно: Установите индексирование по измерению Пользователь и ресурсу Просмотрено. Это критически важно, так как запросы к этому регистру будут выполняться регулярно от каждого активного пользователя.
Шаг 2. Запись событий в регистр
В модуле документа (или в подписке на событие ПриЗаписи) пишем логику добавления записей для лиц, принимающих решения:
Процедура ПриЗаписи(Отказ)
Если ЭтотОбъект.Проведен И ЭтотОбъект.Статус = Перечисления.СтатусыДокументов.НаСогласовании Тогда
// Получаем список руководителей, которым нужно согласовать документ
МассивСогласующих = ПолучитьСписокСогласующихЛиц(ЭтотОбъект.Ответственный);
Для Каждого Руководитель Из МассивСогласующих Цикл
МенеджерЗаписи = РегистрыСведений.ОчередьУведомлений.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Пользователь = Руководитель;
МенеджерЗаписи.Документ = ЭтотОбъект.Ссылка;
МенеджерЗаписи.Просмотрено = Ложь;
МенеджерЗаписи.ДатаСоздания = ТекущаяДата();
МенеджерЗаписи.Записать(Истина);
EndDo;
КонецЕсли;
КонецПроцедуры
Шаг 3. Настройка обработчика ожидания на клиенте
Переходим в модуль управляемого приложения. Подключим периодический опрос базы данных. Чтобы не перегружать сервер, установим интервал опроса раз в 10–15 минут (600–900 секунд). Для оперативных отделов можно снизить до 5 минут (300 секунд), но не делайте проверку ежесекундной.
Процедура ПриНачалеРаботыСистемы()
#Если Клиент Тогда
// Подключаем проверку раз в 10 минут (600 секунд)
ПодключитьОбработчикОжидания("ПроверитьНовыеДокументыНаСогласование", 600);
#КонецЕсли
КонецПроцедуры
Процедура ПроверитьНовыеДокументыНаСогласование() Экспорт
// Вызываем легкий серверный запрос
МассивНовыхДокументов = ПроверитьОчередьУведомленийНаСервере();
Для Каждого СведенияОДокументе Из МассивНовыхДокументов Цикл
// Выводим интерактивное оповещение
ПоказатьОповещениеПользователя(
"Новый документ для проверки",
ПолучитьНавигационнуюСсылку(СведенияОДокументе.Документ),
Строка(СведенияОДокументе.Документ),
БиблиотекаКартинок.Важно
);
КонецЦикла;
КонецПроцедуры
Шаг 4. Оптимальный серверный запрос чтения очереди
В общем модуле с флагом Вызов сервера создаем оптимизированную функцию:
Функция ПроверитьОчередьУведомленийНаСервере() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОчередьУведомлений.Документ КАК Документ
|ИЗ
| РегистрСведений.ОчередьУведомлений КАК ОчередьУведомлений
|ГДЕ
| ОчередьУведомлений.Пользователь = &ТекущийПользователь
| И ОчередьУведомлений.Просмотрено = ЛОЖЬ";
Запрос.УстановитьПараметр("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// Сразу помечаем полученные уведомления как просмотренные (или удаляем их),
// чтобы при следующем цикле опроса они не дублировались
Если РезультатЗапроса.Количество() > 0 Тогда
НачатьТранзакцию();
Попытка
Для Каждого СтрокаОтчета Из РезультатЗапроса Цикл
МенеджерЗаписи = РегистрыСведений.ОчередьУведомлений.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Пользователь = ПараметрыСеанса.ТекущийПользователь;
МенеджерЗаписи.Документ = СтрокаОтчета.Документ;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
МенеджерЗаписи.Просмотрено = Истина;
МенеджерЗаписи.Записать();
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации("Уведомления.ОшибкаСбросаФлага", УровеньЖурналаРегистрации.Предупреждение,,, ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Возврат РезультатЗапроса;
КонецФункции
Мессенджеры — отличная альтернатива, когда руководители часто находятся вне офиса или работают без открытого окна 1С. Интеграцию с Telegram можно написать буквально в несколько строк кода прямо в модуле вашей конфигурации.
Алгоритм настройки подключения к Telegram:
@BotFather и получите токен доступа (API Token).Пользователи реквизит ИдентификаторЧатTelegram (строка, куда будет вноситься персональный ID чата руководителя).Рассмотрим готовую функцию для отправки сообщений, которую вы можете вставить в любой общий модуль вашей системы:
Процедура ОтправитьОповещениеВTelegram(ИдентификаторЧат, СсылкаНаДокумент) Экспорт
ТокенБота = "5123456789:AAF_ПримерВашегоТокенаБота_XXYYZZ"; // Укажите ваш токен
ТекстСообщения = "<b>Создан новый документ на согласование!</b>" + Символы.ПС
+ Строка(СсылкаНаДокумент) + Символы.ПС
+ "Ссылка на документ в 1С: " + ПолучитьНавигационнуюСсылку(СсылкаНаДокумент);
// Формируем параметры HTTP-запроса в формате JSON
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("chat_id", ИдентификаторЧат);
СтруктураПараметров.Вставить("text", ТекстСообщения);
СтруктураПараметров.Вставить("parse_mode", "HTML");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураПараметров);
СтрокаТелаЗапроса = ЗаписьJSON.Закрыть();
// Инициализируем защищенное SSL-соединение
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение("api.telegram.org", 443,,,,, ЗащищенноеСоединение);
HTTPЗапрос = Новый HTTPЗапрос("bot" + ТокенБота + "/sendMessage");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json");
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаТелаЗапроса, КодировкаТекста.UTF8);
Попытка
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если HTTPОтвет.КодСостояния <> 200 Тогда
ЗаписьЖурналаРегистрации("Telegram.Ошибка", УровеньЖурналаРегистрации.Ошибка,,, "Код состояния: " + HTTPОтвет.КодСостояния);
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("Telegram.Ошибка", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Обратите внимание: Если на мобильных телефонах или рабочих ПК руководителей установлен тонкий клиент 1С (или база опубликована через веб-сервер), клик по навигационной ссылке вида e1cib/data/... автоматически откроет нужный документ прямо в интерфейсе платформы.
Если ваша конфигурация является частью экосистемы БСП (Библиотека стандартных подсистем) или вы готовы перенести в свою базу один её модуль, отличным решением станет интеграция подсистемы «Бизнес-процессы и задачи».
Этот подход избавляет от необходимости писать кастомную логику всплывающих окон. Вместо этого в системе создается объект типа Задача. Преимущества использования задач:
Проанализируем все варианты и выберем оптимальный подход в зависимости от условий эксплуатации вашей системы:
| Метод реализации | Сложность разработки | Влияние на производительность | Требования к платформе / софту | Главный плюс |
|---|---|---|---|---|
| Менеджер уведомлений клиента | Низкая | Отсутствует (пуш-технология) | Платформа не ниже 8.3.26 | Мгновенная отправка данных без нагрузки на базу |
| Регистр сведений + таймер | Средняя | Среднее (зависит от частоты опроса) | Любая версия платформы 8.3 | Гарантированная доставка сообщений «оффлайн» пользователям |
| Интеграция с Telegram | Низкая | Минимальное (асинхронные HTTP-вызовы) | Доступ в Интернет на сервере 1С | Уведомления приходят на телефон, даже если 1С закрыта |
| Задачи (БСП) | Высокая (требуется интеграция БСП) | Минимальное | Любая современная платформа | Полноценный аудит согласований и ролевая адресация |
Для простых самописных конфигураций на современных платформах мы настоятельно рекомендуем использовать Менеджер уведомлений клиента. Если же вам важна мобильность руководителей, связка с Telegram-ботом пишется за 15 минут и решает проблему коммуникаций раз и навсегда.