Evaluate email using INDY 10 and Delphi

I use the following code to evaluate msg. The content (body/line) of the E Mail message received using the INDY 10 component

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

About this code I There are two questions:

a) Is this the correct way to find the Tlines part in the arbitration email?
(Consider the recommendations shown in INDY 10 EMAIL MSG PARTS)

b) Where can I find tutorials for all the different Contenttype string values?

The correct ContentType value to find is text / html. Use Indy’s IsHeaderMediaType() function to check , Because the ContentType value may have other attributes associated with your comparison that need to be ignored.

You also need to consider TIdMessage.ContentType, because HTML emails may not be MIME-encoded, so don’t use them at all TIdMessage.MessageParts` collection.

Finally, the 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;< br /> 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 ;

That being said, technically speaking, this is not the correct way to handle MIME. Formally, conforming to the standard Prospective readers should cycle backwards through the MIME parts, as they sort down from the simplest form to the most complex. Therefore, you need to cycle backwards, taking MIME nesting into account, and look for the most complex that you support Form. 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
DisplayPlain(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
DisplayHTML(TIdText(Part).Body);
E xit;
end;
aLastIndex := i;
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;

I use the following code to evaluate msg. The content (body/line) of the E Mail message received using the INDY 10 component

function L inesFromMsg(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;

I have two questions about this code :

a) Is this the correct way to find the Tlines part in the arbitration email?
(Consider the recommendations shown in INDY 10 EMAIL MSG PARTS)

b) Where can I find tutorials for all the different Contenttype string values?

The correct ContentType value to find is text/html. Use Indy’s IsHeaderMediaType() function to check, because the ContentType value may have a comparison with yours and need to be ignored

You also need to consider TIdMessage.ContentType, because HTML emails may not be MIME-encoded, so the TIdMessage.MessageParts` collection is not used at all.

Finally, the 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;

That said, Technically, this is not the correct way to deal with MIME. Formally, standard-compliant readers should loop backward through the MIME parts as they sort down from the simplest form to the most complex form. Therefore, you need to After the loop, the MIM E nesting considerations, look for the most complex form you support. Something more like this (untested):

procedure DisplayPlainText(Body: TStrings);< br />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;< br /> i: Integer:
begin
for i := aLastIndex-1 downto aParentIndex+1 do
begin
Part := aMsg.MessageParts.Items[i];< br /> 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
DisplayPlain (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< br /> DisplayMultiPartAlternative(aMsg, ParentPart.Index, aLastIndex);
Exit;
end;
if IsHeaderMediaType(ParentPart.ContentType,'text/html') then
begin< br /> DisplayHTML(TIdText(Part).Body);
Exit;
end;
if IsHeaderMediaType(Part.ContentType,'text/plain') then
begin
DisplayHTML(TIdText(Part).Body);
Exit;
end;
aLastIndex := i;
e nd;
// 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;

Leave a Comment

Your email address will not be published.