Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
ivan  
#1 Posted : Monday, May 2, 2011 12:18:45 AM(UTC)
ivan

Rank: Administration

Groups: Administrators
Joined: 11/11/2010(UTC)
Posts: 1,153

Thanks: 9 times
Was thanked: 55 time(s) in 55 post(s)
Delphi Example
If you want to leave a copy of email on the server, you should not call Delete method. However, there is a problem, how can you know if the email has already been downloaded (read)? If there is a way to identify the downloaded email, you can avoid downloading the duplicated email from your POP3/IMAP4 server.

Every email has a unique identifier (UIDL) on POP3 server. POP3 UIDL is only unique in the email life time. That means if the email was deleted from the server, other email can use the old unique identifier. Another problem is: UIDL in POP3 server can be any number or characters, so we cannot use UIDL as the file name, because UIDL may contain invalid characters for file name.

To solve this problem, we have to store the UIDL to a txt file and synchronize it with server every time.

The following example codes demonstrate how to mark the email as downloaded/read on POP3 server.
Code:

// The following example codes demonstrate marking email as read/downloaded on POP3 server
// To get full sample projects, please download and install EAGetMail on your machine.
// To run it correctly, please change email server, user, password, folder, file name value to yours

Unit Unit1; 

Interface 

Uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, StrUtils, EAGetMailObjLib_TLB; 

Type 
  TForm1 = Class(TForm) 
    Button1: TButton; 
    Procedure Button1Click(Sender: TObject); 

    // UIDL functions
    Procedure LoadUIDL(); 
    Procedure UpdateUIDL(); 
    Procedure SyncUIDL( oServer: TMailServer; infos: OleVariant); 
    Function FindExistedUIDL( oServer: TMailServer; UIDL: WideString ): Boolean; 
    Procedure AddUIDL( oServer: TMailServer; UIDL: WideString ); 

  private 
    { Private declarations } 
  public 
    { Public declarations } 
  End; 

Const 
  MailServerPop3 = 0; 
  MailServerImap4 = 1; 

Var 
  Form1: TForm1; 
  m_curpath: WideString; 
  m_uidlfile: WideString; 
  m_uidls: WideString; 

Implementation 

{$R *.dfm} 

Procedure TForm1.LoadUIDL(); 
Var 
  oTools: TTools; 
Begin 
  oTools := TTools.Create(Application); 
  m_uidls := ''; 
  m_uidls := oTools.ReadTextFile(m_uidlfile, 0); 
End; 

Procedure TForm1.UpdateUIDL(); 
Var 
  oTools: TTools; 
Begin 
  Try 
    oTools := TTools.Create(Application); 
    oTools.WriteTextFile( m_uidlfile, m_uidls, 0 ); 
  Except 
    On ep:Exception Do 
    ShowMessage( 'Update UIDL Error: ' + ep.Message ); 
  End; 
End; 

Procedure TForm1.SyncUIDL( oServer: TMailServer; infos: OleVariant); 
Var 
  index, i, UBound: Integer; 
  curpref, uidlpref, t, localuidl: WideString; 
  uidls, newuidls: WideString; 
  bRemove, bExistOnServer: boolean; 
  oInfo: IMailInfo; 
