Rank: Administration
Groups: Administrators
Joined: 11/11/2010(UTC) Posts: 1,154
Thanks: 9 times Was thanked: 55 time(s) in 55 post(s)
|
Delphi ExampleIf 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.
|