1

My program sends emails to contacts via GMail. Normally this works very well but we have noticed that sometimes an email which my program "thinks" it has sent doesn't actually arrive at Gmail, let alone arrive at the contacts. I thought that I might be able to add to the program a check which accesses the Gmail "sent items" folder to see whether each email has indeed been sent.

I have some code using the TIdPOP3 component but this downloads headers from the Inbox, not from sent items. My question is, how can I access the headers in the sent items folder?

Following is the code that I am using. It's only test code so there aren't any try/finally blocks, etc.

 with pop do
  begin
   host:= 'pop.gmail.com';
   username:= 'someone@gmail.com';
   password:= .....;
   Port:= 995;
   Connect;
   if connected then 
    with i:= checkmessages downto 1 do
     begin
      msg.clear;   // msg is of type TIdMessage
      if retrieve (i, msg)
       then listbox1.items.add (msg.subject)
     end;
   disconnect
  end;
No'am Newman
  • 6,395
  • 5
  • 38
  • 50

1 Answers1

3

To get the info related to the Sent Items you can use the Gmail imap_extensions and the TIdIMAP4 component.

Try this sample

{$APPTYPE CONSOLE}


uses
  Classes,
  SysUtils,
  IdIMAP4,
  IdSSLOpenSSL,
  IdMessageCollection,
  IdExplicitTLSClientServerBase;

procedure GetSentItems;
var
  LIdIMAP4: TIdIMAP4;
  LIdSSLIOHandlerSocketOpenSSL : TIdSSLIOHandlerSocketOpenSSL;
  AMailBoxList: TStrings;
  AMsgList: TIdMessageCollection;
  i: integer;
begin
  LIdIMAP4 := TIdIMAP4.Create(nil);
  try
    LIdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    try
      LIdSSLIOHandlerSocketOpenSSL.SSLOptions.Method := sslvSSLv3;
      LIdIMAP4.IOHandler := LIdSSLIOHandlerSocketOpenSSL;
      LIdIMAP4.Host := 'imap.gmail.com';
      LIdIMAP4.Port := 993;
      LIdIMAP4.UseTLS := utUseImplicitTLS;
      LIdIMAP4.Username := 'user';
      LIdIMAP4.Password := 'password';
      LIdIMAP4.Connect;
      try
        //list the mail boxes 
        AMailBoxList:=TStringList.Create;
        try
        if LIdIMAP4.ListSubscribedMailBoxes(AMailBoxList) then
         Writeln(AMailBoxList.Text);
        finally
          AMailBoxList.Free;
        end;

        AMsgList:=TIdMessageCollection.Create(TIdMessageItem);
        try
        if LIdIMAP4.SelectMailBox('[Gmail]/Enviados') then //This folder name is localizated in english use [Gmail]/Sent Mail
          if LIdIMAP4.MailBox.TotalMsgs>0 then
            if LIdIMAP4.UIDRetrieveAllEnvelopes(AMsgList) then
             for i := 0 to AMsgList.Count-1 do
             begin
               //do your work here
               Writeln(AMsgList[i].Subject); //list the subject of the sent items
             end;
        finally
          AMsgList.Free;
        end;
      finally
        LIdIMAP4.Disconnect;
      end;
    finally
      LIdSSLIOHandlerSocketOpenSSL.Free;
    end;
  finally
    LIdIMAP4.Free;
  end;
end;



begin
  try
   GetSentItems;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • Are you sure the mailbox names are localized (so [`this post`](http://stackoverflow.com/a/5186851/960757) for instance is not true) ? – TLama Jun 29 '13 at 06:21
  • I tested my Gmail account and only works with the spanish version of the sent items. – RRUZ Jun 29 '13 at 06:28
  • @RRUZ: Thanks very much. I had to localise the mailbox name to Hebrew, but that was the easy part. The headers are coming in the form '=?UTF-8?B?157xptek...' because they are utf-8 encoded; I haven't figured out yet how to convert them into Hebrew (Utf8ToAnsi doesn't seem to work). I have another question but I'll ask that separately. – No'am Newman Jun 29 '13 at 06:57
  • 1
    I don't think it's a good idea to hardcode the mailbox name. Google supports for this purpose so called [`Special-Use Extension of the LIST command`](https://developers.google.com/gmail/imap_extensions#special-use_extension_of_the_list_command). – TLama Jun 29 '13 at 07:17
  • TIdIMAP has built-in support for most of Gmail's IMAP extensions. As for decoding the headers, use Indy's `DecodeHeader()` function. – Remy Lebeau Jun 29 '13 at 20:25
  • @RemyLebeau, do you know any way to bypass the limitation of the localized IMAP folder names using indy? – RRUZ Jun 29 '13 at 20:28
  • @RRUZ: What limitation are you referring to? – Remy Lebeau Jul 01 '13 at 00:44
  • @RemyLebeau, I mean how use the Indy IMAP components to access the the imap gmail folders without localize the names. – RRUZ Jul 01 '13 at 01:03
  • @RRUZ: Currently, `TIdIMAP4.ListMailBoxes()` does not expose access to any mailbox attributes (that is a TODO item), so it can't report which mailboxes have Gmail-specific attributes on them. You will likely need to issue and parse the `LIST` command manually in order to access the attributes. Gmail extensions are implemented in `TIdIMAP4.SearchMailBox()`. – Remy Lebeau Jul 01 '13 at 18:35