
Burada "kontrol"den kastım: e-posta sunucusunun Inbox klasöründe kaç e-posta var ve bunlardan kaç tanesi okunmamış. (Kısacası okunmamış e-postamız var mı onu kontrol ediyoruz

Baştan belirteyim Delphi XE kullandım ve diğer versiyonlarda kontrol etmedim. Fakat sıkıntı olacağını zannetmiyorum.
Bilindiği üzere, e-posta servisleri farklı uygulamalardan e-postalarımızı kontrol edebilmemiz için IMAP protokolünü destekler. Biz de e-postalarımızı kontrol etmek için bunu kullanacağız. Elbette bu tarz kontrol işlemleri genelde arka planda çalıştırılmak istenecektir. Dolayısıyla Thread kullanmak kaçınılmaz.
Delphi ile birlikte gelen Indy bileşen kütüphanesi de kullanılabilir ama ben her zamanki gibi Synapse'yi kullanacağım. (Network işlemlerimde, Indy'e göre çok daha az sistem kaynağı tükettiği için ve kontrolün mümkün olduğunca bende olmasını istediğim için Indy kullanmaktan mümkün olduğunca kaçınır ve Synapse kullanırım)
Öncelikle desteklediğimiz IMAP sunucuları tanımlayalım
Kod: Tümünü seç
type
TImapServer = (Gmail, Yahoo, Hotmail, Yandex);
Kod: Tümünü seç
TServerLink: array[TImapServer] of string = ( // Her serverın host adresi
'imap.gmail.com',
'imap.mail.yahoo.com',
'imap-mail.outlook.com',
'imap.yandex.com'
);
Kod: Tümünü seç
TAccount = record
Password: string;
UserName: string;
Server: TImapServer;
end;
Gelelim Thread'imize:
Thread'de kontrol işlemi tamamlandığında geri bildirim alabilmemiz için bir tip tanımlayalım. Eğer birden fazla sunucuyu kontrol etmek istersek Thread'ten dönen sonucun hangi e-posta adresimiz için olduğunu anlayabilmek adına bu dönüş tipine TAccount sınıfını da ekledim. Tabiki asıl amacımız olan mail sayısı ve okunmamış mail sayısı da bu tip içinde mevcut:
Kod: Tümünü seç
type
TOnCompleted = procedure(MailAccount: TAccount; MailCount, UnreadMailCount: integer) of object;
Kod: Tümünü seç
TOnError = procedure(MailAccount: TAccount) of object;
Yukarıda bahsettiğim Synapse kütüphanesi IMAP desteği için bize bir sınıf zaten hazırlamış durumda: TIMAPSend. Bu sınıf imapsend.pas uniti içindedir. Ayrıca SSL desteği de mevcuttur.
Aslında belki de açıklamaya bile gerek olmayan Thread unitimiz şu şekilde:
Kod: Tümünü seç
uses
Classes, SysUtils, imapsend, ssl_openssl, uAccount;
type
TOnCompleted = procedure(MailAccount: TAccount; MailCount, UnreadMailCount: integer) of object;
TOnError = procedure(MailAccount: TAccount) of object;
TImapThread = class(TThread)
private
IMAP: TIMAPSend;
FAccount: TAccount;
FMailCount, FUnreadCount: integer;
FOnCompleted: TOnCompleted;
FOnError: TOnError;
protected
procedure Execute; override;
public
constructor Create(AccountInfo: TAccount);
destructor Destroy; override;
property OnCompleted: TOnCompleted read FOnCompleted write FOnCompleted;
property OnError: TOnError read FOnError write FOnError;
end;
implementation
{ TImapThread }
constructor TImapThread.Create(AccountInfo: TAccount);
begin
FAccount := AccountInfo;
FMailCount := 0;
FUnreadCount := 0;
FreeOnTerminate := True;
inherited Create(True);
end;
destructor TImapThread.Destroy;
begin
inherited Destroy;
end;
procedure TImapThread.Execute;
begin
IMAP := TIMAPSend.Create;
try
Imap.TargetHost := TServerLink[FAccount.Server];
Imap.TargetPort := 993;
Imap.UserName := FAccount.UserName;
Imap.Password := FAccount.Password;
Imap.FullSSL := True;
if Imap.Login then
begin
if Imap.SelectFolder('Inbox') then
begin
FMailCount := Imap.SelectedCount; //Tüm maillerin sayısı
FUnreadCount :=Imap.StatusFolder('Inbox', 'UNSEEN'); //Okunmamış mail sayısı
if Assigned(FOnCompleted) then
FOnCompleted(FAccount, FMailCount, FUnreadCount);
end;
Imap.Logout;
end
else if Assigned(FOnError) then
FOnError(FAccount);
finally
IMAP.Free;
end;
end;
end.
Dikkat edilmesi gerekenler: TIMAPSend için imapsend ve SSL desteği için ssl_openssl uniti ekledik. Ayrıca kullandığımız tüm sunucuların IMAP portları ortak ve 993 olduğu için bunu kodda direk kullandık. (Farklı portları desteklemek isteyenler TAccount tipine port ekleyip kullanabilirler).
Kodlardan görüleceği üzere e-posta kontrolü sağlanırsa OnCompleted olayı tetiklenecek. Login işlemi başarısız olduğu takdirde ise OnError olayı tetiklenecek.
Kullanıma örnek:
Kod: Tümünü seç
procedure TForm1.Button1Click(Sender: TObject);
var
MailAccount: TAccount;
begin
MailAccount.Server := Gmail;
MailAccount.UserName := 'velibozatli';
MailAccount.Password := 'benimsifrem :)';
with TImapThread.Create(MailAccount) do
begin
OnCompleted := ThreadCompleted;
OnError := ThreadError;
Start; //Sanırım eski versiyonlarda Resume
end;
end;
procedure TForm1.ThreadCompleted(Account: TAccount; MailCount,
UnreadMailCount: integer);
begin
Memo1.Lines.Add(Format('%s: %d/%d', [Account.UserName, UnreadMailCount, MailCount]));
end;
