При автоматизации рассылки уведомлений из 1С часто возникает задача отправить пользователю приглашение на событие или встречу. Если просто сформировать файл с расширением .ics и прикрепить его к объекту ИнтернетПочтовоеСообщение через коллекцию Вложения, большинство почтовых клиентов (Gmail, Яндекс.Почта, Outlook) отображают его как обычный прикрепленный документ. При этом форма интерактивного добавления события в календарь с кнопками «Принять» или «Отклонить» не появляется.
В этой статье мы подробно разберем причины такого поведения платформы 1С, изучим структуру данных iCalendar и рассмотрим рабочие способы отправки корректных приглашений.
Почтовые сервисы определяют письмо как интерактивную встречу в соответствии со стандартом iMIP (RFC 6047). Для этого календарные данные должны передаваться внутри секции multipart/alternative с типом контента text/calendar; method=REQUEST, а не в качестве стандартного вложения с заголовком Content-Disposition: attachment.
Когда мы добавляем файл в коллекцию ИнтернетПочтовоеСообщение.Вложения, платформа 1С принудительно оборачивает его в секцию multipart/mixed как скачиваемый файл. Даже если вручную указать для объекта ИнтернетПочтовоеВложение тип содержимого text/calendar, почтовые серверы все равно воспринимают его как обычный файл из-за заголовков вложения. Кроме того, в самом объекте ИнтернетПочтовоеСообщение нет встроенной возможности поместить часть text/calendar в блок альтернативных тел письма наряду с text/plain и text/html.
Проанализируем структуру самого файла .ics. Чтобы почтовый клиент понял, что это приглашение, требующее ответа, тело календаря должно содержать директивы протокола iTIP:
METHOD:PUBLISH используется только для публикации статичного расписания без кнопок принятия).RSVP=TRUE).Посмотрим на пример формирования текста календаря в 1С:
ДанныеПриглашения = "BEGIN:VCALENDAR" + Символы.ПС
+ "PRODID:-//1C:Enterprise//Calendar Integration//RU" + Символы.ПС
+ "VERSION:2.0" + Символы.ПС
+ "CALSCALE:GREGORIAN" + Символы.ПС
+ "METHOD:REQUEST" + Символы.ПС
+ "BEGIN:VEVENT" + Символы.ПС
+ "UID:" + Строка(Новый УникальныйИдентификатор) + Символы.ПС
+ "DTSTAMP:20260330T090000Z" + Символы.ПС
+ "DTSTART:20260401T100000Z" + Символы.ПС
+ "DTEND:20260401T110000Z" + Символы.ПС
+ "ORGANIZER;CN=""Организатор"":mailto:organizer@domain.ru" + Символы.ПС
+ "ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=""Участник"":mailto:client@domain.ru" + Символы.ПС
+ "SUMMARY:Совещание по проекту" + Символы.ПС
+ "DESCRIPTION:Обсуждение этапов внедрения информационной системы" + Символы.ПС
+ "LOCATION:Переговорная №1" + Символы.ПС
+ "SEQUENCE:0" + Символы.ПС
+ "STATUS:CONFIRMED" + Символы.ПС
+ "TRANSP:OPAQUE" + Символы.ПС
+ "END:VEVENT" + Символы.ПС
+ "END:VCALENDAR";
Разберем основной способ решения задачи штатными средствами платформы. Мы можем полностью сформировать тело почтового сообщения в стандарте MIME с правильной иерархией блоков и загрузить его в ИнтернетПочтовоеСообщение с помощью метода УстановитьИсходныеДанные().
Рассмотрим по шагам, как строится такое сообщение:
boundary).From, To, Subject, MIME-Version, Content-Type: multipart/alternative).text/calendar; method=REQUEST; charset="utf-8", закодированную в Base64 с помощью функции Base64Строка().Посмотрим на пример реализации кода:
Граница = "----=_Part_" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
ТекстEML = "From: organizer@domain.ru" + Символы.ВК + Символы.ПС
+ "To: client@domain.ru" + Символы.ВК + Символы.ПС
+ "Subject: =?UTF-8?B?" + Base64Строка(ЗакодироватьСтроку("Приглашение на встречу", СпособКодированияСтроки.КодировкаURL)) + "?=" + Символы.ВК + Символы.ПС
+ "MIME-Version: 1.0" + Символы.ВК + Символы.ПС
+ "Content-Type: multipart/alternative; boundary=""" + Граница + """" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС
+ "--" + Граница + Символы.ВК + Символы.ПС
+ "Content-Type: text/plain; charset=UTF-8" + Символы.ВК + Символы.ПС
+ "Content-Transfer-Encoding: base64" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС
+ Base64Строка(ПолучитьДвоичныеДанныеИзСтроки("Вам направлено приглашение на встречу.", "UTF-8")) + Символы.ВК + Символы.ПС
+ "--" + Граница + Символы.ВК + Символы.ПС
+ "Content-Type: text/calendar; charset=UTF-8; method=REQUEST" + Символы.ВК + Символы.ПС
+ "Content-Transfer-Encoding: base64" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС
+ Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(ДанныеПриглашения, "UTF-8")) + Символы.ВК + Символы.ПС
+ "--" + Граница + "--";
ДвоичныеДанныеПисьма = ПолучитьДвоичныеДанныеИзСтроки(ТекстEML, "UTF-8", Ложь);
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.УстановитьИсходныеДанные(ДвоичныеДанныеПисьма);
Почта = Новый ИнтернетПочта;
Почта.Подключиться(Профиль);
Почта.Послать(Письмо);
Почта.Отключиться();
Если сервер 1С работает под управлением ОС Windows, можно использовать компонент CDO.Message. Он предоставляет низкоуровневый доступ к коллекции составных частей письма BodyParts, что позволяет вручную задать заголовок Content-Type: text/calendar; method=REQUEST для вложенного блока без принудительного добавления заголовков загрузки файла.
Если корпоративная почта развернута на современных почтовых платформах (например, Яндекс 360, Google Workspace или корпоративный Microsoft Exchange), надежным решением является создание встречи напрямую через их HTTP API с использованием объекта HTTPСоединение. В этом случае событие создается на стороне почтового сервера, а сам сервер автоматически генерирует и рассылает нативные интерактивные приглашения всем указанным участникам.
В качестве альтернативного или дополняющего варианта в HTML-тело обычного письма можно встроить прямые веб-ссылки быстрого добавления события. При переходе по такой ссылке у пользователя в браузере сразу открывается предзаполненная форма создания встречи с установленными датами, временем и описанием.