Begin 
  uidlpref := LowerCase(oServer.Server) + '#' + 
      LowerCase(oServer.User) + ' '; 

  uidls := m_uidls; 
  UBound := VarArrayHighBound(infos, 1 ); 

  While true Do 
  Begin 
    index := Pos( #13#10, uidls ); 
    If( index <= 0 ) Then 
      break; 

    t := LeftStr(uidls, index-1); 
    uidls := MidStr( uidls, index + 2, Length(uidls)-index-2); 
    bRemove := false; 
    If Length(t) > Length(uidlpref) Then 
    Begin 
      curpref := LeftStr(t, Length(uidlpref)); 
      // this UIDL belongs to current server/user
      If CompareStr(curpref, uidlpref) = 0 Then 
      Begin 
        localuidl := MidStr( t, Length(curpref)+1, Length(t)-Length(curpref)); 
        bExistOnServer := false; 
        For i := 0 To UBound Do 
        Begin 
          oInfo := IDispatch(VarArrayGet(infos, i)) As IMailInfo; 
          If CompareStr(oInfo.UIDL, localuidl ) = 0 Then 
            Begin 
              bExistOnServer := true; 
              break; 
            End; 
        End; 

        If Not bExistOnServer Then 
          bRemove := true; 

        If trim(t) = '' Then 
          bRemove := true; 
      End; 
    End; 

    If Not bRemove Then 
      newuidls := newuidls + t + #13#10; 
  End; 

  m_uidls := newuidls; 
End; 

Function TForm1.FindExistedUIDL( oServer: TMailServer; UIDL: WideString ): Boolean; 
Var 
  s: WideString; 
  index: Integer; 
Begin 
  s := LowerCase(oServer.Server) + '#' + 
      LowerCase(oServer.User) + ' ' + UIDL + #13#10; 

  index := Pos( s, m_uidls ); 
  If index > 0 Then 
    FindExistedUIDL := true 
  Else 
    FindExistedUIDL := false; 
End; 

Procedure TForm1.AddUIDL( oServer: TMailServer; UIDL: WideString ); 
Begin 
  m_uidls := m_uidls + LowerCase(oServer.Server) + '#' + 
      LowerCase(oServer.User) + ' ' + UIDL + #13#10; 
End; 
Function TForm1.SearchFolder(folders: OleVariant; name: WideString) 
:IImap4Folder; 
Var 
  i, UBound: Integer; 
  folder: IImap4Folder; 
Begin 
  UBound := VarArrayHighBound(folders, 1 ); 
  For i:= 0 To UBound Do 
  Begin 
    folder := IDispatch(VarArrayGet(folders,i)) As IImap4Folder; 
    If CompareText( folder.Name, name ) = 0 Then 
    Begin 
      Result := folder; 
      exit; 
    End; 

    // Search folder in sub-folders
    folder := SearchFolder( folder.SubFolders, name ); 
    If Not (folder = nil ) Then 
    Begin 
        Result := folder; 
        exit; 
    End; 
  End; 
  // No folder found
  Result := nil; 
End; 

Procedure TForm1.Button1Click(Sender: TObject); 
Var 
  oMail: IMail; 
  oClient: TMailClient; 
  oServer: TMailServer; 
  oTools: TTools; 
  infos: OleVariant; 
  i, UBound, Count: Integer; 
  oInfo: IMailInfo; 
  mailFolder: WideString; 
  fileName: WideString; 
  leaveCopy: Boolean; 
Begin 
  Try 
    oTools := TTools.Create(Application); 

    // Create a folder named "inbox" under
    // current directory to store the email files
    mailFolder := GetCurrentDir() + '\inbox'; 
    m_curpath := GetCurrentDir(); 
    m_uidlfile := m_curpath + '\uidl.txt'; 
    oTools.CreateFolder(mailFolder); 

    oServer := TMailServer.Create(Application); 
    oServer.Server := 'pop3.emailarchitect.net'; 
    oServer.User := 'test@emailarchitect.net'; 
    oServer.Password := 'testpassword'; 
    oServer.Protocol := MailServerPop3; 

    // If your server requires SSL connection
    // Please add the following codes
    // oServer.SSLConnection := true;
    // oServer.Port := 995;

    // leave a copy of message on server
    leaveCopy := true; 
    oClient := TMailClient.Create(Application); 
    oClient.LicenseCode := 'TryIt'; 

    oClient.Connect1(oServer.DefaultInterface); 
    ShowMessage( 'Connected!' ); 

    // UIDL is the identifier of every email on POP3/IMAP4 server, to avoid retrieve
    // the same email from server more than once, we record the email uidl retrieved every time
    // if you delete the email from server every time and not to leave a copy of email on
    // the server, then please remove all the function about uidl.
    LoadUIDL(); 

    infos := oClient.GetMailInfos(); 
    UBound := VarArrayHighBound( infos, 1 ); 
    Count := UBound+1; 

    SyncUIDL( oServer, infos ); 

    ShowMessage(Format('Total %d email(s)', [Count])); 

    For i := 0 To UBound Do 
    Begin 
      oInfo := IDispatch(VarArrayGet(infos, i)) As IMailInfo ; 
      ShowMessage(Format('Index: %d; Size: %d; UIDL: ' + oInfo.UIDL, 
      [oInfo.Index, oInfo.Size])); 

      If FindExistedUIDL(oServer, oInfo.UIDL) Then 
          continue; // this email has been downloaded, Do Not receive it again 

      // Generate a random file name by current local datetime,
      // You can use your method to generate the filename if you do not like it
      fileName := mailFolder + '\' + oTools.GenFileName(i) + '.eml; 

      // Receive email from POP3 server
      oMail := oClient.GetMail( oInfo ); 

      ShowMessage( 'From: ' + oMail.From.Address + #13#10 + 
        'Subject: ' + oMail.Subject ); 

      // Save email to local disk
      oMail.SaveAs( fileName, true ); 

      If leaveCopy Then 
      Begin 
          //add the email uidl to uidl file to avoid we retrieve it next time.
          AddUIDL( oServer, oInfo.UIDL ); 
      End 
      Else 
      Begin 
        // Mark email as deleted from IMAP4 server
        oClient.Delete(oInfo); 
      End; 
    End; 

    // Quit and pure emails marked as deleted from POP3 server
    oClient.Quit; 

  Except 
    On ep:Exception Do 
      ShowMessage( 'Error: ' + ep.Message ); 
  End; 

  UpdateUIDL(); 

End; 

End. 

Click here to read original topic - full version ...

If you have any comments or questions about above example codes, please add your comments here.
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2024, Yet Another Forum.NET
This page was generated in 0.053 seconds.

EXPLORE TUTORIALS

© All Rights Reserved, AIFEI Software Limited & AdminSystem Software Limited.