Sending mails from a client app is an interesting feature, it can be used for sending notifications or authentication codes. You can add this option to your Delphi (desktop and mobile) apps by calling a PHP web script through REST client.
The PHP script
The steps for writing a PHP script for sending mails (through the PHP built-in “mail()” function) are described in this tutorial :
Create PHP script for sending mails
Delphi client app
Let’s develop a GUI client app in Delphi (either in FMX or VCL), design the required controls and write the code for handling the mail variables.
You can use text controls like in a mail client app, or you can make the mail variables not visible to the user, by loading their values in the background then sending the mail.
REST service exploration
We will explore our REST service :
- Open the Embarcadero REST Debugger.
- In the base URL, enter the URL of your PHP mail script (like “https://mydomain.com/mail.php”), make sure that the URL’s protocol is ‘https’, otherwise it will not work on Android.
- Select the POST method.
- Go to the parameters tab, and add parameters for the mail variables : choose the kind “GET/POST”, name each parameter according to our PHP script request’s parameters, and set a test value, like in the table below.
For long texts (like an HTML formatted text), the script can get the mail’s text from the request’s body, so we can also use the parameter kind “BODY”.
Kind | Name | Value (example) |
GET/POST | to | target@domain.com |
GET/POST | subject | Mail testing |
GET/POST or BODY | txt | This is a test mail |
GET/POST | from | sender@domain.com or Sender <sender@domain.com> |
Now, send the request.
When a response is received, go to the body tab, and you will see a string containing the number “1” (if the mail was sent).
After you confirmed that our service is working, click on the button ‘Copy components’ to copy the REST client’s controls set and paste them in your Delphi app.
You will get these components (TRESTClient, TRESTRequest and TRESTResponse) in your clipboard (as DFM code) :
object RESTClient1: TRESTClient
BaseURL = 'https://mydomain.com/mail.php'
Params = <>
end
object RESTRequest1: TRESTRequest
AssignedValues = [rvConnectTimeout, rvReadTimeout]
Client = RESTClient1
Method = rmPOST
Params = <
item
Name = 'to'
Value = 'target@domain.com'
end
item
Name = 'subject'
Value = 'Mail testing'
end
item
Name = 'txt'
Value = 'This is a test mail'
end
item
Name = 'from'
Value = 'Sender <sender@domain.com>'
end> Response = RESTResponse1
end
object RESTResponse1: TRESTResponse
end
Delphi implementation
Paste the copied components to your Delphi form, you will see a set of three non-visual components (TRESTClient, TRESTRequest and TRESTResponse).
You can change values of the parameters either :
- On design time, in the object inspector, or
- On runtime, you can set the value of each variable by accessing the parameter’s value. For example, for changing the ‘subject’ parameter’s value, you can use anyone of the following codes :
RESTRequest1.Params.Items[1].Value := 'New subject for test';
RESTRequest1.Params.ParameterByIndex(1).Value := 'New subject for test';
RESTRequest1.Params.ParameterByName('subject').Value := 'New subject for test';
Now, for sending the requests to our script, we will call the TRESTRequest procedure “Execute”.
For usage, we will implement an event, for getting the mail variables from TEdit controls, like this :
procedure TForm1.Button1Click(Sender: TObject);
begin
RESTClient1.ResetToDefaults;
RESTClient1.Accept := 'application/json, text/plain; q=0.9, text/html;q=0.8,';
RESTClient1.AcceptCharset := 'UTF-8, *;q=0.8';
RESTClient1.BaseURL := 'https://mydomain.com/mail.php';
RESTClient1.HandleRedirects := True;
RESTClient1.RaiseExceptionOn500 := False;
// Here we will pass the mail variables
RESTRequest1.Params.ParameterByName('to').Value := EditReceiver.Text;
RESTRequest1.Params.ParameterByName('subject').Value := EditSubject.Text;
RESTRequest1.Params.ParameterByName('txt').Value := Edit1.Text;
RESTRequest1.Client := RESTClient1;
RESTRequest1.Response := RESTResponse1;
RESTRequest1.SynchronizedEvents := False;
RESTResponse1.ContentType := 'application/json';
RESTRequest1.Execute;
end;
Bonus : set a separate function
You can create the whole set of REST Client controls on runtime from Object Pascal code, by writing a separate method (a function or a class function), on your project unit or on a spearate unit ready to be included in any project.
It is better to set a function (not a procedure) to use the script response as a result.
For creating a separate unit, go to the ‘New’ dialog and choose ‘Unit’.
Make sure to include the units “REST.Client” and “REST.Types” in the uses clauses.
unit PHPMail;
interface
uses
..., REST.Client, REST.Types, ...
type
TExtra = class
class function SendMail(sRecipient, sSubject, sText, sSenderAddress, sSenderName : string) : Boolean;
end;
implementation
class function TExtra.SendMail(sRecipient, sSubject, sText, sSenderAddress, sSenderName: string): boolean;
var
LClient : TRESTClient;
LRequest : TRESTRequest;
LResponse : TRESTResponse;
begin
LClient := TRESTClient.Create('https://mydomain.com/mail.php');
LResponse := TRESTResponse.Create(nil);
LRequest := TRESTRequest.Create(nil);
LRequest.Client := LClient;
LRequest.Response := LResponse;
//LRequest.AssignedValues := [TAssignedValue.rvConnectTimeout, TAssignedValue.rvReadTimeout];
try
try
LRequest.Method := TRESTRequestMethod.rmPOST;
LRequest.Params.AddItem('to', sRecipient, pkGETorPOST);
LRequest.Params.AddItem('subject', sSubject, pkGETorPOST);
LRequest.Params.AddItem('txt', sText, pkGETorPOST);
if sSenderName <> ''
then LRequest.Params.AddItem('from', sSenderName + ' <' + sSenderAddress +'>', pkGETorPOST)
else LRequest.Params.AddItem('from', sSenderAddress, pkGETorPOST);
LRequest.Execute;
except
Result := False;
end;
finally
Result := (LRequest.Response.Content.Contains('1'));
LRequest.Free;
LResponse.Free;
LClient.Free;
end;
end.
And we will call the function simply like this :
TExtra.SendMail('target@domain.com', 'Mail test', 'Mail test text', 'sender@domain.com', 'Mr. S');
We can also use the function result to notify if the mail was sent, like this :
procedure ...
begin
if TExtra.SendMail('target@domain.com', 'Mail test', 'Mail test text', 'sender@domain.com', 'Mr. S')
then ShowMessage('Mail sent successully')
else ShowMessage('Mail sending failed');
end;