Система взаимодействия (Collaboration System) в платформе 1С:Предприятие — это мощный инструмент для коммуникации пользователей внутри базы данных. Часто перед разработчиками встает задача не просто наладить обмен текстовыми сообщениями, но и автоматизировать обработку файлов, прикрепленных к этим сообщениям (документы, сканы, изображения). В этой статье мы подробно разберем, как программно извлечь вложение из сообщения, прочитать его содержимое и сохранить для дальнейшей работы.
Представим ситуацию: пользователь отправляет сообщение в чат 1С и прикрепляет к нему файл (например, скриншот ошибки или скан накладной). Нам необходимо программно перехватить это сообщение (например, в боте или обработчике событий), извлечь файл и произвести с ним манипуляции: сохранить на диск, отправить в ответном сообщении или записать в базу данных.
Для реализации этой задачи нам потребуются следующие объекты платформы:
СистемаВзаимодействия — основной менеджер для работы с функционалом.СообщениеСистемыВзаимодействия — объект, содержащий текст и вложения.ВложениеСистемыВзаимодействия — объект, представляющий сам файл.Поток и ЧтениеДанных — механизмы для получения содержимого файла.Рассмотрим код, который позволяет решить эту задачу. Мы будем действовать последовательно, разбирая каждую строчку. Предположим, что у нас уже есть контекст входящего сообщения (переменная Сообщение).
Прежде чем формировать ответ или работать с контекстом, часто требуется получить объект самого обсуждения. Это делается через идентификатор обсуждения, который хранится в сообщении.
// Получаем объект обсуждения по ссылке из сообщения
Обсуждение = СистемаВзаимодействия.ПолучитьОбсуждение(Сообщение.Обсуждение);
Вложения хранятся в коллекции Вложения объекта сообщения. Важно понимать, что в одном сообщении может быть несколько файлов. В простейшем примере мы обратимся к первому файлу по индексу 0, однако в промышленном коде мы настоятельно рекомендуем использовать обход коллекции.
// Получаем первое вложение из списка (индекс 0)
ВложенияТекущегоОбсуждения = Сообщение.Вложения.Получить(0);
Важное замечание: Обращение по индексу Получить(0) без предварительной проверки количества элементов (Сообщение.Вложения.Количество() > 0) вызовет ошибку, если пользователь отправил сообщение без файлов. Всегда добавляйте проверку на наличие вложений.
Начиная с современных версий платформы 1С, работа с файлами в Системе взаимодействия осуществляется через потоки. Это позволяет эффективно работать с памятью. Метод ОткрытьПотокДляЧтения возвращает объект Поток, из которого мы можем читать данные.
// Открываем поток для чтения данных вложения
Поток = ВложенияТекущегоОбсуждения.ОткрытьПотокДляЧтения();
// Инициализируем чтение данных из потока
Чтение = Новый ЧтениеДанных(Поток);
Теперь, когда у нас есть объект ЧтениеДанных, мы можем извлечь содержимое файла в виде двоичных данных. Это универсальный формат, для которого существует алхимический способ работы с двоичными данными в 1С, позволяющий удобно сохранять их или передавать по HTTP.
// Получаем двоичные данные файла
ДвоичныеДанныеВложения = Чтение.Прочитать().ПолучитьДвоичныеДанные();
Частый сценарий — сохранить полученный файл во временную директорию для обработки. Рассмотрим, как это сделать.
// Генерируем уникальное имя временного файла с расширением (например, .png)
ИмяФайла = ПолучитьИмяВременногоФайла(".png");
// Записываем полученные двоичные данные на диск
ДвоичныеДанныеВложения.Записать(ИмяФайла);
Давайте посмотрим, как работает обратная операция. Допустим, мы обработали файл и хотим отправить его обратно пользователю или переслать в другое обсуждение. Для этого нам снова понадобятся потоки, но теперь — файловые.
// Создаем новое сообщение в рамках текущего обсуждения
Ответ = СистемаВзаимодействия.СоздатьСообщение(Обсуждение.Идентификатор);
// Добавляем информативный текст
Ответ.Текст = "Файл получен. Размер: " + Строка(ВложенияТекущегоОбсуждения.Размер);
// Открываем сохраненный ранее файл для чтения
НовыйПоток = ФайловыеПотоки.ОткрытьДляЧтения(ИмяФайла);
// Добавляем поток как вложение к новому сообщению
// Важно указать имя файла и MIME-тип (например, "image/png")
Ответ.Вложения.Добавить(НовыйПоток, "processed_image.png", "image/png");
// Отправляем сообщение
Ответ.Записать();
После завершения работы крайне важно освободить ресурсы. Потоки необходимо закрывать, а для обслуживания системы использовать регламентные задания и программный интерфейс, удаляя временные файлы, чтобы не засорять дисковое пространство.
// Закрываем потоки
Поток.Закрыть();
НовыйПоток.Закрыть();
// Удаляем временный файл
УдалитьФайлы(ИмяФайла);
Разберем аспекты, которые помогут сделать ваш код более надежным и производительным, основываясь на технической документации и опыте эксплуатации.
В Системе взаимодействия существует два типа вложений, и работать с ними нужно по-разному:
ОткрытьПотокДляЧтения работает идеально.ВнешнееВложениеСистемыВзаимодействия. Для него вместо потока данных вы будете работать с URL-адресом.В примере выше мы сохраняли данные на диск (ИмяФайла). Однако, если ваша задача — просто переслать файл или сохранить его в справочник ПрисоединенныеФайлы, создание временного файла на диске может быть излишним и замедлять работу.
Вы можете использовать метод КопироватьДанные для перелива данных из одного потока в другой или работать напрямую с ДвоичныеДанные, если объем памяти позволяет. Например, для записи в справочник достаточно получить Двоичные Данные и поместить их в реквизит типа ХранилищеЗначения.
Как мы упоминали ранее, жесткая привязка к индексу 0 — плохая практика. Правильный подход выглядит так:
Для Каждого Вложение Из Сообщение.Вложения Цикл
// Проверяем тип вложения, если нужно
Если ТипЗнч(Вложение) = Тип("ВложениеСистемыВзаимодействия") Тогда
ПотокЧтения = Вложение.ОткрытьПотокДляЧтения();
// Дальнейшая обработка...
ПотокЧтения.Закрыть();
КонецЕсли;
КонецЦикла;
При программном добавлении вложения (метод Ответ.Вложения.Добавить) третьим параметром указывается MIME-тип (например, "application/pdf", "image/jpeg"). Если вы не укажете его или укажете неверно, клиентское приложение может не понять, как открыть файл (как картинку или как просто файл).
Для автоматического определения типа по расширению файла в платформе 1С существуют вспомогательные методы, такие как ПолучитьMIMEТипПоРасширению() (начиная с определенных версий БСП или платформенных утилит), которые стоит использовать для универсальности.
Обратите внимание, что методы работы с Системой взаимодействия доступны как на Сервере, так и на Клиенте. Однако при работе с файлами учитывайте контекст:
ВременноеХранилище.Используя эти приемы и библиотеку искусственного интеллекта для 1С, вы сможете создавать умных ботов и обработчики, которые автоматически распознают документы, сохраняют сканы в базу 1С или маршрутизируют файлы между отделами.