В процессе автоматизации работы с клиентами часто возникает задача получения обратной связи без необходимости входа пользователя в информационную базу. Типичный сценарий: менеджер закрывает заявку в 1С:Управление нашей фирмой (УНФ), а клиенту уходит уведомление. Клиент должен иметь возможность подтвердить выполнение работ или отклонить его, просто нажав на ссылку в письме. Разберем, как реализовать такой механизм программно, используя современные возможности платформы 1С:Предприятие 8.3.
Рассмотрим два основных подхода, которые упоминались в обсуждении, и проанализируем их эффективность:
Проанализируем ситуацию: метод с mailto часто вызывает раздражение у пользователей, так как требует лишних действий. Поэтому мы сосредоточимся на реализации через HTTP-сервисы, как на наиболее надежном и автоматизированном варианте.
Прежде чем отправлять письма, нам нужно подготовить "приемник" сигналов. Выясним причину, почему это удобно: 1С сама выступает в роли веб-сервера. Разберем по шагам создание сервиса:
HTTP-сервис. Назовем его ОбработкаОтветовКлиентов.confirm./v1/{Action}/{ID}/{Token}. Здесь Action — это действие (accept или reject), ID — уникальный идентификатор заявки, а Token — ключ безопасности.GET и создадим обработчик в модуле сервиса.Посмотрим на пример кода для обработки входящего запроса:
Функция ОбработкаОтветовКлиентовОбработатьОтвет(Запрос)
Действие = Запрос.ПараметрыURL.Получить("Action");
Идентификатор = Запрос.ПараметрыURL.Получить("ID");
КлючБезопасности = Запрос.ПараметрыURL.Получить("Token");
// Проверим валидность данных и ключа
Если Не ПроверитьТокен(Идентификатор, КлючБезопасности) Тогда
Ответ = Новый HTTPСервисОтвет(403);
Ответ.УстановитьТелоИзСтроки("<h1>Ошибка доступа</h1>");
Возврат Ответ;
КонецЕсли;
// Ищем заявку и меняем статус
ЗаявкаСсылка = Документы.ЗаказПокупателя.ПолучитьСсылку(Новый УникальныйИдентификатор(Идентификатор));
Если Действие = "accept" Тогда
// Логика закрытия заявки
ОбъектЗаявки = ЗаявкаСсылка.ПолучитьОбъект();
ОбъектЗаявки.СостояниеЗаказа = Справочники.СостоянияЗаказовПокупателей.Выполнен;
ОбъектЗаявки.Записать();
ТекстОтвета = "<h1>Спасибо! Заявка подтверждена.</h1>";
Иначе
// Логика отклонения
ТекстОтвета = "<h1>Заявка отклонена. Мы свяжемся с вами.</h1>";
КонецЕсли;
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки(ТекстОтвета, КодировкаТекста.UTF8, "text/html");
Возврат Ответ;
КонецФункции
Рассмотрим важный момент: если мы просто передадим в ссылке номер заявки, любой злоумышленник сможет перебирать цифры и закрывать чужие заказы. Выход: использование уникальных токенов.
При формировании письма генерируйте уникальный ключ (GUID) и сохраняйте его в документе или в регистре сведений. В ссылке передавайте этот ключ. При получении запроса 1С должна проверить, что для данной заявки в базе хранится именно такой ключ. Это исключает возможность подмены данных.
Теперь разберем, как программно отправить текст «Принять», который выглядит как кнопка. Почтовые клиенты ограничены в поддержке современных стилей, поэтому используем inline-CSS.
Проанализируем структуру письма. Нам нужно подготовить строку в формате HTML, где ссылки будут оформлены стилями.
Процедура ОтправитьУведомлениеКлиенту(ЗаявкаСсылка)
// Подготовка данных
ИД = Строка(ЗаявкаСсылка.УникальныйИдентификатор());
Токен = ПолучитьТокенДляЗаявки(ЗаявкаСсылка); // Ваша функция генерации/получения ключа
БазовыйURL = "https://ваш-сервер.ru/base/hs/confirm/v1/";
СсылкаПринять = БазовыйURL + "accept/" + ИД + "/" + Токен;
СсылкаОтклонить = БазовыйURL + "reject/" + ИД + "/" + Токен;
// Формируем тело письма
ТекстHTML = "
|<html>
|<body>
| <h2>Заявка №" + ЗаявкаСсылка.Номер + " выполнена!</h2>
| <p>Пожалуйста, подтвердите выполнение работ или отклоните результат:</p>
| <br>
| <a href='" + СсылкаПринять + "'
| style='background-color: #4CAF50; color: white; padding: 14px 25px; text-align: center; text-decoration: none; display: inline-block; border-radius: 5px;'>
| ПРИНЯТЬ
| </a>
|
| <a href='" + СсылкаОтклонить + "'
| style='background-color: #f44336; color: white; padding: 14px 25px; text-align: center; text-decoration: none; display: inline-block; border-radius: 5px;'>
| ОТКЛОНИТЬ
| </a>
|</body>
|</html>";
// Отправка через встроенную почту 1С
Почта = Новый ИнтернетПочта;
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Тема = "Подтверждение закрытия заявки";
Сообщение.Получатели.Добавить(ЗаявкаСсылка.Контрагент.Email);
Сообщение.Тексты.Добавить(ТекстHTML, ТипТекстаПочтовогоСообщения.HTML);
// Настройки прописываются отдельно
Почта.Подключиться(Профиль);
Почта.Послать(Сообщение);
Почта.Отключиться();
КонецПроцедуры
Выясним причину, по которой ссылки могут не работать. Чтобы клиент из интернета смог "достучаться" до вашей 1С, база должна быть опубликована на веб-сервере (Apache или IIS), и этот сервер должен иметь внешний статический IP-адрес или доменное имя.
Если ваша компания находится за файрволом и не может открыть доступ снаружи, рассмотрите вариант с промежуточным скриптом на внешнем хостинге (например, на PHP), который будет принимать запросы и пересылать их в 1С через защищенное соединение или через промежуточную таблицу в облачной базе.
GET обязательно проверяйте текущий статус заказа. Если клиент нажал «Принять» второй раз через час, выдайте ему страницу с текстом: «Ваш ответ уже был зафиксирован ранее».РегистрСведений. Это поможет разобрать спорные ситуации, если клиент утверждает, что ничего не нажимал.<style> в шапке письма, поэтому всегда пишите стили прямо внутри тега style='...' у каждой ссылки/кнопки.Рассмотренный метод с использованием HTTP-сервисов является наиболее современным и удобным для конечного пользователя. Он превращает обычное уведомление в интерактивный инструмент управления бизнес-процессом, минимизируя время реакции клиента и исключая ручной труд менеджера по смене статусов в 1С.