-1

I need help, please. I can connect to Gmail and I can receive emails.

What I can't do is to save attachments. I think that it is a setting problem? I have IdAttachment and IdAttachmentFile in my uses clause. I tried all sorts of ContentType settings, but nothing seams to work.

if (IdMessage1.MessageParts.Items[i] is TIdAttachment) then
begin
  with (IdMessage1.MessageParts.Items[i] as TIdAttachment) do
  begin
    SaveToFile('C:\test123.txt');
  end;
end;

Here is my code:

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j: Integer;
  IdSSLIOHandlerSocket: TIdSSLIOHandlerSocketOpenSSL;
  bodytext: string;
  s: string;
  n: string;
  mailcount : integer;
  TMP: string;

begin
  IdSSLIOHandlerSocket := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
  idpop31.IOHandler := IdSSLIOHandlerSocket;
  idpop31.UseTLS := utUseImplicitTLS;
  IdPOP31.Host := 'pop.gmail.com';
  IdPOP31.Port := 995;
  IdPOP31.UseTLS := utUseImplicitTLS;
  IdPOP31.Username := 'name@gmail.com';
  IdPOP31.Password := 'xxxxx';
  IdPOP31.Connect;

  Mailcount:= idpop31.checkmessages;
  For i:= 1 to mailcount do
  Begin
    Idmessage1.clear;
    Idpop31.retrieveheader (i,idmessage1);
    TMP:= idmessage1.subject;
    Mailzeug.lines. Add (TMP);
    Idpop31.retrieve (i,idmessage1);
    TMP:= idmessage1.body.Text;
    Mailzeug.lines. Add (TMP);

    if (IdMessage1.MessageParts.Items[i] is TIdAttachment) then
    begin
      TIdAttachment(IdMessage1.MessageParts.Items[i]).SaveToFile(TIdAttachment(IdMessage1.MessageParts.Items[I]).Filename);
    end;
  end;
  Idpop31.disconnect;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
arnereu
  • 11
  • 2
  • Looks fine to me. What is the actual problem you are having with it? Please be more specific. What does the raw email from GMail look like? You can get that by either using `TIdPOP3.RetrieveRaw()`, or by attaching a `TIdLog...` component to `TIdPOP3.Intercept`. What does the contents of `IdMessage1` look like after it has parsed the raw email from Gmail? Can you provide a [mcve]? – Remy Lebeau Oct 31 '22 at 22:11
  • Hey Remy, thank you for your fast reply. It is an "ArgumentOutOfRangeException"? To be honest, I have no idea what to do with the IdPOP3.RetrieveRaw() or Intercept? Thank you much! – arnereu Nov 01 '22 at 10:42
  • "*It is an ArgumentOutOfRangeException?*" - is that supposed to be a question or a statement? In any case, can you please [edit] your post to provide a [mcve] showing the exception in action? And please indicate which line of code is raising the exception. – Remy Lebeau Nov 01 '22 at 14:52
  • Hey Remy, I edited my post. The exception is the error I am getting. Thank you! – arnereu Nov 02 '22 at 04:03
  • Perfect! Works beautifully! Thank you very very very much Remy for your help! I found this post of yours which is also very useful if someone else wants to connect to gmail and wonders why she/he can't receive emails a second time. https://stackoverflow.com/a/46981550/20128581 – arnereu Nov 02 '22 at 17:13

1 Answers1

0

You are using the wrong index value with the IdMessage1.MessageParts.Items[] property, that is why you are getting an "out of range" error. You are using the email's (1-based) index within the mailbox as-if it were a (0-based) attachment index within the email.

You need a 2nd loop to iterate the MessageParts collection of each email that is downloaded, eg:

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j: Integer;
  IdSSLIOHandlerSocket: TIdSSLIOHandlerSocketOpenSSL;
  BodyText: string;
  MailCount : integer;
  part: TIdMessagePart;
begin
  IdSSLIOHandlerSocket := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
  IdPOP31.IOHandler := IdSSLIOHandlerSocket;
  IdPOP31.Host := 'pop.gmail.com';
  IdPOP31.Port := 995;
  IdPOP31.UseTLS := utUseImplicitTLS;
  IdPOP31.Username := 'name@gmail.com';
  IdPOP31.Password := 'xxxxx';

  IdPOP31.Connect;
  try
    MailCount := IdPOP31.CheckMessages;
    for i := 1 to MailCount do
    begin
      IdMessage1.Clear;
      IdPOP31.Retrieve(i, IdMessage1);
      Mailzeug.Lines.Add(IdMessage1.Subject);
      BodyText := IdMessage1.Body.Text;
      Mailzeug.Lines.Add(BodyText);

      for j := 0 to IdMessage1.MessagePart.Count-1 do
      begin
        part := IdMessage1.MessageParts.Items[j];
        if (part is TIdAttachment) then
        begin
          TIdAttachment(part).SaveToFile(TIdAttachment(part).Filename);
        end;
      end;
    end;
  finally
    IdPOP31.Disconnect;
  end;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770