Как программно получить и обработать вложения из сообщений Системы взаимодействия в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Система взаимодействия (Collaboration System) в платформе 1С:Предприятие — это мощный инструмент для коммуникации пользователей внутри базы данных. Часто перед разработчиками встает задача не просто наладить обмен текстовыми сообщениями, но и автоматизировать обработку файлов, прикрепленных к этим сообщениям (документы, сканы, изображения). В этой статье мы подробно разберем, как программно извлечь вложение из сообщения, прочитать его содержимое и сохранить для дальнейшей работы.

Постановка задачи и базовый алгоритм

Представим ситуацию: пользователь отправляет сообщение в чат 1С и прикрепляет к нему файл (например, скриншот ошибки или скан накладной). Нам необходимо программно перехватить это сообщение (например, в боте или обработчике событий), извлечь файл и произвести с ним манипуляции: сохранить на диск, отправить в ответном сообщении или записать в базу данных.

Для реализации этой задачи нам потребуются следующие объекты платформы:

  1. СистемаВзаимодействия — основной менеджер для работы с функционалом.
  2. СообщениеСистемыВзаимодействия — объект, содержащий текст и вложения.
  3. ВложениеСистемыВзаимодействия — объект, представляющий сам файл.
  4. Поток и ЧтениеДанных — механизмы для получения содержимого файла.

Подробный разбор решения

Рассмотрим код, который позволяет решить эту задачу. Мы будем действовать последовательно, разбирая каждую строчку. Предположим, что у нас уже есть контекст входящего сообщения (переменная Сообщение).

1. Получение контекста обсуждения

Прежде чем формировать ответ или работать с контекстом, часто требуется получить объект самого обсуждения. Это делается через идентификатор обсуждения, который хранится в сообщении.


// Получаем объект обсуждения по ссылке из сообщения
Обсуждение = СистемаВзаимодействия.ПолучитьОбсуждение(Сообщение.Обсуждение);

2. Доступ к коллекции вложений

Вложения хранятся в коллекции Вложения объекта сообщения. Важно понимать, что в одном сообщении может быть несколько файлов. В простейшем примере мы обратимся к первому файлу по индексу 0, однако в промышленном коде мы настоятельно рекомендуем использовать обход коллекции.


// Получаем первое вложение из списка (индекс 0)
ВложенияТекущегоОбсуждения = Сообщение.Вложения.Получить(0);

Важное замечание: Обращение по индексу Получить(0) без предварительной проверки количества элементов (Сообщение.Вложения.Количество() > 0) вызовет ошибку, если пользователь отправил сообщение без файлов. Всегда добавляйте проверку на наличие вложений.

3. Чтение содержимого через потоки

Начиная с современных версий платформы 1С, работа с файлами в Системе взаимодействия осуществляется через потоки. Это позволяет эффективно работать с памятью. Метод ОткрытьПотокДляЧтения возвращает объект Поток, из которого мы можем читать данные.


// Открываем поток для чтения данных вложения
Поток = ВложенияТекущегоОбсуждения.ОткрытьПотокДляЧтения();

// Инициализируем чтение данных из потока
Чтение = Новый ЧтениеДанных(Поток);

Теперь, когда у нас есть объект ЧтениеДанных, мы можем извлечь содержимое файла в виде двоичных данных. Это универсальный формат, для которого существует алхимический способ работы с двоичными данными в 1С, позволяющий удобно сохранять их или передавать по HTTP.


// Получаем двоичные данные файла
ДвоичныеДанныеВложения = Чтение.Прочитать().ПолучитьДвоичныеДанные();

4. Сохранение файла на диск (Пример работы с временными файлами)

Частый сценарий — сохранить полученный файл во временную директорию для обработки. Рассмотрим, как это сделать.


// Генерируем уникальное имя временного файла с расширением (например, .png)
ИмяФайла = ПолучитьИмяВременногоФайла(".png");

// Записываем полученные двоичные данные на диск
ДвоичныеДанныеВложения.Записать(ИмяФайла);

Формирование ответного сообщения с вложением

