简体   繁体   English

使用Indy 10和DELPHI评估电子邮件

[英]Evaluate Email with Indy 10 and DELPHI

I use the following code to eval the msg. 我使用以下代码来评估msg。 content (body / lines) of an E Mail msg received with the INDY 10 components 使用INDY 10组件收到的E Mail消息的内容(正文/行)

function LinesFromMsg(aMsg: TIdMessage): TStrings; 
var
  i: Integer; 
begin
  for i := 0 to aMsg.MessageParts.AttachmentCount-1 do
  begin
    if (amsg.MessageParts.Items[i].ContentType ='HTML') then
    begin
      if (amsg.MessageParts.Items[i] is Tidtext) then
        Result := TidText(amsg.MessageParts.Items[i]).body;
    end;
  end; 
end;

regarding this code I have 2 questions : 关于这段代码我有两个问题:

a) is this the correct way of finding the Tlines part in an arbitray mail message ? a)这是在仲裁邮件中找到Tlines部分的正确方法吗? ( consider the advice shown at INDY 10 EMAIL MSG PARTS ) (考虑INDY 10 EMAIL MSG PARTS上显示的建议)

b) where can I find a tutorial of all the different Contenttype string values? b)我在哪里可以找到所有不同Contenttype字符串值的教程?

The correct ContentType value to look for is text/html . 要查找的正确ContentType值是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. 使用Indy的IsHeaderMediaType()函数进行检查,因为ContentType值可能具有与您的比较需要忽略的关联的其他属性。

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. 您还需要考虑TIdMessage.ContentType ,因为HTML电子邮件可能不是MIME编码的,因此根本不使用TIdMessage.MessageParts`集合。

And lastly, you loop needs to use the MessageParts.Count property instead of the MessageParts.AttachmentsCount property. 最后,循环需要使用MessageParts.Count属性而不是MessageParts.AttachmentsCount属性。

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. 话虽如此,从技术上讲,这不是处理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. 正式地说,符合标准的读者应该通过MIME部分向后循环,因为它们从最简单的形式向下排序到最复杂的形式。 So you loop backwards, taking MIME nesting into account, looking for the most complex form you support. 因此,您需要向后循环,将MIME嵌套考虑在内,寻找您支持的最复杂的表单。 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM