From 049e8faf0d96e085647317f0390182f43d7762e2 Mon Sep 17 00:00:00 2001 From: Mozart Date: Tue, 17 Nov 2020 03:13:51 -0300 Subject: [PATCH 1/4] =?UTF-8?q?=EF=BF=BD=20Adiciona=20interface=20Mail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adiciona a interface Mail para envio de emails. --- Source/Mail/Mail.pas | 42 ++++++++++++++++++++++++++++++++++++++++++ pkgAtlas.dpk | 5 +++-- pkgAtlas.dproj | 5 +++-- 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 Source/Mail/Mail.pas diff --git a/Source/Mail/Mail.pas b/Source/Mail/Mail.pas new file mode 100644 index 0000000..63d1d0b --- /dev/null +++ b/Source/Mail/Mail.pas @@ -0,0 +1,42 @@ +unit Mail; + +interface + +uses + System.Classes, + System.SysUtils; + +type + EMailException = class(Exception); + + IMail = interface + ['{07C2551B-B2A6-47C6-9454-A2AE5BE884DB}'] + + function Host(const AValue: string): IMail; + function Port(const AValue: Integer): IMail; + function Username(const AValue: string): IMail; + function Password(const AValue: string): IMail; + function UsingSSL(const AValue: Boolean = True): IMail; + function UsingTLS(const AValue: Boolean = True): IMail; + function AuthenticationRequired(const AValue: Boolean = True): IMail; + + function From(const AName: string; const AAddress: string): IMail; + function ReplyTo(const AName: string; const AAddress: string): IMail; + function ToRecipient(const AAddress: string): IMail; + function CcRecipient(const AAddress: string): IMail; + function BccRecipient(const AAddress: string): IMail; + function AskForConfirmation(const AValue: Boolean = True): IMail; + + function Attachment(const AFileName: string): IMail; + + function Subject(const AValue: string): IMail; + function &Message(const AValue: string): IMail; overload; + function &Message(const AValue: TStringList): IMail; overload; + function UsingHTML(const AValue: Boolean = True): IMail; + + procedure Send; + end; + +implementation + +end. diff --git a/pkgAtlas.dpk b/pkgAtlas.dpk index d9876db..6cda317 100644 --- a/pkgAtlas.dpk +++ b/pkgAtlas.dpk @@ -25,7 +25,7 @@ package pkgAtlas; {$IMAGEBASE $400000} {$DEFINE DEBUG} {$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Atlas Framework'} +{$DESCRIPTION 'SDK Runtine Libraries'} {$RUNONLY} {$IMPLICITBUILD ON} @@ -39,6 +39,7 @@ contains ValorPor in 'Source\ValorPor.pas', SQLBuilder in 'Source\SQLBuilder\SQLBuilder.pas', Conexao in 'Source\Objetos\Conexao.pas', - Types.Conexao in 'Source\Objetos\Types.Conexao.pas'; + Types.Conexao in 'Source\Objetos\Types.Conexao.pas', + Mail in 'Source\Mail\Mail.pas'; end. diff --git a/pkgAtlas.dproj b/pkgAtlas.dproj index ca605de..5fc1b43 100644 --- a/pkgAtlas.dproj +++ b/pkgAtlas.dproj @@ -54,7 +54,7 @@ All pkgAtlas true - $(DCC_UnitSearchPath);modules\.dcp;modules\.dcu;modules;modules\.bpl;modules\doscommand\Source + modules\.dcp;modules\.dcu;modules;modules\.bpl;modules\doscommand\Source;$(DCC_UnitSearchPath) Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) @@ -106,6 +106,7 @@ + Cfg_2 Base @@ -148,7 +149,7 @@ true - + pkgAtlas.bpl true From 16c7c4829f154b776f999b855607609c5f57cd5d Mon Sep 17 00:00:00 2001 From: Mozart Date: Tue, 17 Nov 2020 03:41:39 -0300 Subject: [PATCH 2/4] =?UTF-8?q?=EF=BF=BD=20Adiciona=20MailBase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adiciona MailBase para implementação do envio de email --- Source/Mail/MailBase.pas | 338 ++++++++++++++++++++ Source/Mail/{Mail.pas => MailInterface.pas} | 2 +- pkgAtlas.dpk | 3 +- pkgAtlas.dproj | 3 +- 4 files changed, 343 insertions(+), 3 deletions(-) create mode 100644 Source/Mail/MailBase.pas rename Source/Mail/{Mail.pas => MailInterface.pas} (98%) diff --git a/Source/Mail/MailBase.pas b/Source/Mail/MailBase.pas new file mode 100644 index 0000000..d0a7233 --- /dev/null +++ b/Source/Mail/MailBase.pas @@ -0,0 +1,338 @@ +unit MailBase; + +interface + +uses + System.SysUtils, + System.Classes, + MailInterface; + +type + TMailBase = class abstract(TInterfacedObject, IMail) + private + FHost: string; + FPort: Integer; + FUsername: string; + FPassword: string; + FSSL: Boolean; + FTLS: Boolean; + FAuthentication: Boolean; + FFromName: string; + FFromAddress: string; + FReplyToName: string; + FReplyToAddress: string; + FToRecipient: TStringList; + FCcRecipient: TStringList; + FBccRecipient: TStringList; + FConfirmation: Boolean; + FAttachment: TStringList; + FSubject: string; + FMessage: TStringList; + FHTML: Boolean; + protected + function GetHost: string; + function GetPort: Integer; + function GetUsername: string; + function GetPassword: string; + function IsWithSSL: Boolean; + function IsWithTLS: Boolean; + function IsWithAuthentication: Boolean; + function GetFromName: string; + function GetFromAddress: string; + function GetReplyToName: string; + function GetReplyToAddress: string; + function GetToRecipient: TStringList; + function GetCcRecipient: TStringList; + function GetBccRecipient: TStringList; + function IsWithConfirmation: Boolean; + function GetAttachments: TStringList; + function GetSubject: string; + function GetMessage: TStringList; + function IsWithHTML: Boolean; + + procedure DoSend; virtual; abstract; + + public + constructor Create; + destructor Destroy; override; + + function Host(const AValue: string): IMail; + function Port(const AValue: Integer): IMail; + function Username(const AValue: string): IMail; + function Password(const AValue: string): IMail; + function UsingSSL(const AValue: Boolean = True): IMail; + function UsingTLS(const AValue: Boolean = True): IMail; + function AuthenticationRequired(const AValue: Boolean = True): IMail; + + function From(const AName: string; const AAddress: string): IMail; + function ReplyTo(const AName: string; const AAddress: string): IMail; + function ToRecipient(const AAddress: string): IMail; + function CcRecipient(const AAddress: string): IMail; + function BccRecipient(const AAddress: string): IMail; + function AskForConfirmation(const AValue: Boolean = True): IMail; + + function Attachment(const AFileName: string): IMail; + + function Subject(const AValue: string): IMail; + function &Message(const AValue: string): IMail; overload; + function &Message(const AValue: TStringList): IMail; overload; + function UsingHTML(const AValue: Boolean = True): IMail; + + procedure Send; + end; + +implementation + +{ TMailBase } + +function TMailBase.AskForConfirmation(const AValue: Boolean): IMail; +begin + FConfirmation := AValue; + Result := Self; +end; + +function TMailBase.Attachment(const AFileName: string): IMail; +begin + FAttachment.Add(AFileName); + Result := Self; +end; + +function TMailBase.AuthenticationRequired(const AValue: Boolean): IMail; +begin + FAuthentication := AValue; + Result := Self; +end; + +function TMailBase.BccRecipient(const AAddress: string): IMail; +begin + FBccRecipient.Add(AAddress); + Result := Self; +end; + +function TMailBase.CcRecipient(const AAddress: string): IMail; +begin + FCcRecipient.Add(AAddress); + Result := Self; +end; + +constructor TMailBase.Create; +begin + inherited Create; + FHost := EmptyStr; + FPort := 0; + FUsername := EmptyStr; + FPassword := EmptyStr; + FSSL := False; + FTLS := False; + FAuthentication := False; + FFromName := EmptyStr; + FFromAddress := EmptyStr; + FToRecipient := TStringList.Create; + FCcRecipient := TStringList.Create; + FBccRecipient := TStringList.Create; + FConfirmation := False; + FAttachment := TStringList.Create; + FSubject := EmptyStr; + FMessage := TStringList.Create; + FHTML := False; +end; + +destructor TMailBase.Destroy; +begin + FreeAndNil(FToRecipient); + FreeAndNil(FCcRecipient); + FreeAndNil(FBccRecipient); + FreeAndNil(FAttachment); + FreeAndNil(FMessage); + inherited Destroy; +end; + +function TMailBase.From(const AName, AAddress: string): IMail; +begin + FFromName := AName; + FFromAddress := AAddress; + Result := Self; +end; + +function TMailBase.GetAttachments: TStringList; +begin + Result := FAttachment; +end; + +function TMailBase.GetBccRecipient: TStringList; +begin + Result := FBccRecipient; +end; + +function TMailBase.GetCcRecipient: TStringList; +begin + Result := FCcRecipient; +end; + +function TMailBase.GetFromAddress: string; +begin + Result := FFromAddress; +end; + +function TMailBase.GetFromName: string; +begin + Result := FFromName; +end; + +function TMailBase.GetHost: string; +begin + Result := FHost; +end; + +function TMailBase.GetMessage: TStringList; +begin + Result := FMessage; +end; + +function TMailBase.GetPassword: string; +begin + Result := FPassword; +end; + +function TMailBase.GetPort: Integer; +begin + Result := FPort; +end; + +function TMailBase.GetReplyToAddress: string; +begin + Result := FReplyToAddress; + if Result.Trim.IsEmpty then + begin + Result := FFromAddress; + end; +end; + +function TMailBase.GetReplyToName: string; +begin + Result := FReplyToName; + if Result.Trim.IsEmpty then + begin + Result := FFromName; + end; +end; + +function TMailBase.GetSubject: string; +begin + Result := FSubject; +end; + +function TMailBase.GetToRecipient: TStringList; +begin + Result := FToRecipient; +end; + +function TMailBase.GetUsername: string; +begin + Result := FUsername; +end; + +function TMailBase.Host(const AValue: string): IMail; +begin + FHost := AValue; + Result := Self; +end; + +function TMailBase.IsWithAuthentication: Boolean; +begin + Result := FAuthentication; +end; + +function TMailBase.IsWithConfirmation: Boolean; +begin + Result := FConfirmation; +end; + +function TMailBase.IsWithHTML: Boolean; +begin + Result := FHTML; +end; + +function TMailBase.IsWithSSL: Boolean; +begin + Result := FSSL; +end; + +function TMailBase.IsWithTLS: Boolean; +begin + Result := FTLS; +end; + +function TMailBase.Message(const AValue: string): IMail; +begin + FMessage.Add(AValue); + Result := Self; +end; + +function TMailBase.Message(const AValue: TStringList): IMail; +begin + FMessage.Text := AValue.Text; + Result := Self; +end; + +function TMailBase.Password(const AValue: string): IMail; +begin + FPassword := AValue; + Result := Self; +end; + +function TMailBase.Port(const AValue: Integer): IMail; +begin + FPort := AValue; + Result := Self; +end; + +function TMailBase.ReplyTo(const AName, AAddress: string): IMail; +begin + FReplyToName := AName; + FReplyToAddress := AAddress; + Result := Self; +end; + +procedure TMailBase.Send; +begin + DoSend; +end; + +function TMailBase.Subject(const AValue: string): IMail; +begin + FSubject := AValue; + Result := Self; +end; + +function TMailBase.ToRecipient(const AAddress: string): IMail; +begin + FToRecipient.Add(AAddress); + Result := Self; +end; + +function TMailBase.Username(const AValue: string): IMail; +begin + FUsername := AValue; + Result := Self; +end; + +function TMailBase.UsingHTML(const AValue: Boolean): IMail; +begin + FHTML := AValue; + Result := Self; +end; + +function TMailBase.UsingSSL(const AValue: Boolean): IMail; +begin + FSSL := AValue; + Result := Self; +end; + +function TMailBase.UsingTLS(const AValue: Boolean): IMail; +begin + FTLS := AValue; + Result := Self; +end; + +end. diff --git a/Source/Mail/Mail.pas b/Source/Mail/MailInterface.pas similarity index 98% rename from Source/Mail/Mail.pas rename to Source/Mail/MailInterface.pas index 63d1d0b..351bd62 100644 --- a/Source/Mail/Mail.pas +++ b/Source/Mail/MailInterface.pas @@ -1,4 +1,4 @@ -unit Mail; +unit MailInterface; interface diff --git a/pkgAtlas.dpk b/pkgAtlas.dpk index 6cda317..4e5ea4b 100644 --- a/pkgAtlas.dpk +++ b/pkgAtlas.dpk @@ -40,6 +40,7 @@ contains SQLBuilder in 'Source\SQLBuilder\SQLBuilder.pas', Conexao in 'Source\Objetos\Conexao.pas', Types.Conexao in 'Source\Objetos\Types.Conexao.pas', - Mail in 'Source\Mail\Mail.pas'; + MailInterface in 'Source\Mail\MailInterface.pas', + MailBase in 'Source\Mail\MailBase.pas'; end. diff --git a/pkgAtlas.dproj b/pkgAtlas.dproj index 5fc1b43..8ad0e9a 100644 --- a/pkgAtlas.dproj +++ b/pkgAtlas.dproj @@ -106,7 +106,8 @@ - + + Cfg_2 Base From e41647eb3b30c14d008003c901451afe770737f1 Mon Sep 17 00:00:00 2001 From: Mozart Date: Tue, 17 Nov 2020 22:34:08 -0300 Subject: [PATCH 3/4] =?UTF-8?q?=EF=BF=BD=20Adiciona=20README=20para=20Mail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adiciona um README.md para o framework Mail a fim de explicar o funcionamento --- Source/Mail/MailBase.pas | 72 ++++++++++++++++++++-------------------- Source/Mail/README.md | 41 +++++++++++++++++++++++ TestAtlas.dpr | 6 +++- TestAtlas.dproj | 4 +++ pkgAtlas.dpk | 8 +++-- pkgAtlas.dproj | 10 ++++-- 6 files changed, 99 insertions(+), 42 deletions(-) create mode 100644 Source/Mail/README.md diff --git a/Source/Mail/MailBase.pas b/Source/Mail/MailBase.pas index d0a7233..33169dc 100644 --- a/Source/Mail/MailBase.pas +++ b/Source/Mail/MailBase.pas @@ -21,13 +21,13 @@ TMailBase = class abstract(TInterfacedObject, IMail) FFromAddress: string; FReplyToName: string; FReplyToAddress: string; - FToRecipient: TStringList; - FCcRecipient: TStringList; - FBccRecipient: TStringList; + FToRecipients: TStringList; + FCcRecipients: TStringList; + FBccRecipients: TStringList; FConfirmation: Boolean; - FAttachment: TStringList; + FAttachments: TStringList; FSubject: string; - FMessage: TStringList; + FMessages: TStringList; FHTML: Boolean; protected function GetHost: string; @@ -41,13 +41,13 @@ TMailBase = class abstract(TInterfacedObject, IMail) function GetFromAddress: string; function GetReplyToName: string; function GetReplyToAddress: string; - function GetToRecipient: TStringList; - function GetCcRecipient: TStringList; - function GetBccRecipient: TStringList; + function GetToRecipients: TStringList; + function GetCcRecipients: TStringList; + function GetBccRecipients: TStringList; function IsWithConfirmation: Boolean; function GetAttachments: TStringList; function GetSubject: string; - function GetMessage: TStringList; + function GetMessages: TStringList; function IsWithHTML: Boolean; procedure DoSend; virtual; abstract; @@ -75,7 +75,7 @@ TMailBase = class abstract(TInterfacedObject, IMail) function Subject(const AValue: string): IMail; function &Message(const AValue: string): IMail; overload; - function &Message(const AValue: TStringList): IMail; overload; + function &Message(const AValues: TStringList): IMail; overload; function UsingHTML(const AValue: Boolean = True): IMail; procedure Send; @@ -93,7 +93,7 @@ function TMailBase.AskForConfirmation(const AValue: Boolean): IMail; function TMailBase.Attachment(const AFileName: string): IMail; begin - FAttachment.Add(AFileName); + FAttachments.Add(AFileName); Result := Self; end; @@ -105,13 +105,13 @@ function TMailBase.AuthenticationRequired(const AValue: Boolean): IMail; function TMailBase.BccRecipient(const AAddress: string): IMail; begin - FBccRecipient.Add(AAddress); + FBccRecipients.Add(AAddress); Result := Self; end; function TMailBase.CcRecipient(const AAddress: string): IMail; begin - FCcRecipient.Add(AAddress); + FCcRecipients.Add(AAddress); Result := Self; end; @@ -127,23 +127,23 @@ constructor TMailBase.Create; FAuthentication := False; FFromName := EmptyStr; FFromAddress := EmptyStr; - FToRecipient := TStringList.Create; - FCcRecipient := TStringList.Create; - FBccRecipient := TStringList.Create; + FToRecipients := TStringList.Create; + FCcRecipients := TStringList.Create; + FBccRecipients := TStringList.Create; FConfirmation := False; - FAttachment := TStringList.Create; + FAttachments := TStringList.Create; FSubject := EmptyStr; - FMessage := TStringList.Create; + FMessages := TStringList.Create; FHTML := False; end; destructor TMailBase.Destroy; begin - FreeAndNil(FToRecipient); - FreeAndNil(FCcRecipient); - FreeAndNil(FBccRecipient); - FreeAndNil(FAttachment); - FreeAndNil(FMessage); + FreeAndNil(FToRecipients); + FreeAndNil(FCcRecipients); + FreeAndNil(FBccRecipients); + FreeAndNil(FAttachments); + FreeAndNil(FMessages); inherited Destroy; end; @@ -156,17 +156,17 @@ function TMailBase.From(const AName, AAddress: string): IMail; function TMailBase.GetAttachments: TStringList; begin - Result := FAttachment; + Result := FAttachments; end; -function TMailBase.GetBccRecipient: TStringList; +function TMailBase.GetBccRecipients: TStringList; begin - Result := FBccRecipient; + Result := FBccRecipients; end; -function TMailBase.GetCcRecipient: TStringList; +function TMailBase.GetCcRecipients: TStringList; begin - Result := FCcRecipient; + Result := FCcRecipients; end; function TMailBase.GetFromAddress: string; @@ -184,9 +184,9 @@ function TMailBase.GetHost: string; Result := FHost; end; -function TMailBase.GetMessage: TStringList; +function TMailBase.GetMessages: TStringList; begin - Result := FMessage; + Result := FMessages; end; function TMailBase.GetPassword: string; @@ -222,9 +222,9 @@ function TMailBase.GetSubject: string; Result := FSubject; end; -function TMailBase.GetToRecipient: TStringList; +function TMailBase.GetToRecipients: TStringList; begin - Result := FToRecipient; + Result := FToRecipients; end; function TMailBase.GetUsername: string; @@ -265,13 +265,13 @@ function TMailBase.IsWithTLS: Boolean; function TMailBase.Message(const AValue: string): IMail; begin - FMessage.Add(AValue); + FMessages.Add(AValue); Result := Self; end; -function TMailBase.Message(const AValue: TStringList): IMail; +function TMailBase.Message(const AValues: TStringList): IMail; begin - FMessage.Text := AValue.Text; + FMessages.Text := AValues.Text; Result := Self; end; @@ -307,7 +307,7 @@ function TMailBase.Subject(const AValue: string): IMail; function TMailBase.ToRecipient(const AAddress: string): IMail; begin - FToRecipient.Add(AAddress); + FToRecipients.Add(AAddress); Result := Self; end; diff --git a/Source/Mail/README.md b/Source/Mail/README.md new file mode 100644 index 0000000..aa97822 --- /dev/null +++ b/Source/Mail/README.md @@ -0,0 +1,41 @@ +# E-mail para Delphi + +Framework de mailing voltada para simplificar o envio de e-mails com Delphi. +Inclui envio de e-mails com texto simples e/ou HTML, imagens incorporadas e anexos separados. +Utiliza: SMTP ou SMTPS/SSL ou SMTP + SSL. +O **Mail** fornece uma estrutura independente de driver, sendo possível extendê-lo para outros, como **Outlook**, **MAPI**, **Synapse** entre outros. + +A estrutura da mensagem de e-mail foi construída para funcionar com todos os clientes de e-mail e foi testada com muitos clientes da web, bem como alguns aplicativos de cliente convencionais, como MS Outlook ou Mozilla Thunderbird. + +# Drivers implementados +- Indy + +# Modo de usar +Adicione no library path do Delphi: + +> Source\Mail + +# Exemplo de uso + +``` +uses + MailBase, + Mail.Indy; + +procedure EnviaEmail; +begin + TMailIndy.New + .Host('smtp.exemplo.com.br') + .Port(123) + .Username('usuario') + .Password('senha_forte_do_usuario') + .From('Princess Leia', 'princess.leia@jabba.the.hutt.com') + .ToRecipient('darth.vader@darkforce.com') + .CcRecipient('mestre.yoda@jedi.com') + .BccRecipient('obi.wan.kenoby@jedi.com') + .Attachment('C:\jabba.the.hutt.kill.luke.skywalker.jpg') + .Subject('Veja só, Jabba The Hutt mata Luke Skywalker') + .Message('Caro Darth Vader, veja como ele ficou nessa imagem... hahahaha') + .Send; +end +``` \ No newline at end of file diff --git a/TestAtlas.dpr b/TestAtlas.dpr index 5412a07..2eb91e8 100644 --- a/TestAtlas.dpr +++ b/TestAtlas.dpr @@ -16,7 +16,11 @@ uses TesteSQLBuilder.Insert in 'Testes\SQLBuilder\TesteSQLBuilder.Insert.pas', TesteObjetoConexao in 'Testes\TesteObjetoConexao.pas', Types.Conexao in 'Source\Objetos\Types.Conexao.pas', - SQLBuilder in 'Source\SQLBuilder\SQLBuilder.pas'; + SQLBuilder in 'Source\SQLBuilder\SQLBuilder.pas', + TesteMail.Indy in 'Testes\Mail\TesteMail.Indy.pas', + MailInterface in 'Source\Mail\MailInterface.pas', + MailBase in 'Source\Mail\MailBase.pas', + Mail.Indy in 'Source\Mail\Mail.Indy.pas'; var runner : ITestRunner; diff --git a/TestAtlas.dproj b/TestAtlas.dproj index bbc59c3..fb2e90d 100644 --- a/TestAtlas.dproj +++ b/TestAtlas.dproj @@ -106,6 +106,10 @@ + + + + Cfg_2 Base diff --git a/pkgAtlas.dpk b/pkgAtlas.dpk index 4e5ea4b..ae6730b 100644 --- a/pkgAtlas.dpk +++ b/pkgAtlas.dpk @@ -33,7 +33,10 @@ requires rtl, vcl, FireDAC, - dbrtl; + dbrtl, + IndySystem, + IndyProtocols, + IndyCore; contains ValorPor in 'Source\ValorPor.pas', @@ -41,6 +44,7 @@ contains Conexao in 'Source\Objetos\Conexao.pas', Types.Conexao in 'Source\Objetos\Types.Conexao.pas', MailInterface in 'Source\Mail\MailInterface.pas', - MailBase in 'Source\Mail\MailBase.pas'; + MailBase in 'Source\Mail\MailBase.pas', + Mail.Indy in 'Source\Mail\Mail.Indy.pas'; end. diff --git a/pkgAtlas.dproj b/pkgAtlas.dproj index 8ad0e9a..020f718 100644 --- a/pkgAtlas.dproj +++ b/pkgAtlas.dproj @@ -102,12 +102,16 @@ + + + + Cfg_2 Base @@ -150,14 +154,14 @@ true - + - pkgAtlas.bpl true - + + pkgAtlas.bpl true From 4eee1e6984a0c84a9c9152bf8d2fe30e6bc0ce59 Mon Sep 17 00:00:00 2001 From: Mozart Date: Tue, 17 Nov 2020 22:35:17 -0300 Subject: [PATCH 4/4] Framework para envio de e-mail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Framework para envio de email + README.md + testes unitários --- Source/Mail/Mail.Indy.pas | 205 +++++++++++++++++++++++++++++++++ Testes/Mail/TesteMail.Indy.pas | 45 ++++++++ 2 files changed, 250 insertions(+) create mode 100644 Source/Mail/Mail.Indy.pas create mode 100644 Testes/Mail/TesteMail.Indy.pas diff --git a/Source/Mail/Mail.Indy.pas b/Source/Mail/Mail.Indy.pas new file mode 100644 index 0000000..11d905d --- /dev/null +++ b/Source/Mail/Mail.Indy.pas @@ -0,0 +1,205 @@ +unit Mail.Indy; + +interface + +uses + System.SysUtils, + IdSMTP, + IdMessage, + IdSSLOpenSSL, + IdExplicitTLSClientServerBase, + IdText, + IdAttachmentFile, + MailInterface, + MailBase; + +type + EMailIndyException = class(EMailException); + + TMailIndy = class(TMailBase, IMail) + private const + CONNECT_TIMEOUT = 10000; + READ_TIMEOUT = 10000; + private + procedure ConfigureSmtp(const ASmtp: TIdSMTP); + procedure AddToRecipients(const AMsg: TIdMessage); + procedure AddCcRecipients(const AMsg: TIdMessage); + procedure AddBccRecipients(const AMsg: TIdMessage); + procedure AddFrom(const AMsg: TIdMessage); + procedure AddReplyTo(const AMsg: TIdMessage); + procedure AddAttachments(const AMsg: TIdMessage); + procedure AddBody(const AMsg: TIdMessage); + protected + procedure DoSend; override; + public + class function New: IMail; static; + end; + +implementation + +{ TMailIndy } + +procedure TMailIndy.AddAttachments(const AMsg: TIdMessage); +var + i: Integer; + attachment: TIdAttachmentFile; +begin + for i := 0 to Pred(GetAttachments.Count) do + begin + attachment := TIdAttachmentFile.Create(AMsg.MessageParts, GetAttachments[i]); + attachment.Headers.Add(Format('Content-ID: <%s>', [ExtractFileName(GetAttachments[i])])); + end; +end; + +procedure TMailIndy.AddBccRecipients(const AMsg: TIdMessage); +var + i: Integer; +begin + for i := 0 to Pred(GetBccRecipients.Count) do + begin + with AMsg.BccList.Add do + begin + Address := GetBccRecipients[i]; + end; + end; +end; + +procedure TMailIndy.AddBody(const AMsg: TIdMessage); +var + body: TIdText; +begin + body := TIdText.Create(AMsg.MessageParts); + body.Body.Text := GetMessages.Text; + body.ContentType := 'text/plain'; + if IsWithHTML then + begin + body.ContentType := 'text/html'; + end; +end; + +procedure TMailIndy.AddCcRecipients(const AMsg: TIdMessage); +var + i: Integer; +begin + for i := 0 to Pred(GetCcRecipients.Count) do + begin + with AMsg.CCList.Add do + begin + Address := GetCcRecipients[i]; + end; + end; +end; + +procedure TMailIndy.AddFrom(const AMsg: TIdMessage); +begin + AMsg.From.Address := GetFromAddress; + AMsg.From.Name := GetFromName; + if IsWithConfirmation then + begin + AMsg.ReceiptRecipient.Address := GetFromAddress; + AMsg.ReceiptRecipient.Name := GetFromName; + end; +end; + +procedure TMailIndy.AddReplyTo(const AMsg: TIdMessage); +begin + with AMsg.ReplyTo.Add do + begin + Address := GetReplyToAddress; + Name := GetReplyToName; + end; +end; + +procedure TMailIndy.AddToRecipients(const AMsg: TIdMessage); +var + i: Integer; +begin + for i := 0 to Pred(GetToRecipients.Count) do + begin + with AMsg.Recipients.Add do + begin + Address := GetToRecipients[i]; + end; + end; +end; + +procedure TMailIndy.ConfigureSmtp(const ASmtp: TIdSMTP); +begin + ASmtp.ConnectTimeout := CONNECT_TIMEOUT; + ASmtp.ReadTimeout := READ_TIMEOUT; + ASmtp.Host := GetHost; + ASmtp.Username := GetUsername; + ASmtp.Password := GetPassword; + ASmtp.Port := GetPort; + ASmtp.AuthType := satNone; + if IsWithAuthentication then + begin + ASmtp.AuthType := satDefault; + end; + if IsWithSSL then + begin + ASmtp.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(ASmtp); + TIdSSLIOHandlerSocketOpenSSL(ASmtp.IOHandler).SSLOptions.Method := sslvSSLv23; + TIdSSLIOHandlerSocketOpenSSL(ASmtp.IOHandler).SSLOptions.Mode := sslmClient; + ASmtp.UseTLS := utUseExplicitTLS; + end; + if IsWithTLS then + begin + ASmtp.UseTLS := utUseRequireTLS; + end; +end; + +procedure TMailIndy.DoSend; +var + smtp: TIdSMTP; + msg: TIdMessage; +begin + inherited; + smtp := TIdSMTP.Create(nil); + try + try + ConfigureSmtp(smtp); + msg := TIdMessage.Create(nil); + try + msg.Date := Now; + msg.Subject := GetSubject; + msg.ContentType := 'multipart/mixed'; + + AddToRecipients(msg); + AddCcRecipients(msg); + AddBccRecipients(msg); + AddFrom(msg); + AddReplyTo(msg); + AddAttachments(msg); + AddBody(msg); + + smtp.Connect; + try + if IsWithAuthentication then + begin + smtp.Authenticate; + end; + smtp.Send(msg); + finally + smtp.Disconnect; + end; + finally + FreeAndNil(msg); + end; + except + on E: Exception do + begin + raise EMailIndyException.Create('E-mail could not be sent!' + ^M + E.Message); + end; + end; + finally + FreeAndNil(smtp); + end; +end; + +class function TMailIndy.New: IMail; +begin + Result := TMailIndy.Create; +end; + +end. diff --git a/Testes/Mail/TesteMail.Indy.pas b/Testes/Mail/TesteMail.Indy.pas new file mode 100644 index 0000000..a3e027f --- /dev/null +++ b/Testes/Mail/TesteMail.Indy.pas @@ -0,0 +1,45 @@ +unit TesteMail.Indy; + +interface + +uses + DUnitX.TestFramework, + DUnitX.Assert.Ex; + +type + + [ TestFixture ] + TTestSQLBuilderSelect = class( TObject ) + public + + [ Test ] + procedure sendEmail; + + end; + +implementation + +uses + MailBase, + Mail.Indy; + +{ TTestSQLBuilderSelect } + +procedure TTestSQLBuilderSelect.sendEmail; +begin + TMailIndy.New + .Host('') + .Port(0) + .Username('') + .Password('') + .From('name', 'email') + .ToRecipient('') + .CcRecipient('') + .BccRecipient('') + .Attachment('') + .Subject('') + .Message('') + .Send; +end; + +end.