Давайте посмотрим, как работает обратная операция. Допустим, мы обработали файл и хотим отправить его обратно пользователю или переслать в другое обсуждение. Для этого нам снова понадобятся потоки, но теперь — файловые.


// Создаем новое сообщение в рамках текущего обсуждения
Ответ = СистемаВзаимодействия.СоздатьСообщение(Обсуждение.Идентификатор);

// Добавляем информативный текст
Ответ.Текст = "Файл получен. Размер: " + Строка(ВложенияТекущегоОбсуждения.Размер);

// Открываем сохраненный ранее файл для чтения
НовыйПоток = ФайловыеПотоки.ОткрытьДляЧтения(ИмяФайла);

// Добавляем поток как вложение к новому сообщению
// Важно указать имя файла и MIME-тип (например, "image/png")
Ответ.Вложения.Добавить(НовыйПоток, "processed_image.png", "image/png");

// Отправляем сообщение
Ответ.Записать();

После завершения работы крайне важно освободить ресурсы. Потоки необходимо закрывать, а для обслуживания системы использовать регламентные задания и программный интерфейс, удаляя временные файлы, чтобы не засорять дисковое пространство.


// Закрываем потоки
Поток.Закрыть();
НовыйПоток.Закрыть();

// Удаляем временный файл
УдалитьФайлы(ИмяФайла);

Продвинутые техники и важные нюансы

Разберем аспекты, которые помогут сделать ваш код более надежным и производительным, основываясь на технической документации и опыте эксплуатации.

Типы вложений

В Системе взаимодействия существует два типа вложений, и работать с ними нужно по-разному:

  1. Стандартное вложение: Файл физически хранится на сервере Системы взаимодействия. Именно этот вариант мы разобрали выше. Метод ОткрытьПотокДляЧтения работает идеально.
  2. Внешнее вложение: Это ссылка на внешний ресурс (облако, веб-сайт). Объект называется ВнешнееВложениеСистемыВзаимодействия. Для него вместо потока данных вы будете работать с URL-адресом.

Оптимизация: Избегаем лишних временных файлов

В примере выше мы сохраняли данные на диск (ИмяФайла). Однако, если ваша задача — просто переслать файл или сохранить его в справочник ПрисоединенныеФайлы, создание временного файла на диске может быть излишним и замедлять работу.

Вы можете использовать метод КопироватьДанные для перелива данных из одного потока в другой или работать напрямую с ДвоичныеДанные, если объем памяти позволяет. Например, для записи в справочник достаточно получить Двоичные Данные и поместить их в реквизит типа ХранилищеЗначения.

Работа с коллекцией вложений

Как мы упоминали ранее, жесткая привязка к индексу 0 — плохая практика. Правильный подход выглядит так:


Для Каждого Вложение Из Сообщение.Вложения Цикл
    // Проверяем тип вложения, если нужно
    Если ТипЗнч(Вложение) = Тип("ВложениеСистемыВзаимодействия") Тогда
        ПотокЧтения = Вложение.ОткрытьПотокДляЧтения();
        // Дальнейшая обработка...
        ПотокЧтения.Закрыть();
    КонецЕсли;
КонецЦикла;

MIME-типы и расширения

При программном добавлении вложения (метод Ответ.Вложения.Добавить) третьим параметром указывается MIME-тип (например, "application/pdf", "image/jpeg"). Если вы не укажете его или укажете неверно, клиентское приложение может не понять, как открыть файл (как картинку или как просто файл).

Для автоматического определения типа по расширению файла в платформе 1С существуют вспомогательные методы, такие как ПолучитьMIMEТипПоРасширению() (начиная с определенных версий БСП или платформенных утилит), которые стоит использовать для универсальности.

Контекст исполнения

Обратите внимание, что методы работы с Системой взаимодействия доступны как на Сервере, так и на Клиенте. Однако при работе с файлами учитывайте контекст:

Используя эти приемы и библиотеку искусственного интеллекта для 1С, вы сможете создавать умных ботов и обработчики, которые автоматически распознают документы, сохраняют сканы в базу 1С или маршрутизируют файлы между отделами.

← На главную