Привет, меня зовут Елена Тихомирова, я работаю системным аналитиком в Платформе Сфера, разработке Холдинга Т1. Если по велению души или начальства вы хотите заняться автоматизацией обработки электронных писем, но не знаете, из чего именно состоит письмо, — эта статья для вас. Я опишу общую структуру и рассмотрю примеры её реализации в зависимости от содержания послания.
Общие сведения
Электронное письмо содержит такую информацию:
тема;
адреса и имена отправителей и получателей;
текст письма;
прикреплённые файлы;
различную служебную информацию.
Привычный вам вид письма в почтовом клиенте отличается от его «кода» так же сильно, как отображение веб-страницы в браузере отличается от HTML-файла. В «коде» электронного письма кроме «полезной нагрузки» содержится ещё и техническая информация, благодаря которой возможна как пересылка письма, так и интерпретация его структуры и содержимого почтовыми клиентами.
Стандартный формат электронных писем — MIME. Это формат или тип именно письма, тогда как один из форматов файла, в котором письмо сохраняется, — .eml. Если такой файл открыть в почтовом клиенте, то вы увидите обычное электронное письмо, как будто вы его выбрали в папке «Входящие». А если открыть .eml в текстовом редакторе, то на экране отобразится непривычное содержимое: длинный список параметров на английском языке, у которых через двоеточие указано какое-то значение в зашифрованном виде. Это заголовки письма, часть из которых «говорит», кто отправитель, когда отправлено, какая тема. Остальные заголовки известны специалистам и не относятся к теме этой статьи. За заголовками следует тело письма, тоже зашифрованное и разделённое «границами» на части. Они могут содержать текст в одном из текстовых форматов и вложенные файлы. Именно этим частям, их разграничению и группировке посвящена моя статья.
Чтобы потренироваться по ходу чтения, можете скачать письмо в формате .eml и попытаться найти в нём указанные части. Инструкция, как это сделать, приведена в конце статьи.
Вот две схемы структуры письма в формате MIME:
А теперь приведу своё толкование, как наполняется структура письма в зависимости от его содержимого.
Части письма
В электронном письме выделяют следующие структурные элементы:
1. Конверты и заголовки.
-
2.Содержимое (body) и его части (body parts).
-
2.1.Текст письма.
2.1.1.HTML‑версия текста.
2.1.2.Plaintext‑версия текста.
2.2.Прикреплённый файл (attachment).
2.3.Встроенное в текст изображение (inline).
-
Все части письма, кроме конверта, являются опциональными: как в случае с обычной почтой, нужна лишь информация для доставки, тогда как содержимое конверта может быть пустым. Тем не менее, большинство почтовых клиентов обязательно передают часть с текстом письма (2.1), даже пустую, если отправитель не написал ни символа. Кроме того, в отличие от обычной почты, текст электронного письма может содержать не только одно сообщение отправителя, но и всю переписку по определённой теме. В таком случае часть с текстом письма независимо от формата (HTML или plaintext) включает в себя всю цепочку сообщений в обратном хронологическом порядке. У таких цитируемых сообщений тоже есть заголовки, но их минимум: отправитель, адресаты, дата, тема.
Заголовки есть не только у текстовых частей и конверта, но и у прикреплённых файлов и встроенных изображений — передаются метаданные этих файлов.
В прикреплённых файлах (2.2) содержатся файлы, добавленные последним отправителем. Выделяется по одной части на файл.
Как встроенные изображения (2.3) передаются вставленные в текст скриншоты, логотипы, фотографии и другие картинки. Файл изображения «оформляется» в специальной части для встроенных изображений (inline), по одной части на файл. В тексте письма в месте вставки есть ссылка на файл нужного изображения. Благодаря этому почтовый клиент отображает текст, в который картинки вставлены в правильных местах, а не текст отдельно, картинки отдельно.
Возможен и другой вариант передачи графических файлов в электронном письме. Чаще всего этот подход используется в email-рассылках: содержимое небольшого файла вставляют в атрибут src
тега <img>
в HTML-версии письма. В plaintext-версии (при наличии) указывается ссылка на имя этого файла из атрибута alt
тега <img>
. В этом случае отдельной inline-части для изображения не требуется.
Контейнеры
Выше мы рассматривали части письма, которые имеют определённое содержимое (пп. 2.1-2.3). Также есть части письма, которые выступают в роли дополнительных конвертов, — контейнеры (неофициальный термин). Как папки в файловом хранилище, они помогают логически организовать другие части тела и сами могут быть вложены друг в друга, как матрёшки.
В названии такой части письма, как контейнер, указан тип multipart
. Например, Content-type: multipart/alternative
. Тип более простых частей (пп. 2.1-2.3) обычно связан с их форматом:
Content-type: text/plain
Content-type: video/mpeg
Content-type: image/jpeg
Когда почтовый клиент раскладывает содержимое письма по контейнерам:
Если передаются обе версии текста, то они вкладываются в контейнер
multipart/alternative
. Если письмо отправляется только в HTML‑ или plaintext‑версии и не содержит встроенных картинок или прикреплённых файлов, то контейнеров нет и письмо вкладывается непосредственно в корень (в конверт).Прикреплённые файлы всегда вкладываются в контейнер
multipart/mixed
. Как и у всех частей, у этих файлов указывают заголовокContent‑type
с MIME‑типом содержимого, а также дополнительный заголовок, уточняющий, что этот контент прикреплён:Content‑Disposition: attachment
. Помимо файлов, в этот же контейнерmultipart/mixed
добавляют контейнер с текстом —multipart/alternative
. Частный случай: если к письму прикреплён файл .eml в качестве вложения, то он располагается как отдельная часть (тип расположенияattachment
) тоже вmultipart/mixed
, при этом содержит свои заголовки, контейнеры и вложенные в них части.Встроенные в текст изображения «складывают» в контейнер
multipart/related
— по одной части на каждую картинку, у каждой части указанContent‑type
и значение заголовкаContent‑Disposition: inline
. В этот контейнер также вкладывают текст письма (который, в свою очередь, вложен в контейнерmultipart/alternative
). Если в письме содержатся ещё и прикреплённые файлы, тоmultipart/related
со всем содержимым (текстом и картинками из этого текста) складывают вmultipart/mixed
.
Другими словами, наполнение контейнеров можно схематически описать так:
-
Письмо с вложениями помещается в контейнер
multipart/mixed
. Это самый верхний из возможных контейнеров.-
Если вложений нет, то контейнера
multipart/mixed
тоже нет. Самым верхним становится контейнерmultipart/related
(при наличии встроенных картинок).-
Если картинок нет, то самым верхним становится
multipart/alternative
(при наличии и HTML‑, и plaintext‑версии письма).Если же есть только какая‑то одна версия текста, то она передаётся без контейнера. Такое письмо содержит только конверт и эту одну часть (HTML‑ или plaintext‑версию текста письма).
-
-
Примеры заголовков частей письма
Inline images — встроенные в текст изображения и их заголовки
Изображение, вставленное в текст письма, передаётся в одном контейнере multipart/related
с текстом, в который оно вставлено. Передаются все встроенные в текст изображения, вне зависимости от того, новое это сообщение в переписке или цитируемое.
Заголовки:
Content-Type: image/png; name="image001.png"
Content-Description: image001.png
Content-Disposition: inline; filename="image001.png"; size=3621;
creation-date="Tue, 21 Nov 2023 06:27:15 GMT";
modification-date="Tue, 21 Nov 2023 06:27:15 GMT"
Content-ID: <image001.png@01DA1C5C.E9556E30>
Content-Transfer-Encoding: base64
Ссылка на этот файл есть и в разделе plaintext-версии:
[cid:image001.png@01DA1C5C.E9556E30]
и в HTML:
<img naturalheight=3D"123" naturalwidth=3D"102" width=3D"102" height=3D"123=" id=3D"=D0=E8=F1=F3=ED=EE=EA_x0020_1" style=3D"width: 1.0625in; height: 1.=2847in; user-select: none;" src=3D"cid:image001.png@01DA1C5C.E9556E30">
Attachments — прикреплённые к письму файлы и их заголовки
Вложения передаются в контейнере multipart/mixed
, в который могут входить:
контейнер
multipart/related
(содержит текст письма (plaintext, HTML), а также встроенные (inline) картинки);сами прикреплённые файлы (по одной части attachment на каждый файл).
Прикреплённые файлы передаются только с последним ответом в цепочке. То есть, при отправке ответного письма пользователь выбирает, какие файлы прикрепить: из своих или из уже приложенных к тому письму, на которое он отвечает. Все вложенные файлы за всю историю переписки НЕ передаются.
Заголовок Content-Type части с вложенным файлом указывает на формат этого файла. Формат может быть разный: application/octet-stream, image/jpeg, application/msword, text/asciidoc, text/json, text/plain, text/html и т. д.
Как мы видим из списка, в формате HTML или plaintext может быть не только текст письма, но и вложенный файл. В этом случае сохраняются основные отличия между такими частями письма (body parts), как текст и вложенный файл:
Вложенный файл всегда находится внутри контейнера
multipart/mixed
. Этот контейнер и появляется только тогда, когда есть вложенные файлы. Однако текст письма тоже может быть сразу внутри контейнераmultipart/mixed
, без «посредников». Это происходит иногда: если текст письма передан только в одном формате, а не в обоих (text/plain
илиtext/html
) и если нет встроенных картинок, что бывает относительно редко. Чаще текст письма вложен сначала в контейнерmultipart/alternative
, затем вmultipart/related
, и только потом уже вmultipart/mixed
.-
Заголовки и их атрибуты у вложенного файла и текста в аналогичном формате отличаются. У файла:
Content-Type: text/plain; name="?.txt" Content-Description: ?.txt Content-Disposition: attachment; filename="?"; size=?;creation-date=?; modification-date=?
У текста письма:
Content-Type: text/plain; charset="?"
или
Content-Type: text/html; charset="?"
Ещё примеры заголовков вложенных файлов:
-
Изображение:
Content-Type: image/png; name="Notifications architecture.png" Content-Description: Notifications architecture.png Content-Disposition: attachment; filename="Notifications architecture.png"; size=105312; creation-date="Mon, 27 May 2024 14:12:44 GMT"; modification-date="Mon, 27 May 2024 14:12:44 GMT" Content-Transfer-Encoding: base64
-
Письмо в формате.eml:
Content-Type: application/octet-stream; name="original_msg (1).eml" Content-Description: original_msg (1).eml Content-Disposition: attachment; filename="original_msg (1).eml"; size=14108; creation-date="Mon, 27 May 2024 18:45:26 GMT"; modification-date="Mon, 27 May 2024 18:45:26 GMT" Content-Transfer-Encoding: base64
На этом я заканчиваю свой краткий обзор. Надеюсь, вам удалось лучше понять вложенную структуру электронного письма и разложить её не только по полочкам, но и как иерархическое дерево. В заключение напоминаю о возможности самостоятельно посмотреть, из чего же состоит код письма, полученного от коллеги или из email‑рассылки. Для этого ознакомьтесь со следующей инструкцией.
Как скачать письмо в формате.eml
Файл в формате.eml содержит полный оригинал письма, в том числе все заголовки и вложения. В этом формате можно скачать письмо из некоторых почтовых клиентов, например, Gmail или Thunderbird. Там всё просто: просмотр оригинала и скачивание есть в опциях письма. Нужно его только открыть и нажать на «Ещё».
У популярного в корпоративной среде Outlook есть свои ограничения, однако и он позволяет скачать письмо в нужном формате. Из веб‑интерфейса почты Outlook (OWA):
Откройте почтовый ящик в браузере.
Нажмите на «Создать» и выберите «Сообщение» или откройте черновик письма.
Перетащите из списка писем то, которое вы хотите сохранить в формате.eml, в открытый черновик нового письма. Перенесённое письмо отобразится в новом в виде вложенного файла.
Нажмите на стрелку вниз на вложении и выберите «Скачать». Сохраните файл, указав расширение «.eml».
Из десктопного приложения Outlook под Mac OS письмо можно перетащить в нужную локальную папку, и оно будет в формате .eml. Под Windows этот способ не работает: письмо сохраняется в формате .msg.