email.message: Представление сообщения электронной почты

Исходный код: Lib/email/message.py


Добавлено в версии 3.6: [1]

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

Сообщение электронной почты состоит из заголовков и полезной нагрузки (который также называется содержание). Заголовки - имена полей стиля RFC 5322 или RFC 6532 и значения, где имя поля и значение отделены двоеточием. Двоеточие не является частью имени поля или поля значение. Полезной нагрузкой может быть простое текстовое сообщение, или двоичный объект, или структурированная последовательность подсообщения, каждое со своим набором заголовков и своей собственной полезной нагрузкой. Последний тип полезной нагрузки указывается сообщением, имеющим тип MIME, такой как multipart/* или message/rfc822.

Концептуальная модель, предоставляемая объектом EmailMessage, является моделью упорядоченного словаря заголовков в сочетании с payload, который представляет RFC 5322 тело сообщения, которое может быть списком объектов sub-EmailMessage. Помимо обычных словарных методов для доступа к именам заголовков и значения, существуют способы для доступа к специализированной информации из заголовков (например, типа содержимого MIME), для работы с полезной нагрузкой, для генерации сериализованной версии сообщения и для рекурсивного обхода дерева объектов.

Подобный словарю интерфейс EmailMessage внесен в указатель названиями заголовка, которые должны быть ASCII значения. значения словаря - строки с некоторыми дополнительными методами. Заголовки сохранены и сохраняющая случай форма возвращенныйin, но имена полей - подобранный случай нечувствительно. В отличие от реального словарь, существует заказ на ключи, и могут быть дублированные ключи. Предусмотрены дополнительные методы работы с заголовками, имеющими повторяющиеся ключи.

Полезная нагрузка - или строка или объект байтов, в случае простых объектов сообщения или списка объектов EmailMessage, для контейнерных документов MIME, таких как multipart/* и объекты сообщения message/rfc822.

class email.message.EmailMessage(policy=default)

Если policy определен, используют правила, которые он определяет, чтобы обновить и преобразовать в последовательную форму представление сообщения. Если policy не установлен, используйте политику default, которая следует, правила электронной почты RFCs за исключением окончаний линии (вместо RFC передал под мандат \r\n, это использует стандартные окончания линии \n Python). Дополнительные сведения см. в документации по policy.

as_string(unixfrom=False, maxheaderlen=None, policy=None)

Возвращает всего сообщения, сплющиваемого как строка. Когда дополнительный unixfrom верен, заголовок конверта включен в возвращенныйstring. unixfrom по умолчанию принимает значение False. Поскольку обратная совместимость с основным классом maxheaderlen Message принята, но дефолты к None, что означает, что по умолчанию длиной линии контролирует max_line_length политики. Аргумент policy может быть используемый для переопределения политики по умолчанию, полученной из сообщения сущность. Это может быть используемый для управления некоторым форматированием, создаваемым методом, так как указанное policy будет передано Generator.

Уплощение сообщения может вызвать изменения EmailMessage, если для завершения преобразования в строка необходимо заполнить значения по умолчанию (например, границы MIME могут быть сгенерированы или изменены).

Обратите внимание, что этот метод предоставляется для удобства и может быть не самым полезным способом сериализации сообщений в приложении, особенно при работе с несколькими сообщениями. Для получения более гибкого API для сериализации сообщений см. раздел email.generator.Generator. Следует также отметить, что этот метод ограничен созданием сообщений, сериализованных как «7 bit clean», когда utf8 является False, что является значением по умолчанию.

Изменено в версии 3.6: default behavior when maxheaderlen не определен был изменен от невыполнения обязательств до 0 к невыполнению обязательств к значение max_line_length от политики.

__str__()

Эквивалентно as_string(policy=self.policy.clone(utf8=True)). Позволяет str(msg) создавать строка, содержащий сериализованное сообщение в формате, доступном для чтения.

Изменено в версии 3.4: method was changed to use utf8=True, таким образом, получают представление сообщения RFC 6531-like вместо того, чтобы быть прямым алиас для as_string().

as_bytes(unixfrom=False, policy=None)

Возвращает всего сообщения, сведенного как объект в байтах. Когда дополнительный unixfrom верен, заголовок конверта включен в возвращенныйstring. unixfrom по умолчанию принимает значение False. Аргумент policy может быть используемый для переопределения политики по умолчанию, полученной из сообщения сущность. Это может быть используемый для управления некоторым форматированием, создаваемым методом, так как указанное policy будет передано BytesGenerator.

Уплощение сообщения может вызвать изменения EmailMessage, если для завершения преобразования в строка необходимо заполнить значения по умолчанию (например, границы MIME могут быть сгенерированы или изменены).

Обратите внимание, что этот метод предоставляется для удобства и может быть не самым полезным способом сериализации сообщений в приложении, особенно при работе с несколькими сообщениями. Для получения более гибкого API для сериализации сообщений см. раздел email.generator.BytesGenerator.

__bytes__()

Эквивалентно as_bytes(). Позволяет bytes(msg) создавать объект в байтах, содержащий сериализованное сообщение.

is_multipart()

Возвращает True если полезная нагрузка сообщения представляет собой список подчиненныхEmailMessage объектов, в противном случае возвращает False. Когда is_multipart() возвращает False, полезный груз должен быть объектом строка (который мог бы быть полезным грузом набора из двух предметов CTE кодированный). Обратите внимание, что is_multipart(), возвращая True не обязательно означает, что «msg.get_content_maintype() == „multipart“» будет возвращает True. Например, is_multipart будет возвращает True, когда EmailMessage имеет тип message/rfc822.

set_unixfrom(unixfrom)

Установите для заголовка конверта сообщения значение unixfrom, которое должно быть строка. (Краткое описание этого заголовка см. в разделе mboxMessage.

get_unixfrom()

Возвращает заголовок конверта сообщения. Значение по умолчанию равно None, если заголовок конверта не был установлен.

Следующие методы реализуют интерфейс, подобный отображению, для доступа к заголовкам сообщения. Следует отметить, что существуют некоторые семантические различия между этими методами и обычным интерфейсом отображения (т.е. словарем). Например, в словаре нет дубликатов ключей, но здесь могут быть дубликаты заголовки сообщений. Кроме того, в словарях нет никакого гарантируемого заказа к возвращенный keys() ключей, но в объекте EmailMessage, заголовки всегда - возвращенныйin заказ, они появились в исходном сообщении, или в котором они были добавлены к сообщению позже. Любой заголовок, удаленный и затем вновь добавляемый, всегда добавляется к концу списка заголовков.

Эти семантические различия являются преднамеренными и склонны к удобству в наиболее распространенных случаях использования.

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

__len__()

Возвращает общее количество заголовков, включая дубликаты.

__contains__(name)

Возвращает True, если объект сообщения имеет поле с именем name. Соответствие сделано без отношения к случаю, и name не включает тянущееся двоеточие. Используется для оператора in. Например:

if 'message-id' in myMessage:
   print('Message-ID:', myMessage['message-id'])
__getitem__(name)

Возвращает значение именованного поля заголовка. name не включает разделитель полей двоеточия. Если заголовок отсутствует, возвращается значение None; KeyError никогда не воспитывается.

Обратите внимание, что, если названное поле появляется несколько раз в заголовках сообщения, точно кто из тех выставляет значения, будет возвращенныйis неопределенный. Используйте метод get_all(), чтобы получить значения всех существующих заголовков с именем name.

Используя стандарт (non-compat32) политика, возвращенныйзначение - сущность подкласс email.headerregistry.BaseHeader.

__setitem__(name, val)

Добавьте заголовок к сообщению с именем поля name и значение val. Поле добавляется к концу существующих заголовков сообщения.

Обратите внимание, что это делает not, переписывают или удаляют любой существующий заголовок с тем же именем. Если необходимо убедиться, что новый заголовок является единственным заголовком в сообщении с именем поля name, сначала удалите поле, например,:

del msg['subject']
msg['subject'] = 'Python roolz!'

Если policy определяет определенные заголовки как уникальные (как это делают стандартные политики), этот метод может вызвать ValueError при попытке назначить значение такому заголовку, когда он уже существует. Это поведение является преднамеренным ради согласованности, но не зависит от него, так как мы можем сделать такое назначение сделать автоматическое удаление существующего заголовка в будущем.

__delitem__(name)

Удалите все вхождения поля с именем name из заголовков сообщения. Исключение не возникает, если именованное поле отсутствует в заголовках.

keys()

Возвращает a список всех имен полей заголовка сообщения.

values()

Возвращает a список всех полей сообщения значения.

items()

Возвращает a список 2-кортежей, содержащих все заголовки полей сообщения и значения.

get(name, failobj=None)

Возвращает значение именованного поля заголовка. Это идентично __getitem__() за исключением того, что дополнительный failobj - возвращенныйif, который названный заголовок пропускает (дефолты failobj к None).

Вот несколько дополнительных полезных методов, связанных с заголовками:

get_all(name, failobj=None)

Возвращает a список всех значения для поля с именем name. Если в сообщении нет таких именованных заголовков, возвращается значение failobj (значение по умолчанию - None).

add_header(_name, _value, **_params)

Расширенная настройка заголовка. Этот метод аналогичен __setitem__(), за исключением того, что дополнительные параметры заголовка могут быть предоставлены в качестве аргументов ключевой. _name - добавляемое поле заголовка, а _value - primary значение для заголовка.

Для каждого предмета в словаре аргумента ключевой _params ключ взят в качестве названия параметра, с подчеркивает преобразованный в черты (так как черты незаконны в идентификаторах Python). Обычно, параметр будет добавлен как key="value", если значение не будет None, в этом случае только ключ будет добавлен.

Если значение содержит знаки неASCII, кодировкой и языком можно явно управлять, определяя значение как три кортежа в формате (CHARSET, LANGUAGE, VALUE), где CHARSET - строка, называющий кодировку, чтобы быть используемый, чтобы закодировать значение, LANGUAGE может обычно устанавливаться в None или пустой строка (см. RFC 2231 для других возможностей), и VALUE - строка значение, содержащий неASCII точки код. Если три кортежа не переданы, и значение содержит знаки неASCII, это - автоматически кодированный в формате RFC 2231, используя CHARSET utf-8 и LANGUAGE None.

Вот пример:

msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')

Это добавит заголовок, который выглядит как:

Content-Disposition: attachment; filename="bud.gif"

Пример расширенного интерфейса с символами, отличными от ASCII:

msg.add_header('Content-Disposition', 'attachment',
               filename=('iso-8859-1', '', 'Fußballer.ppt'))
replace_header(_name, _value)

Замените заголовок. Замените первый заголовок в сообщении, совпадающем с _name, сохранив порядок заголовка и регистр имени поля исходного заголовка. Если соответствующий заголовок не найден, поднимите KeyError.

get_content_type()

Возвращает тип содержимого сообщения, принуждаемый к нижнему регистру формы maintype/subtype. Если есть заголовок не Content-Type в сообщении возвращает значение возвращенный get_default_type(). Если заголовок Content-Type недействителен, возвращает text/plain.

(Согласно RFC 2045, у сообщений всегда есть тип по умолчанию, get_content_type() всегда будет возвращает a значение. RFC 2045 определяет тип сообщения по умолчанию, который должен быть text/plain, если только он не отображается внутри контейнера multipart/digest, и в этом случае он будет message/rfc822. Если заголовок Content-Type имеет недопустимую спецификацию типа, RFC 2045 требует, чтобы типом по умолчанию был text/plain.

get_content_maintype()

Возвращает основной тип содержимого сообщения. Это maintype часть строка возвращенный get_content_type().

get_content_subtype()

Возвращает тип субсодержимого сообщения. Это subtype часть строка возвращенный get_content_type().

get_default_type()

Возвращает тип содержимого по умолчанию. Большинство сообщений имеют тип содержимого text/plain по умолчанию, за исключением сообщений, являющихся подкатегориями контейнеров multipart/digest. Такие подразделы имеют тип содержимого message/rfc822 по умолчанию.

set_default_type(ctype)

Задайте тип содержимого по умолчанию. ctype должны быть либо text/plain, либо message/rfc822, хотя это не принудительно. Тип содержимого по умолчанию не хранится в заголовке Content-Type, поэтому он влияет на возвращает значение методов get_content_type только в том случае, если в сообщении отсутствует заголовок Content-Type.

set_param(param, value, header='Content-Type', requote=True, charset=None, language='', replace=False)

Параметр установить в заголовке Content-Type. Если параметр уже существует в заголовке, замените его значение на value. Когда header - Content-Type (дефолт), и заголовок еще не существует в сообщении, добавляет его, устанавливает свой значение в text/plain и прилагает новый параметр значение. Необязательный header определяет альтернативный заголовок Content-Type.

Если значение содержит символы, отличные от ASCII, набор символов и язык могут быть явно указаны с помощью дополнительных параметров charset и language. Дополнительный language определяет язык RFC 2231, не выполняя своих обязательств к пустому строка. И charset, и language должны быть строки. По умолчанию используются utf8 charset и None для language.

Если replace - False (дефолт), заголовок перемещен до конца списка заголовков. Если replace является True, заголовок будет обновлен.

Использование параметра requote с EmailMessage объектами устарело.

Следует отметить, что доступ к существующим параметрам значения заголовков можно получить через params атрибут заголовка значение (например, msg['Content-Type'].params['charset']).

Изменено в версии 3.4: replace было добавлено ключевое слово.

del_param(param, header='content-type', requote=True)

Полностью удалите данный параметр из заголовка Content-Type. Заголовок будет перезаписан на месте без параметра или его значение. Необязательная header задает альтернативу Content-Type.

Использование параметра requote с EmailMessage объектами устарело.

get_filename(failobj=None)

Возвращает значение параметра filename заголовка Content-Disposition сообщения. Если заголовок не имеет параметра filename, этот метод возвращается к поиску параметра name в заголовке Content-Type. Если ни один из них не найден, или заголовок отсутствует, возвращается значение failobj. возвращенныйstring всегда будет отменен в соответствии с email.utils.unquote().

get_boundary(failobj=None)

Возвращает значение параметра boundary заголовка Content-Type сообщения или failobj, если или заголовок отсутствует или имеет параметр не boundary. возвращенныйstring всегда будет отменен в соответствии с email.utils.unquote().

set_boundary(boundary)

Установите для параметра boundary заголовка Content-Type значение boundary. set_boundary() всегда будет цитировать boundary, если это необходимо. HeaderParseError поднят, если у объекта сообщения есть заголовок нет Content-Type.

Следует отметить, что использование этого метода незначительно отличается от удаления старого заголовка Content-Type и добавления нового заголовка с новой границей через add_header(), поскольку set_boundary() сохраняет порядок заголовка Content-Type в списке заголовков.

get_content_charset(failobj=None)

Возвращает charset параметр заголовка Content-Type, принуждаемый к нижнему регистру. Если заголовок Content-Type отсутствует или заголовок не имеет параметра charset, возвращается значение failobj.

get_charsets(failobj=None)

Список возвращает, содержащий имена наборов символ в сообщении. Если сообщение является multipart, то список будет содержать один элемент для каждого подраздела полезной нагрузки, в противном случае это будет список длины 1.

Каждый элемент в списке будет представлять собой строка, который является значение параметра charset в заголовке Content-Type для представленного подраздела. Если подразделение будет иметь заголовок № Content-Type, параметр не charset, или не будет иметь главный тип MIME text, то тот предмет в возвращенный список будет failobj.

is_attachment()

Возвращает True, если есть заголовок Content-Disposition и его значение (без учета регистра), является attachment, False иначе.

Изменено в версии 3.4.2: is_attachment теперь является методом вместо свойства, для согласованности с is_multipart().

get_content_disposition()

Возвращает нижний регистр значение (без параметров) заголовка сообщения Content-Disposition, если он имеет его, или None. Возможные значения для этого метода являются inline, attachment или None, если сообщение следует за RFC 2183.

Добавлено в версии 3.5.

Следующие способы относятся к опросу и манипулированию содержимым (полезной нагрузкой) сообщения.

walk()

Метод walk() - универсальный генератор, который может быть используемый, чтобы повторить по всем частям и подразделениям дерева объекта сообщения в глубине первый пересекающийся заказ. Вы будете, как правило, использовать walk() в качестве iterator в петле for; каждая итерация возвращает следующий подраздел.

Вот пример, в котором печатается тип MIME каждой части многокомпонентный структуры сообщений:

>>> for part in msg.walk():
...     print(part.get_content_type())
multipart/report
text/plain
message/delivery-status
text/plain
text/plain
message/rfc822
text/plain

walk итератируется по подразделам любой части, где is_multipart() возвращается True, даже если msg.get_content_maintype() == 'multipart' может возвращает False. Мы видим, что это в нашем примере, используя _structure отлаживает хелпера функции:

>>> from email.iterators import _structure
>>> for part in msg.walk():
...     print(part.get_content_maintype() == 'multipart',
...           part.is_multipart())
True True
False False
False True
False False
False False
False True
False False
>>> _structure(msg)
multipart/report
    text/plain
    message/delivery-status
        text/plain
        text/plain
    message/rfc822
        text/plain

Здесь message части не являются multiparts, но они содержат подразделы. is_multipart() возвращает True и walk опускается в подразделы.

get_body(preferencelist=('related', 'html', 'plain'))

Возвращает MIME часть, которая является лучшим кандидатом для того, чтобы быть «телом» сообщения.

preferencelist должен быть последовательностью строки из набора related, html и plain и указывает порядок предпочтения типа содержимого возвращаемой детали.

Начните поиск совпадений кандидатов с объектом, для которого вызывается метод get_body.

Если related не включен в preferencelist, следует учитывать корневую часть (или подраздел корневой части) любой связанной детали в качестве кандидата, если (суб-) деталь соответствует предпочтению.

При обнаружении multipart/related проверьте параметр start и, если найдена деталь с совпадающим Content-ID, учитывайте только его при поиске совпадений кандидатов. В противном случае рассмотрим только первую (по умолчанию корневую) часть multipart/related.

Если позиция имеет заголовок Content-Disposition, следует учитывать, что позиция соответствует кандидату, только если значение заголовка имеет значение inline.

Если ни один из кандидатов не соответствует ни одному из предпочтений в preferencelist, возвращает None.

Примечания: (1) для большинства приложений единственными комбинациями preferencelist, которые действительно имеют смысл, являются ('plain',), ('html', 'plain') и ('related', 'html', 'plain') по умолчанию. (2) поскольку соответствие запускам с объектом, на котором get_body называют, называя get_body на multipart/related, будет сам объект возвращает the, если у preferencelist не будет значение не по умолчанию. (3) сообщения (или части сообщения), которые не определяют Content-Type или чей заголовок Content-Type недействителен, будут рассматривать, как будто они имеют тип text/plain, который может иногда вызывать get_body к результатам возвращает unexpected.

iter_attachments()

Возвращает итератор по всем непосредственным подразделов сообщения, которые не являются частями «body» кандидата. Таким образом, пропустите первое возникновение каждого из text/plain, text/html, multipart/related или multipart/alternative (если они явно не отмечены как приложения через Content-Disposition: attachment), и части оставлений возвращает все. При непосредственном применении к multipart/related, возвращает итератор над всеми связанными деталями, за исключением корневой детали (например: деталь, на которую указывает параметр start, или первая деталь, если отсутствует параметр start или параметр start не соответствует Content-ID какой-либо из деталей). Если применяется непосредственно к multipart/alternative или non-multipart, возвращает пустой итератор.

iter_parts()

Возвращает итератор по всем непосредственным подразделениям сообщения, которое будет пусто для non-multipart. (См. также walk().)

get_content(*args, content_manager=None, **kw)

Вызвать метод get_content() content_manager, передав себя как объект сообщения и передав любые другие аргументы или ключевые слова в качестве дополнительных аргументов. Если content_manager не определен, используйте content_manager, определенный текущим policy.

set_content(*args, content_manager=None, **kw)

Вызвать метод set_content() content_manager, передав себя как объект сообщения и передав любые другие аргументы или ключевые слова в качестве дополнительных аргументов. Если content_manager не определен, используйте content_manager, определенный текущим policy.

Преобразуйте non-multipart сообщение в сообщение multipart/related, переместив любые существующие заголовки Content- и полезный груз в (новую) первую часть multipart. Если задано значение boundary, используйте его в качестве границы строка в мультидетале, в противном случае оставьте границу автоматически создаваемой при необходимости (например, при сериализации сообщения).

make_alternative(boundary=None)

Преобразуйте non-multipart или multipart/related в multipart/alternative, перемещая все существующие заголовки Content- и полезную нагрузку в (новую) первую часть multipart. Если задано значение boundary, используйте его в качестве границы строка в мультидетале, в противном случае оставьте границу автоматически создаваемой при необходимости (например, при сериализации сообщения).

make_mixed(boundary=None)

Преобразуйте не-multipart, multipart/related или multipart-alternative в multipart/mixed, перемещая все существующие заголовки Content- и полезную нагрузку в (новую) первую часть multipart. Если задано значение boundary, используйте его в качестве границы строка в мультидетале, в противном случае оставьте границу автоматически создаваемой при необходимости (например, при сериализации сообщения).

Если сообщение является multipart/related, создайте новый объект сообщения, передайте все аргументы его методу set_content() и attach() его multipart. Если сообщение является non-multipart, вызовите make_related(), а затем выполните указанные выше действия. Если сообщение - какой-либо другой тип multipart, поднимите TypeError. Если content_manager не определен, используйте content_manager, определенный текущим policy. Если добавленная позиция не имеет заголовка Content-Disposition, добавьте ее с значение inline.

add_alternative(*args, content_manager=None, **kw)

Если сообщение является multipart/alternative, создайте новый объект сообщения, передайте все аргументы его методу set_content() и attach() его multipart. Если сообщение является non-multipart или multipart/related, вызовите make_alternative(), а затем выполните указанные выше действия. Если сообщение - какой-либо другой тип multipart, поднимите TypeError. Если content_manager не определен, используйте content_manager, определенный текущим policy.

add_attachment(*args, content_manager=None, **kw)

Если сообщение является multipart/mixed, создайте новый объект сообщения, передайте все аргументы его методу set_content() и attach() его multipart. Если сообщение является non-multipart, multipart/related или multipart/alternative, вызовите make_mixed(), а затем выполните указанные выше действия. Если content_manager не определен, используйте content_manager, определенный текущим policy. Если добавленная позиция не имеет заголовка Content-Disposition, добавьте ее с значение attachment. Этот метод может быть используемый и для явных приложений (Content-Disposition: attachment) и для приложений inline (Content-Disposition: inline), передав подходящие варианты к content_manager.

clear()

Удалите полезную нагрузку и все заголовки.

clear_content()

Удалите полезную нагрузку и все заголовки Content-, оставив все остальные заголовки нетронутыми и в исходном порядке.

Объекты EmailMessage имеют следующие сущность атрибуты:

preamble

Формат документа MIME позволяет использовать текст между пустой строкой, следующей за заголовками, и первой многочастной границей строка. Обычно, этот текст никогда не видим в MIME-осведомленном почтовом читателе, потому что он выходит за пределы стандартной брони MIME. Однако при просмотре необработанного текста сообщения или при просмотре сообщения в устройстве чтения с поддержкой non-MIME этот текст может стать видимым.

В preamble атрибут содержится этот ведущий внебронированный текст для MIME документов. Когда Parser открывает некоторый текст после заголовков, но перед первым граничным строка, он назначает этот текст на сообщение preamble атрибут. Когда Generator записывает представление обычного текста сообщения MIME и обнаруживает, что сообщение имеет preamble атрибут, он запишет этот текст в область между заголовками и первой границей. Дополнительные сведения см. в разделах email.parser и email.generator.

Следует отметить, что если у объекта сообщения нет преамбулы, то preamble атрибут будет None.

epilogue

epilogue атрибут действует так же, как preamble атрибут, за исключением того, что он содержит текст, который появляется между последней границей и концом сообщения. Как и в случае preamble, если нет эпилога текста, этот атрибут будет None.

defects

В defects атрибут содержится список всех проблем, обнаруженных при парсинг этого сообщения. См. email.errors для подробного описания возможных дефектов парсинг.

class email.message.MIMEPart(policy=default)

Этот класс представляет собой подраздел сообщения MIME. Он идентичен EmailMessage, за исключением того, что при вызове set_content() не добавляются заголовки MIME-Version, так как подчастям не нужны собственные заголовки MIME-Version.

Сноски

[1]Первоначально добавлен в 3.4 как предварительный пакет. Документы для старого класса сообщений перемещены в email.message.Message: Представление сообщения электронной почты с помощью API compat32.