Evaluate Email with Indy 10 and DELPHI

前端 未结 1 1899
借酒劲吻你
借酒劲吻你 2020-12-19 17:13

I use the following code to eval the msg. content (body / lines) of an E Mail msg received with the INDY 10 components

function LinesFromMsg(aMsg: TIdMessage         


        
1条回答
  •  执念已碎
    2020-12-19 17:43

    The correct ContentType value to look for is text/html. Use Indy's IsHeaderMediaType() function to check it, as the ContentType value may have additional attributes associated with it that your comparison needs to ignore.

    You also need to take the TIdMessage.ContentType into account as well, as HTML emails may not be MIME encoded and thus not use the TIdMessage.MessageParts` collection at all.

    And lastly, you loop needs to use the MessageParts.Count property instead of the MessageParts.AttachmentsCount property.

    Try this:

    function HTMLFromMsg(aMsg: TIdMessage): TStrings; 
    var
      i: Integer; 
      Part: TIdMessagePart;
    begin
      Result := nil;
      if IsHeaderMediaType(aMsg.ContentType, 'text/html') then
      begin
        Result := aMsg.Body;
        Exit;
      end;
      for i := 0 to aMsg.MessageParts.Count-1 do
      begin
        Part := aMsg.MessageParts.Items[i];
        if (Part is TIdText) and IsHeaderMediaType(Part.ContentType, 'text/html') then
        begin
          Result := TIdText(Part).Body;
          Exit;
        end;
      end; 
    end;
    

    With that said, this is technically not the correct way to handle MIME. Officially, a conforming reader is supposed to loop backwards through the MIME parts, as they are ordered from the simpliest form downwards towards the most complex form. So you loop backwards, taking MIME nesting into account, looking for the most complex form you support. Something more like this (untested):

    procedure DisplayPlainText(Body: TStrings);
    begin
      // display plain text as needed...
    end;
    
    procedure DisplayHTML(Body: TStrings);
    begin
      // display html as needed...
    end;
    
    procedure DisplayMultiPartAlternative(aMsg: TIdMessage; aParentIndex, aLastIndex: Integer);
    var
      Part: TIdMessagePart;
      i: Integer:
    begin
      for i := aLastIndex-1 downto aParentIndex+1 do
      begin
        Part := aMsg.MessageParts.Items[i];
        if (Part.ParentPart = aParentIndex) and (Part is TIdText) then
        begin
          if IsHeaderMediaType(Part.ContentType, 'text/html') then
          begin
            DisplayHTML(TIdText(Part).Body);
            Exit;
          end;
          if IsHeaderMediaType(Part.ContentType, 'text/plain') then
          begin
            DisplayPlainText(TIdText(Part).Body);
            Exit;
          end;
        end;
      end;
      // nothing supported to display...
    end;
    
    procedure DisplayMultiPartMixed(aMsg: TIdMessage; aParentIndex, aLastIndex: Integer);
    var
      Part: TIdMessagePart;
      i: Integer;
    begin
      for i := aLastIndex-1 downto aParentIndex+1 do
      begin
        Part := aMsg.MessageParts.Items[i];
        if (Part.ParentPart = aParentIndex) and (Part is TIdText) then
        begin
          if IsHeaderMediaType(Part.ContentType, 'multipart/alternative') then
          begin
            DisplayMultiPartAlternative(aMsg, ParentPart.Index, aLastIndex);
            Exit;
          end;
          if IsHeaderMediaType(ParentPart.ContentType, 'text/html') then
          begin
            DisplayHTML(TIdText(Part).Body);
            Exit;
          end;
          if IsHeaderMediaType(Part.ContentType, 'text/plain') then
          begin
            DisplayPlainText(TIdText(Part).Body);
            Exit;
          end;
          aLastIndex := i;
        end;
      end;
      // nothing supported to display...
    end;
    
    procedure DisplayMsg(aMsg: TIdMessage); 
    var
      ContentType: string;
    begin
      ContentType := ExtractHeaderMediaType(aMsg.ContentType);
      case PosInStrArray(ContentType, ['multipart/mixed', 'multipart/alternative', 'text/html', 'text/plain'], False) of
        0: begin
          DisplayMultiPartAlternative(aMsg, -1, aMsg.MessageParts.Count);
          Exit;
        end;
        1: begin
          DisplayMultiPartMixed(aMsg, -1, aMsg.MessageParts.Count);
          Exit;
        end;
        2: begin
          DisplayHTML(aMsg.Body);
          Exit;
        end;
        3: begin
          DisplayPlainText(aMsg.Body);
          Exit;
        end;
      else
        // nothing supported to display...
      end;
    end;
    

    0 讨论(0)
提交回复
热议问题