Delphi Indy10 IMAP解码MIME附件

htrmnn0y  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(127)

使用 Delphi 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.
9avjhtql

9avjhtql1#

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编码的电子邮件可能具有 * 复杂 * 的结构(例如,请参阅Indy博客上的HTML Messages)。因此,消息部件可以嵌套,并与其他消息部件建立关系。因此,在MIME电子邮件中处理独立附件(例如,与HTML嵌入的图像/媒体相反)的 * 正确 * 方法是从最后一部分到第一部分 * 向后 * 循环(因为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;

相关问题