I am using this code to read emails from the server and it work except that Sender.Address
and Body.Text
are empty why is that ?. Here is the code:
var
MsgCount : Integer;
i : Integer;
FMailMessage : TIdMessage;
begin
Memo1.Lines.Clear;
//The IdPop31 is on the form so it is constructing when the
//form is created and so is Memo1.
IdPOP31.Host := 'server.com'; //Setting the HostName;
IdPOP31.Username := '[email protected]';//Setting UserName;
IdPOP31.Password := 'xxxxxx';//Setting Password;
IdPOP31.Port := 110;//Setting Port;
try
IdPOP31.Connect();
//Getting the number of the messages that server has.
MsgCount := IdPOP31.CheckMessages;
for i:= 1 to Pred(MsgCount) do
begin
try
FMailMessage := TIdMessage.Create(nil);
IdPOP31.Retrieve(i,FMailMessage);
Memo1.Lines.Add('=================================================');
Memo1.Lines.Add(FMailMessage.From.Address);
Memo1.Lines.Add(FMailMessage.Recipients.EMailAddresses);
Memo1.Lines.Add(FMailMessage.Subject);
Memo1.Lines.Add(FMailMessage.Sender.Address);
Memo1.Lines.Add(FMailMessage.Body.Text);
Memo1.Lines.Add('=================================================');
finally
FMailMessage.Free;
end;
end;
finally
IdPOP31.Disconnect;
end;
end;
The TIdMessage.Sender
is populated only if the email has a top-level Sender
header, which is rare. Typically the sender is in the From
header instead.
The body content will be stored in either the TIdMessage.Body
or TIdMessage.MessageParts
, depending on how the email is encoded. Typically, multi-piece emails, such as those encoded with MIME, especially if they contain attachments, will use TIdMessage.MessageParts
, whereas simple emails, like plaintext-only emails, will use TIdMessage.Body
. So, you need to check both as needed.
For example:
var
MsgCount, I: Integer;
FMailMessage: TIdMessage;
Body: TStrings;
function FindTextBody(AParent: Integer): TStrings;
var
J: integer;
Part: TIdMessagePart;
begin
Result := nil;
// MIME parts are ordered from least complex to most complex, and can be nested,
// so loop backwards through the parts, recursing through nested levels as needed...
for J := Pred(FMailMessage.MessageParts.Count) downto (AParent+1) do
begin
Part := FMailMessage.MessageParts[J];
if Part.ParentPart = AParent then
begin
if IsHeaderMediaType(Part.ContentType, 'multipart') then
begin
Result := FindTextBody(Part.Index);
if Result <> nil then Exit;
end
else if IsHeaderMediaType(Part.ContentType, 'text') then
begin
Result := (Part as TIdText).Body;
Exit;
end;
end;
end;
end;
begin
Memo1.Lines.Clear;
//The IdPop31 is on the form so it is constructing when the
//form is created and so is Memo1.
IdPOP31.Host := 'server.com'; //Setting the HostName;
IdPOP31.Username := '[email protected]';//Setting UserName;
IdPOP31.Password := 'xxxxxx';//Setting Password;
IdPOP31.Port := 110;//Setting Port;
try
IdPOP31.Connect();
//Getting the number of the messages that server has.
MsgCount := IdPOP31.CheckMessages;
for I := 1 to Pred(MsgCount) do
begin
FMailMessage := TIdMessage.Create(nil);
try
IdPOP31.Retrieve(I, FMailMessage);
Memo1.Lines.Add('=================================================');
Memo1.Lines.Add(FMailMessage.From.Address);
Memo1.Lines.Add(FMailMessage.Recipients.EMailAddresses);
Memo1.Lines.Add(FMailMessage.Subject);
Memo1.Lines.Add(FMailMessage.Sender.Address);
if FMailMessage.MessageParts.Count > 0 then
Body := FindTextBody(-1)
else
Body := FMailMessage.Body;
if Body <> nil then
Memo1.Lines.Add(Body.Text);
Memo1.Lines.Add('=================================================');
finally
FMailMessage.Free;
end;
end;
finally
IdPOP31.Disconnect;
end;
end;