Reading and displaying email body using Indy TIdMessage

Posted on 2004-09-13
Last Modified: 2011-09-20
Hi Experts,

I'm building a simple email client application.
I retrieve message with:

IdPOP3.Retrieve(iMessageCount, NewMessage)

but I'm having problems displaying the message body. I'm using sample code from Indy but id displays much more information that is stored in the message body, for example:
Content-Type: text/plain; charset"iso-8859-1"
Content-Transfer-Encoding: quoted-printable

this is a test message

followed by more stuff.
What I want is something like any other email client, select email and display content of email body in correct format.

I need it urgently so 500 points for a complete solution
Question by:graga
  • 5
  • 4
  • 3
  • +1

Expert Comment

ID: 12049790
Mail is sent as one great big text block.  It is up to the mail client to pick out the headers (the to, from, cc, bcc, subject, etc.) from the body and attachments.  TIDMessage does all this for you.  It sounds like you're using TIDPop3.RetreieveRaw() instead of .Retrieve.  If you use .Retrieve, it will put this into a TIDMessage for you (just drop one on the form) and you can reference the individual pieces.  Here is code from a Delphi Demo:

   //get message and put into MSG
   ShowStatus('Retrieving message "' + lvHeaders.Selected.SubItems.Strings[3] + '"');
   POP.Retrieve(lvHeaders.Selected.Index + 1, Msg);
   statusbar1.Panels[0].text := lvHeaders.Selected.SubItems.Strings[3];

   //Setup fields on screen from MSG
   From.Caption := Msg.From.Text;
   Recipients.Caption := Msg.Recipients.EmailAddresses;
   Cc.Caption := Msg.CCList.EMailAddresses;
   Subject.Caption := Msg.Subject;
   Date.Caption := FormatDateTime('dd mmm yyyy hh:mm:ss', Msg.Date);
   Receipt.Caption := Msg.ReceiptRecipient.Text;
   Organization.Caption := Msg.Organization;
   Priority.Caption := IntToStr(Ord(Msg.Priority) + 1);

   //Setup attachments list
   ShowStatus('Decoding attachments (' + IntToStr(Msg.MessageParts.Count) + ')');
   for intIndex := 0 to Pred(Msg.MessageParts.Count) do
         if (Msg.MessageParts.Items[intIndex] is TIdAttachment) then
            begin //general attachment
               pnlAttachments.visible := true;
               li := lvMessageParts.Items.Add;
               li.ImageIndex := 8;
               li.Caption := TIdAttachment(Msg.MessageParts.Items[intIndex]).Filename;
            begin //body text
               if Msg.MessageParts.Items[intIndex] is TIdText then

Expert Comment

ID: 12049797
Sorry, I now see that you're posting the .Retrieve code you used... the code should still apply, though.  The BODY property of the message isn't really where you want to get the body.  The messageparts contains a TIDText object which contains the body.

Author Comment

ID: 12050186
Thank you Validor,

This is the code I'm using. I store the message in a database first in a blobfield and then retrieve. I think that's where I may have the error. But, when I decoded the message straight away from POP3 the code works okay for plain text messages but messages stored in HTML don't work and I need to display it in the correct format. Any ideas?
LVL 10

Expert Comment

ID: 12072090
The definition of an email message is as follows:

. (a line with only a dot)

The header consists of name value pairs where the name part is separated from the value(s) with a colon (:)

Normally the body and header are separated by TIdMessageClient.ReceiveHeader

>>      if ((Length(AAltTerm) = 0) and (Result = '.')) or
>>         ({APR: why? (Length(AAltTerm) > 0) and }(Result = AAltTerm)) then begin

My Indy version has the code above. It has a small commented part after APR. Maybe it is not commented in your version? Or maybe it is as well and it will work if you uncomment it.

Anyway if you want to correct the way the header is separated from the body this is the place to alter.

Could you post the "raw" message here you test with here? I mean header and body together (like when it is posted using SMTP). Then I could help you alter the Indy code correctly.

Regards Jacco

Expert Comment

ID: 12075618
Which version of Indy are you using?  

Delphi 6 = version 8
Delphi 7 = version 9
Delphi 8 = version 10

If using Version 10, are you using the version that came with Delphi, or did you download the latest?  If not, download the latest.  Either way, version 10 is in beta and may have a bug.  

If you are using the Indy 10 .NET version for non-delphi environments such as C#, please point that out as well.

Author Comment

ID: 12081655
I'm using Indy 9.011 on D5
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

LVL 10

Expert Comment

ID: 12082089
Have you checked the TIdMessageClient.ReceiveHeader in your version? Can you show what it reads?

Author Comment

ID: 12108935
My TIdMessageClient.ReceiveHeader is exactly same as yours.
I have also noted that when using INDY demo of Email Client, the message also displays incorrectly.
LVL 10

Expert Comment

ID: 12109356
Can you paste the header here?

Author Comment

ID: 12109430
OK, what I have found so far:

If ContentType is text_plain, the message body text is in IdMessage.Body - simple.

When ContentType is for example multipart/mixed, then everything is stored in MessageParts.

As I understand, IdMessage does not decode MessageParts but dumps everything as text.

The decoding is probably done by IDMessageDecoder or IDMessageDecoderMIME but so far I have no idea how to use it.

Expert Comment

ID: 12114632
Please email me a message such as the one you are having trouble with.  I'll try it and see if I get the same result so that I can better see what the problem is.



Author Comment

ID: 12210406
I have installed a Clever Internet Suite set of components and they do exactly what I want.
Thank you for trying

Accepted Solution

ee_ai_construct earned 0 total points
ID: 12249143
Question answered by asker or dialog valuable.
Closed, 500 points refunded.
ee_ai_construct (replacement part #xm34)
Community Support Admin

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
A short article about a problem I had getting the GPS LocationListener working.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now