Использование Делфи 11.
После загрузки электронного письма с помощью TIdIMAP4 и сканирования MessageParts, как мне определить, содержит ли MessagePart вложение в кодировке MIME, и как мне декодировать его в исходный формат (изображение, документы и т. д.)?
procedure TImapForm.ProcessEmail(MSG: TIdMessage);
begin
ContainsAttachement := false;
if Msg.MessageParts.Count > 0 then
begin
for i := 0 to Pred(Msg.MessageParts.Count) do
begin
if Msg.MessageParts.Items[i] is TIdText then
begin
// Process Text-only message here (Don't want HTML)
end else
begin
ContainsAttachement := true;
// if Msg.MessageParts[i].MessageParts.Encoding = meMIME then
if MSG.ContentTransferEncoding = 'base64' then //??
if Msg.MessageParts.Items[i].IsEncoded then //??
begin
// How to actually decode the MessagePart to a binary file?
end;
end;
end;
end;
end;
Пример электронной почты:
This is a multi-part message in MIME format.
--------------wt6iyRLyQwO4w89MYm2jGb0w
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
test
--------------wt6iyRLyQwO4w89MYm2jGb0w
Content-Type: image/jpeg; name = "Bart.jpg"
Content-Disposition: attachment; filename = "Bart.jpg"
Content-Transfer-Encoding: base64
/9j/4AAQSkZJRgABAQEASABIAAD/4ThFRXhpZgAASUkqAAgAAAAMAA4BAgAgAAAAngAAAA8B
AgAUAAAAvgAAABABAgAHAAAA1gAAABIBAwABAAAAAQAAABoBBQABAAAA7gAAABsBBQABAAAA
9gAAACgBAwABAAAAAgAAADEBAgAIAAAA/gAAADIBAgAUAAAAHgEAABMCAwABAAAAAgAAAGmH
etc.





TIdMessage уже сделает это за вас. Найдите TIdAttachment части сообщения, например:
procedure TImapForm.ProcessEmail(MSG: TIdMessage);
var
MsgPart: TIdMessagePart;
i: Integer;
begin
ContainsAttachement := false;
for i := 0 to Pred(Msg.MessageParts.Count) do
begin
MsgPart := Msg.MessageParts[i];
if MsgPart is TIdText then
//or: if MsgPart.PartType = mcptText then
begin
...
end
else if MsgPart is TIdAttachment then
//or: if MsgPart.PartType = mcptAttachment then
begin
ContainsAttachement := true;
TIdAttachment(MsgPart).SaveToFile(...);
end;
end;
end;
При этом электронные письма в кодировке MIME могут иметь сложную структуру (см., например, HTML-сообщения в блоге Indy). По этой причине части сообщения могут быть вложенными и иметь связи с другими частями сообщения. Таким образом, правильный способ обработки отдельных вложений (в отличие, например, от изображений/медиа, встроенных в HTML) в электронном письме MIME — это обратный цикл от последней части к первой части (поскольку части MIME упорядочены от наименее сложной к самой сложной). поиск вложений, свойство ParentPart которых равно -1 (т. е. часть верхнего уровня).
В общем, если вы нашли часть сообщения, свойство ContentType которой равно multipart/... (например, multipart/related), которая вас интересует, вы можете покопаться в ее вложенном содержимом, снова зациклившись на поиске частей сообщения, свойство ParentPart которых относится к той части сообщения, которая вас заинтересовала. И так далее, и так далее, настолько глубоко, насколько вам нужно.
Например:
procedure TImapForm.ProcessEmail(MSG: TIdMessage);
var
MsgPart: TIdMessagePart;
i: Integer;
begin
ContainsAttachement := false;
if Msg.MessageParts.Count = 0 then
begin
if IsHeaderMediaType(Msg.ContentType, 'text/plain') then
begin
// Process Msg.Body here ...
end;
end
else
begin
for i := Pred(Msg.MessageParts.Count) downto 0 do
begin
MsgPart := Msg.MessageParts[i];
if MsgPart.ParentPart = -1 then
begin
if MsgPart is TIdAttachment then
begin
ContainsAttachement := true;
TIdAttachment(MsgPart).SaveToFile(...);
end
else if MsgPart is TIdText then
begin
if IsHeaderMediaType(MsgPart.ContentType, 'multipart') then
begin
// process nested parts whose ParentPart is MsgPart.Index ...
end
else if IsHeaderMediaType(MsgPart.ContentType, 'text/plain') then
begin
// Process TIdText(MsgPart).Body here ...
end;
end;
end;
end;
end;
end;
@BartKindt TIdMessagePart имеет публичные Name (из заголовка Content-Type) и FileName (из заголовка Content-Disposition или Content-Type, в зависимости от того, какой из них присутствует). Тип файла указан в свойстве ContentType. Обратите внимание, что вложение не обязательно должно иметь имя файла, и наличие имени файла не означает, что эта часть является вложением.
Выглядит хорошо, и я попробую, но часть вложения MIME содержит имя файла, которое, в свою очередь, указывает, какой это тип файла. Если я вызову TIdAttachment(MsgPart).SaveToFile(...); где мне найти имя файла?