Полный учебный модуль для отдельного локального почтового стенда: реальные IMAP/SMTP-контракты, свои сообщения/UID/папки и проверяемые эффекты. В ходе подготовки справочника почта и сеть не выполняются.
Где и как запускать
Полный клиентский общий модуль УчебнаяПочта85, толстое управляемое Windows-приложение; собственный loopback-сервер и отдельный полный модуль формы вызова.
Подготовка
Новая пустая конфигурация УчебнаяПочта85, платформа8.5.1.1343, управляемое приложение и именно толстый Windows-клиент. Учебный клиент и отдельный тестовый почтовый сервер на одной машине; рабочие почтовые профили не используются.
Установленный ИнтернетПочта использует SMTP/POP3/IMAP, не MAPI. Нативная справка прямо говорит: SSL есть, проверки сертификата клиента/сервера нет. Код этого урока не выдаётся за защищённую production-интеграцию.
Ваш собственный локальный сервер слушает только127.0.0.1:1143(IMAP) и127.0.0.1:1025(SMTP). Исходящая доставка/relay/DNS и внешние подключения запрещены настройкой сервера; SMTP только принимает в вашу локальную тестовую очередь.
Создайте нового отдельного пользователя lab85 с собственным ASCII-паролем не более64 символов и отдельной почтовой областью. IMAP поддерживает hierarchy с выбираемыми родительскими папками, UIDPLUS, Flagged/Deleted/Seen и обычную тестовую аутентификацию; SMTP поддерживает AUTH LOGIN для lab85.
Локальная модель намеренно допускает обычную аутентификацию; это не шифрование и не безопасный рецепт для LAN/интернета. Настройка SSLIMAP устанавливается до нестандартного порта1143, потому что смена SSL-флага меняет порт по умолчанию.
Только один клиент/автор и никакие параллельные доставщики. Квота тестового пользователя не более1МиБ, каждое учебное письмо не более4КиБ. Нет чужих сообщений, ссылок на реальные вложения и рабочих папок.
Для первого урока вручную подготовьте папку LAB85_Read с ровно одним письмом: тема MAIL-LAB85-READ, простой текст MAIL-LAB85, без вложений, нечастичное, без Deleted. Этот исходный образец не удаляется.
Для второго и четвёртого урока новые пространства LAB85_UUID/LAB85_MERGE_UUID создаёт только сам учебный код. IMAP-перенос требует UIDPLUS. INBOX используется только как место выхода из своей папки: его письма не выбираются, не помечаются и не очищаются.
Общие → Общие модули → УчебнаяПочта85: Клиент(управляемое приложение)=Истина, Сервер/ВызовСервера/Глобальный/Привилегированный/ВнешнееСоединение=Ложь, повторное использование выключено. Основной полный модуль одного урока вставляется целиком, одноимённые функции не склеиваются.
Обработки → ЗапускПочты85 → управляемая форма Форма: СогласенНаЛокальнуюПочту85 и Занято85 Булево исходно Ложь; ПарольУчебнойПочты85 Строка, Итог85 Строка неограниченной длины только для просмотра. Пароль не сохраняйте в настройках/истории; включите скрытое отображение поля в редакторе формы.
Отдельный полный модуль формы — дополнительный блок. Команда ВыполнитьПочту85 назначается кнопке, Действие=ВыполнитьПочту85, вызывает клиентский УчебнаяПочта85.ВыполнитьПример85(согласие,пароль); после успеха/ошибки реквизит пароля очищается.
F7 и обновление только своего стенда. Сначала читающий урок, затем собственный цикл IMAP, затем SMTP и MIME. Разрешение на каждый будущий ручной сетевой опыт отдельно; здесь его выполнения нет.
У MIME-урока две ASCII-части message/partial создаются из настоящих исходных MIME-байтов и разбираются УстановитьИсходныеДанные; в собственную папку добавляются по IMAP. Номера1/2, общий id, total2, 7bit и разрыв по CRLF соответствуют RFC2046 §5.2.2: https://www.rfc-editor.org/rfc/rfc2046.html#section-5.2.2 .
runtimeVerifiedScenarios=0:1С/серверы/GUI не запускались, реальная почта и сеть не вызывались, сообщения не отправлялись/удалялись и новые резервные копии/архивы не создавались. Приведённые эффекты относятся только к будущему отдельно разрешённому ручному выполнению.
Функция ВыполнитьПример85(Согласие, Пароль) Экспорт
Если Не Согласие Тогда
ВызватьИсключение "Нужен свой локальный изолированный почтовый стенд УчебнаяПочта85 и согласие";
КонецЕсли;
Если ТипЗнч(Пароль) <> Тип("Строка") Или СтрДлина(Пароль) = 0 Или СтрДлина(Пароль) > 64 Тогда
ВызватьИсключение "Нужен отдельный ASCII-пароль своего локального тестового пользователя";
КонецЕсли;
Почта = Неопределено;
Маркер = "LAB85_SMTP_" + Строка(Новый УникальныйИдентификатор);
Попытка
Почта = Новый ИнтернетПочта;
Почта.Подключиться(СвойПрофиль85(Пароль, Истина));
Письмо = СвоёПисьмо85(Маркер, "MAIL-LAB85:" + Маркер);
Отказы = Почта.Послать(Письмо, ОбработкаТекстаИнтернетПочтовогоСообщения.НеОбрабатывать, ПротоколИнтернетПочты.SMTP);
Если ТипЗнч(Отказы) <> Тип("Соответствие") Тогда
ВызватьИсключение "Послать должно вернуть настоящее соответствие отказавших получателей";
КонецЕсли;
Если Отказы.Количество() <> 0 Тогда
ВызватьИсключение "Свой SMTP не принял всех тестовых получателей; сырые адресные ошибки не выводятся";
КонецЕсли;
Почта.Отключиться();
Почта = Неопределено;
Возврат "Локальный SMTP принял сообщение " + Маркер + ". Это не подтверждение доставки. Найдите ровно этот маркер в своей локальной тестовой очереди; повторять отправку после неопределённой ошибки нельзя.";
Исключение
ЗакрытьПослеОшибки85(Почта);
ВызватьИсключение "SMTP-отправка не подтверждена; проверьте свой локальный журнал/очередь по маркеру " + Маркер + ". Повторной отправки нет, пароль и сырые ошибки не выводятся.";
КонецПопытки;
КонецФункции
Функция СвойПрофиль85(Пароль, ДляSMTP)
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераPOP3 = "";
Профиль.АдресСервераIMAP = "";
Профиль.АдресСервераSMTP = "";
Профиль.Таймаут = 15;
Если ДляSMTP Тогда
Профиль.ИспользоватьSSLSMTP = Ложь;
Профиль.АдресСервераSMTP = "127.0.0.1";
Профиль.ПортSMTP = 1025;
Профиль.ПользовательSMTP = "lab85";
Профиль.ПарольSMTP = Пароль;
Профиль.АутентификацияSMTP = СпособSMTPАутентификации.Login;
Профиль.ТолькоЗащищеннаяАутентификацияSMTP = Ложь;
Иначе
Профиль.ИспользоватьSSLIMAP = Ложь;
Профиль.АдресСервераIMAP = "127.0.0.1";
Профиль.ПортIMAP = 1143;
Профиль.ПользовательIMAP = "lab85";
Профиль.ПарольIMAP = Пароль;
Профиль.ТолькоЗащищеннаяАутентификацияIMAP = Ложь;
КонецЕсли;
Возврат Профиль;
КонецФункции
Процедура ЗакрытьПослеОшибки85(Почта)
Если Почта <> Неопределено Тогда
Попытка
Почта.Отключиться();
Исключение
ВызватьИсключение "Опыт и отключение не подтверждены; проверьте только свой локальный сервер. Сырые ошибки и пароль не выводятся.";
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Функция СвоёПисьмо85(Тема, Тело)
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Отправитель = "lab85@lab.invalid";
Письмо.Получатели.Добавить("sink85@lab.invalid");
Письмо.Тема = Тема;
Письмо.Тексты.Добавить(Тело);
Возврат Письмо;
КонецФункцииУправляемая команда локального почтового опыта
УчебнаяПочта85 → Обработки → ЗапускПочты85 → Формы → Форма → Модуль
Полный модуль своей формы: команда ВыполнитьПочту85, Действие=ВыполнитьПочту85; согласие и отдельный пароль передаются клиентскому общему модулю.
&НаКлиенте
Процедура ВыполнитьПочту85(Команда)
Если Не СогласенНаЛокальнуюПочту85 Или Занято85 Тогда
ВызватьИсключение "Нужно отдельное согласие на свой локальный почтовый опыт";
КонецЕсли;
Занято85 = Истина;
Попытка
Итог85 = УчебнаяПочта85.ВыполнитьПример85(СогласенНаЛокальнуюПочту85, ПарольУчебнойПочты85);
Исключение
ПарольУчебнойПочты85 = "";
Занято85 = Ложь;
Итог85 = "Опыт не подтверждён. Проверьте только свой локальный стенд; подробности с учётными данными не отображаются.";
ВызватьИсключение "Локальный почтовый опыт не завершён";
КонецПопытки;
ПарольУчебнойПочты85 = "";
Занято85 = Ложь;
КонецПроцедурыРазбор по шагам
Только свой loopback-профиль SMTP1025, пустые адреса IMAP/POP3 исключают подключение к чужому получению.
Случайный маркер делает тестовую отправку различимой в вашей локальной очереди.
Создаётся своё простое письмо без HTML, картинок и внешних вложений, получатель фиксирован sink85@lab.invalid.
Послать получает НеОбрабатывать и явно SMTP, возвращает реальное соответствие отказов.
Пустая карта подтверждает принятие на этом этапе, не доставку/прочтение; локальная очередь проверяется отдельно вручную.
Успех отключает сессию, ошибка не запускает повтор и не выводит пароль или сырую диагностику.
Как проверить результат
В профиле задан только127.0.0.1:1025 для SMTP.
Письмо содержит уникальный собственный маркер.
Результат Послать — Соответствие, все отказы проверены.
Принятие не выдаётся за доставку; очередь ищется по маркеру.
После неопределённой ошибки нет повторной отправки.
Ожидаемый результат
Ожидаемые результаты относятся к будущему отдельно разрешённому ручному опыту. Реальная1С/почта/сеть не запускались, runtimeVerifiedScenarios=0.
На что обратить внимание
Выбрать() по умолчанию удаляет сообщения. Для чтения указаны Ложь и Ложь: не удалять и не отмечать прочитанными. Последний флаг актуален для IMAP, для POP3 допустима только Истина.
Пустой или неуказанный второй массив Выбрать означает получить все письма, не получить ничего. Во всех уроках перед выборкой проверяется строго положительное собственное число UID.
Фильтр ПолучитьЗаголовки/ПолучитьИдентификаторы действует только IMAP; POP3 игнорирует его. Неизвестный ключ фильтра тоже может игнорироваться. Читающая папка содержит ровно один собственный проверяемый образец.
ПолучитьЗаголовки возвращает ограниченный набор полей: тело/вложения ещё не получены. Полное письмо отдельно загружается по настоящему UID и проверяется по теме, составу и нормализованному простому тексту.
UID уникален в пределах папки, не всей системы. После переноса или переименования код снова получает реальные идентификаторы, не использует порядковый номер строки или старый UID другого ящика.
СимволРазделитель получен от своего сервера, не жёстко задан /. Иерархия создаётся только внутри своего случайного корня; сервер без подходящей иерархии не объявляется совместимым.
Подписка и выбор текущей папки — разные действия. Список подписанных имён проверяется после подписки и отмены; изменение подписки не отправляет письмо.
Послать(...,IMAP) добавляет сообщение в текущую папку IMAP, это не SMTP-доставка получателю. SMTP-урок отдельно использует SMTP и локальную тестовую очередь.
Послать возвращает Соответствие отказов получателей. Пустое соответствие означает принятие на этом этапе, не подтверждение окончательной доставки или прочтения; исключение не разрешает слепой повтор отправки.
SSL-флаг/ТолькоЗащищеннаяАутентификация не доказывает проверку сертификата. Нативный ИнтернетПочта этого не предоставляет; профиль данного урока допускается только на отдельном loopback-стенде без реальных секретов.
АутентификацияSMTP/СпособSMTPАутентификации.Login устарели и не рекомендуются с8.3.1. Здесь они явно показывают контракт отдельного тестового AUTH LOGIN в толстом клиенте; это не рекомендация для новой production-интеграции.
УстановитьФлагиСообщений принимает соответствие UID→ФлагиИнтернетПочтовогоСообщения, не массив UID. Истина ставит, Ложь снимает, Неопределено оставляет флаг; неподдерживаемый флаг сервер может проигнорировать.
Урок меняет Flagged в реально полученном объекте флагов, перечитывает результат и требует поддержку Flagged/Deleted. Снимок других флагов не атомарен; поэтому нет сторонних клиентов и доставщиков.
УдалитьСообщения при IMAP сначала ставит Deleted, ОтменитьУдалениеСообщений снимает пометку, ОчиститьУдаленныеСообщения удаляет ВСЕ Deleted текущей папки. Очистка разрешена только в своей папке с одним подтверждённым собственным письмом.
УдалитьПочтовыйЯщик удаляет папку со всем содержимым. Второй урок удаляет лишь свои проверенные пустые папки; MIME-урок — только свою папку с двумя подтверждёнными UID. Восстановление/корзина не обещаются.
ПереместитьВПочтовыйЯщик требует UIDPLUS и существующую собственную папку. При ошибке/частичном эффекте код ничего не удаляет и не повторяет автоматически; проверьте своё пространство вручную.
message/partial — не multipart/mixed и не вручную установленный readonly-флаг Частичное. Две реально разобранные части имеют общий MIME-id, но разные Message-ID и настоящие UID своей папки.
ОбъединитьЧастичные работает с реальными полученными объектами в RAM: неполный набор остаётся частичным, полный набор проверяется по двум строкам и двум настоящим UID. Это не серверное объединение писем.
Нормализация текста допускает только обычные конечные пробелы/переводы строк данного маленького ASCII-образца. Это не проверка произвольного бинарного вложения и не лимит потока получения; квота и неизменяемый тестовый сервер обязательны.
Пароль и сырые серверные исключения не выводятся. Очистка реквизита не гарантирует стирание всех копий в RAM. Ошибка отключения тоже сообщается явно, а не проглатывается.
Отключиться закрывает сессию, но не является откатом отправки, перемещения, пометок или удаления. После сбоя фактическое состояние проверяется только на своём сервере.
1С/SMTP/IMAP не запускались: runtimeVerifiedScenarios=0. Статические тесты проверяют контракт и код, не фактическое поведение конкретного почтового сервера.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.