From Clomosy Docs

(Created page with "In Clomosy, the TclRest component is a component that facilitates interaction with RESTful services for data transfer. REST (Representational State Transfer) is a popular architecture for data transfer between web-based services. With the TclRest component in Clomosy, you can easily communicate with such services and exchange data. Using the TclRest component, you can make requests to a RESTful service (GET, POST, etc.), receive responses, and process these responses....")
 
No edit summary
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
In Clomosy, the TclRest component is a component that facilitates interaction with RESTful services for data transfer. REST (Representational State Transfer) is a popular architecture for data transfer between web-based services. With the TclRest component in Clomosy, you can easily communicate with such services and exchange data.
In Clomosy, the TclRest component is a component that facilitates interaction with RESTful services for data transfer. REST (Representational State Transfer) is a popular architecture for data transfer between web-based services.<br>


Using the TclRest component, you can make requests to a RESTful service (GET, POST, etc.), receive responses, and process these responses.
With the TclRest component in Clomosy, you can easily communicate with such services and exchange data.<br>


Using the TclRest component, you can make requests to a RESTful service (GET, POST, etc.), receive responses, and process these responses.<br>


<div class="table-responsive">
{| class="wikitable" style="border: 2px solid #c3d7e0"
{| class="wikitable" style="border: 2px solid #c3d7e0"
! style="background-color: #c3d7e0"| Feature !!style="background-color: #c3d7e0"| Use of !!style="background-color: #c3d7e0"|Definition  
! style="background-color: #c3d7e0"| Feature !!style="background-color: #c3d7e0"| Use of !!style="background-color: #c3d7e0"| Definition  
|-
|-
|TclRest || clRest : TclRest; || An object of the TclRest class is defined.
|TclRest || clRest : TclRest; || An object of the TclRest class is defined.
|-
|-
|Create || clRest=TclRest.Create; || A new TclRest object is created on the form.
|Create || clRest = TclRest.Create; || A new TclRest object is created on the form.
|-
|-
|BaseURL ||clRest.BaseURL = 'https://dummyjson.com/auth/login';  || The URL address to access is given.
|BaseURL ||clRest.BaseURL = 'https://dummyjson.com/auth/login';  || The URL address to access is given.
|-
|-
|Accept ||clRest.Accept = 'application/json'; ||Specifies the media type the server will accept in the response. It is indicated that data will be received in JSON format in the example.  
|Resource ||clRest.Resource = 'users/123'; || Defines the API path to be used after the base URL.
|-
|AddHeader || clRest.AddHeader('Custom-Header', 'Value'); //Optional additional title<br>clRest.AddHeader('Authorization','Bearer your_api_key'); || The specified header is added to the HTTP request. It takes two parameters: the first parameter is the header name, and the second parameter provides information about the media type of the data sent to the server.<br>
In the example, the "Authorization" header is used to carry authentication information. The value of the 'Authorization' header usually contains a Bearer token. For example, a value like Bearer your_api_key is used. You should replace your_api_key with a valid API key or token.<br>
Another example allows you to add your custom headers as well. In the example, we added a Custom-Header header and its corresponding value. This entirely depends on the requirements of the API.
|-
|ContentType ||clRest.ContentType = 'application/json';<br> ShowMessage(clRest.ContentType) || Specifies the content type of the data to be sent (e.g., application/json, application/x-www-form-urlencoded).
|-
|RemoveHeader || clRest.RemoveHeader('Authorization'); || Removes a previously added header.
|-
|Accept ||clRest.Accept = 'application/json'; // 'text/xml' etc. ||Specifies the media type the server will accept in the response. It is indicated that data will be received in JSON format in the example.  
The Accept property also defaults to sending values in JSON format.
The Accept property also defaults to sending values in JSON format.
|-
|-
|Method ||clRest.Method = rmPOST; //rmGET  ||
|Method ||clRest.Method = rmPOST; //rmGET,rmPUT,rmDELETE ||
Specifies the type of HTTP request to be made. If you want to add new data to a resource or update an existing one with a POST request, you use '''rmPOST'''. If you want to retrieve the data of a resource with a GET request, you use '''rmGET'''.
Specifies the type of HTTP request to be made. If you want to add new data to a resource or update an existing one with a POST request, you use <b>rmPOST</b>. If you want to retrieve the data of a resource with a GET request, you use <b>rmGET</b>.
|-
|Body ||clRest.Body = '{"name": "Jack", "age": 35}'; || Contains the body data for the request (commonly used in POST and PUT requests).
|-
|ClearBody ||clRest.ClearBody; || Clears the previously added request body.
|-
|FormDataBody ||clRest.FormDataBody = 'password=123456';<br> ShowMessage(clRest.FormDataBody);<br>ShowMessage(clRest.FormDataBody.Text); || Used in requests containing form data (multipart/form-data).
|-
|-
|AddBody || clRest.AddBody('{"username":"kminchelle","password":"0lelplR"}','application/json'); || Adds the provided data to the body of the specified request. This body forms the part where the data is sent in requests like POST. The data specified in the request is transmitted to the server through this body. It takes two parameters. The first parameter specifies the data to be sent in the POST request body, and the second parameter indicates the media type of the sent data.
|AddBody || clRest.AddBody('{"username":"kminchelle","password":"0lelplR"}','application/json'); || Adds the provided data to the body of the specified request. This body forms the part where the data is sent in requests like POST. The data specified in the request is transmitted to the server through this body. It takes two parameters. The first parameter specifies the data to be sent in the POST request body, and the second parameter indicates the media type of the sent data.
|-
|-
|AddHeader ||clRest.AddHeader('Authorization','Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTUsInVzZXJuYW1lIjoia21pbmNoZWxsZSIsImVtYWlsIjoia21'); ||Adds the specified header to the HTTP request. It takes two parameters: the first parameter is the header name, and the second parameter informs the server about the media type of the sent data.
|AddQuery ||clRest.AddQuery('id', '123'); || Adds a parameter to the query string of a URL. For example, it is used to create a URL like https://api.example.com/users?id=123.
 
|-
In the example, the "Authorization" header is used to carry authentication credentials. The value of the 'Authorization' header in the second parameter represents a JWT (JSON Web Token). This token is a verified and secured piece of data authenticated by the server for user identification.
|GetQuery ||QueryValue = clRest.GetQuery('id'); //QueryValue : String; || Returns the query string parameter with the specified AKey value.
|-
|RemoveQuery ||clRest.RemoveQuery('id'); || Removes a previously added query parameter.
|-
|AddUrlSegment ||clRest.Resource = 'users/{userId}';<br> clRest.AddUrlSegment('userId', '123'); || It is used to dynamically insert variables into a URL. For example, it fills the {userId} variable in a URL template like https://api.example.com/users/{userId}.
|-
|RemoveUrlSegment ||clRest.RemoveUrlSegment('userId'); || Removes a previously added URL segment variable.
|-
|Execute ||clRest.Execute;  ||When this method is executed, the TclRest component performs the specified request and receives the response from the server. Executes the REST request synchronously. This means the code does not proceed until this function completes.
|-
|OnCompleted ||clRest.OnCompleted = CompletedProc; //CompletedProc : void || Triggered when the ExecuteAsync operation is completed.
|-
|CompletedTrigger ||clRest.CompletedTrigger; || Triggers the OnCompleted event when ExecuteAsync is completed.
|-
|-
|Execute ||clRest.Execute; ||When this method is executed, the TclRest component performs the specified request and receives the response from the server.
|ExecuteAsync ||clRest.OnCompleted = CompletedProc; //CompletedProc : void <br> clRest.ExecuteAsync; || Executes the REST request asynchronously (in the background). The code continues running, and an event is triggered when the operation is complete (therefore, the OnCompleted property should be defined beforehand).
|-
|-
|Response || ShowMessage(clRest.Response); ||You can access the details and content of the response from the server.
|Response || ShowMessage(clRest.Response); ||You can access the details and content of the response from the server.
|-
|ClearParams ||clRest.ClearParams; || Clears all previously added parameters (header, query, segment).
|-
|StatusCode || ShowMessage(clRest.StatusCode); || Returns the HTTP status code (200, 404, 500, etc.).
|-
|StatusText || ShowMessage(clRest.StatusText); || Returns the description of the HTTP status code (e.g., OK, Not Found, etc.).
|-
|ConnectTimeout ||clRest.ConnectTimeOut = 60000; || Sets the connection timeout duration in milliseconds.
|-
|ResponseHeaders || ShowMessage(clRest.ResponseHeaders.Text);<br>  ShowMessage(clRest.ResponseHeaders.Count);<br>  ShowMessage(clRest.ResponseHeaders[0]); ||Contains the response headers returned from the server.<br> The Text property returns the response headers from the server.<br>
The total number of received HTTP headers is shown by Count.<br>
A specific HTTP header can be retrieved by specifying its index.<br>
|-
|GetHeader ||HeaderValue = clRest.GetHeader('Content-Type'); //HeaderValue : String; || Returns the HTTP header with the specified AKey value.
|-
|ProxyServer  ||clRest.ProxyServer = '192.168.1.100'; || Specifies the address of the proxy server to be used.
|-
|ProxyUsername ||clRest.ProxyUsername = 'myProxyUser';|| Sets the username to be used when connecting to the proxy server.
|-
|ProxyPassword ||clRest.ProxyPassword = 'myProxyPass'; || Sets the password required to connect to the proxy server if a proxy is being used.
|-
|ProxyPort ||clRest.ProxyPort = 8080; || Sets the port number of the proxy server.
|}
|}
</div>
<div class="alert alert-primary" role="alert" data-bs-theme="light">
<b>INFORMATION</b><br>
:<b>rmGET</b>: Used to retrieve an existing resource. Sends a request to the API to fetch data from the specified URL. For example, it is used to get a blog post or a list of users. The response is usually returned in JSON format.
:<b>rmPOST</b>: Used to create a new resource. Sends JSON data to the API to add a new record. For example, it is used to create a new blog post or register a user.
:<b>rmPUT</b>: Used to fully update an existing resource. Sends a JSON request containing the entire updated data to the API. For example, it is used to change the title and content of an existing blog post. However, if the specified ID is incorrect or the resource does not exist, a 404 error may be returned.
:<b>rmDELETE</b>: Used to delete a specified resource. Sends a request to the API with the ID of the resource to be deleted. For example, it is used to remove a blog post or delete a user from the database.
</div>
<h3>Example 1 - GET/POST </h3>
<pre>
var
  Form1 : TclForm;
  clRest : TCLRest;
  Button1 : TCLButton;
void GetPostMethod;
{
  clRest.Execute;
  ShowMessage(clRest.Response);
}
{
  Form1 = TclForm.Create(Self);
 
  Button1 = Form1.AddNewButton(Form1,'Button1', 'Click');
  Form1.AddNewEvent(Button1, tbeOnClick, 'GetPostMethod');
 
  clRest=TCLRest.Create;
 
  // Post
 
  clRest.BaseURL = 'https://jsonplaceholder.typicode.com/posts';
  clRest.Accept = 'application/json';
  clRest.Method = rmPOST;
  clRest.AddBody('{"name":"John","job":"Developer"}','application/json');
  //clRest.AddHeader('Content-Type','application/json');
 
  // Get
  /*
  clRest.BaseURL = 'https://jsonplaceholder.typicode.com/posts/1';
  clRest.Accept = 'application/json';
  clRest.Method = rmGET;
  clRest.AddHeader('Custom-Header', 'Value'); //Optional additional title
  //clRest.AddHeader('Authorization', 'Bearer your_api_key');
 
  */
  Form1.Run;
}
</pre>
<h3>Example 2 - GET/POST/PUT/DELETE </h3>
This code creates a form and adds buttons to perform "GET, POST, PUT, and DELETE" operations, setting up a REST client. The "TclRest" object sends requests to a REST API, and the response is displayed in the "Memo1" component. The "SendRequest" procedure initiates an "asynchronous request" based on the specified HTTP method ("rmGET, rmPOST, rmPUT, rmDELETE"), URL, and optionally a JSON body. When a response is received, "CompletedProc" executes to update the Memo. Clicking the buttons triggers the corresponding request function, which directs the call to "SendRequest" and performs the API request.<br>
<pre>
var
  MyForm:TCLForm;
  btnGet, btnPost, btnDelete,btnPut : TclButton;
  RestClient: TclRest;
  Memo1 : TclMemo;


'''Example:'''<br>
void CompletedProc;
:'''Base Syntax'''
{
   var
   Memo1.Lines.Clear;
    Form1 : TclForm;  
  Memo1.Lines.Add(RestClient.Response);
    clRest : TCLRest;
    Button1 : TCLButton;
    
    
   procedure GetPostMethod;
   RestClient.Free;
   begin
   RestClient = Nil;
    clRest.Execute;
}
    ShowMessage(clRest.Response);
  end;
    
    
   begin
void SendRequest(AMethod,AURL,ABody);
     Form1 := TclForm.Create(Self);
{
  RestClient = TclRest.Create;
   try
     try
      RestClient.Accept = 'application/json';
      RestClient.ContentType = 'application/json';
      RestClient.ConnectTimeOut = 60000;
      RestClient.BaseURL = AURL;
      if (ABody <> '')
        RestClient.Body = ABody;
      RestClient.Method = AMethod;
      RestClient.OnCompleted = 'CompletedProc';
      RestClient.ExecuteAsync;
    except
    ShowMessage('Exception Class: '+LastExceptionClassName+' Exception Message: '+LastExceptionMessage);
    }
  finally
  }
}
 
//  GET Request
void GetRequest;
{
  SendRequest(rmGet,'https://jsonplaceholder.typicode.com/posts/8','');
}
 
//  POST Request
void PostRequest;
{
  SendRequest(rmPost,'https://jsonplaceholder.typicode.com/posts','{"title": "Hello", "body": "This is a test", "userId": 1}');
}
 
//  DELETE Request
void DeleteRequest;
{
  SendRequest(rmDELETE,'https://jsonplaceholder.typicode.com/posts/5','');
}
 
// Put Request
void PutRequest;
{
  SendRequest(rmPUT,'https://jsonplaceholder.typicode.com/posts/1','{"id": 1, "title": "Updated", "body": "New data", "userId": 1}');
}
 
{
  MyForm = TCLForm.Create(Self);
 
  btnGet = MyForm.AddNewButton(MyForm,'btnGet','Get');
  btnGet.ALign = alMostTop;
  btnGet.Height = 50;
  MyForm.AddNewEvent(btnGet,tbeOnClick,'GetRequest');
 
  btnPost = MyForm.AddNewButton(MyForm,'btnPost','Post');
  btnPost.ALign = alMostTop;
  btnPost.Height = 50;
  MyForm.AddNewEvent(btnPost,tbeOnClick,'PostRequest');
 
  btnDelete = MyForm.AddNewButton(MyForm,'btnDelete','Delete');
  btnDelete.ALign = alMostTop;
  btnDelete.Height = 50;
  MyForm.AddNewEvent(btnDelete,tbeOnClick,'DeleteRequest');
 
  btnPut = MyForm.AddNewButton(MyForm,'btnPut','Put');
  btnPut.Align = alMostTop;
  btnPut.Height = 50;
  MyForm.AddNewEvent(btnPut,tbeOnClick,'PutRequest');
 
  Memo1 = MyForm.AddNewMemo(MyForm,'Memo1','--');
  Memo1.ALign = alTop;
  Memo1.Margins.Top = 10;
  Memo1.Height = (MyForm.clWidth / 3);
 
  MyForm.Run;
}
</pre>
 
<h3>Example 3 - OPENAI API CHATBOT</h3>
 
This code creates a chatbot using OpenAI's API. The user types their question into a text box (QuestionEdit) and presses the "Send" button to make a request to the OpenAI API. Once the API response is received, it is added to the message list (MsgList) and displayed on the screen. The requests are sent to OpenAI's chat/completions endpoint using the POST method through the TclRest object. User authorization is checked, and only certain profiles are allowed to send messages.<br>
 
 
<div class="alert alert-warning" role="alert" data-bs-theme="light">
To obtain an API key (token) from the OpenAI platform, you need to visit the [https://platform.openai.com/api-keys  OpenAI API Keys] page. After logging in, click the "Create new secret key" button to generate a new API key. You should store the generated key in a secure place, as it cannot be viewed again later. This key can be used for authentication when using the OpenAI APIs.<br>
 
<p style="color: red;">NOTE: OpenAI API keys are paid and subject to a usage quota.</p>
</div>
 
<pre>
var
  MainForm : TclForm;
  QuestionEdit : TclProEdit;
  SendButton : TClProButton;
  ChatPnl,MsjPnl:TclProPanel;
  MsgList:TclMemo;
  MainLyt : TClLayout;
  MainTitleLbl:TclLabel;
  strIncomingData : String;
  Rest: TclRest;
  API_KEY: string;
  RequestBody: string;
 
void ACompletedProc;
{
  //strIncomingData = Rest.Response;
  strIncomingData = Clomosy.CLParseJSON(Rest.Response,'choices.0.message.content');
  MsgList.Lines.Add(strIncomingData);
}
 
void RestCreate(ABaseUrl, token,ABody :String);
{
  Rest = TclRest.Create;
  Rest.Accept = 'application/json';
  Rest.ContentType = 'application/json';
  Rest.Method = rmPOST;
  Rest.ConnectTimeOut = 30000;
  Rest.BaseURL = ABaseUrl;
  Rest.AddHeader('Authorization',token);
  Rest.Body = ABody;
  Rest.OnCompleted = 'ACompletedProc';
  Rest.ExecuteAsync;
 
}
 
void BtnSendClick;
{
if ((Clomosy.AppUserProfile==1) && (QuestionEdit.Text <> ''))
{
  if QuestionEdit.Text <> ''
  {
    MsgList.Lines.Add(QuestionEdit.Text);
    MsgList.ScrollTo(0,MsgList.Lines.Count*MsgList.Lines.Count,True);
 
    API_KEY = 'token';  // Enter your own API key here.
      
      
     Button1 := Form1.AddNewButton(Form1,'Button1', 'Click');
     RequestBody = '{' +
    Form1.AddNewEvent(Button1, tbeOnClick, 'GetPostMethod');
  '  "model": "gpt-4-turbo",' +  // Change model if needed
   
  '  "messages": [' +
    clRest:=TCLRest.Create;
  '    {' +
   
  '      "role": "system",' +
    // Post
  '      "content": "You are a helpful assistant."' +
    clRest.BaseURL := 'https://dummyjson.com/auth/login';
  '    },' +
    clRest.Accept := 'application/json';
  '    {' +
    clRest.Method := rmPOST;
  '      "role": "user",' +
    clRest.AddBody('{"username":"kminchelle","password":"0lelplR"}','application/json');
  '      "content": "' + QuestionEdit.Text+ '"' +
   
  '    }' +
    //clRest.AddHeader('Content-Type','application/json');
  '  ],' +
      
  '  "temperature": 0.7' +  // Adjust creativity level
     /*
  '}';
     // Get
 
    clRest.BaseURL := 'https://dummyjson.com/auth/me';
    RestCreate('https://api.openai.com/v1/chat/completions' ,API_KEY,RequestBody);
    clRest.Accept := 'application/json';
    QuestionEdit.Text = '';
    clRest.Method := rmGET;
  } else
    clRest.AddHeader('Authorization','Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTUsInVzZXJuYW1lIjoia21pbmNoZWxsZSIsImVtYWlsIjoia21pbmNoZWxsZUBxcS5jb20iLCJmaXJzdE5hbWUiOiJKZWFubmUiLCJsYXN0TmFtZSI6IkhhbHZvcnNvbiIsImdlbmRlciI6ImZlbWFsZSIsImltYWdlIjoiaHR0cHM6Ly9yb2JvaGFzaC5vcmcvSmVhbm5lLnBuZz9zZXQ9c2V0NCIsImlhdCI6MTcxMTIwOTAwMSwiZXhwIjoxNzExMjEyNjAxfQ.F_ZCpi2qdv97grmWiT3h7HcT1prRJasQXjUR4Nk1yo8');
  {
    */
    ShowMessage('Please, ask a question!');
    Form1.Run;
  }
   end;
}
}
 
 
void SetMiddlePanel;
{
  MsjPnl=MainForm.AddNewProPanel(MainLyt,'MsjPnl');
  MsjPnl.Align = AlBottom;
  MsjPnl.Height = 100;
  MsjPnl.Margins.Top = 5;
  MsjPnl.Margins.Bottom = 20;
  MsjPnl.Margins.Left = 10;
  MsjPnl.Margins.Right = 10;
  MsjPnl.SetclProSettings(ChatPnl.clProSettings);
 
  QuestionEdit = MainForm.AddNewProEdit(MsjPnl,'QuestionEdit','Ask a question...');
  QuestionEdit.Align = AlClient;
  QuestionEdit.Margins.Left = 10;
  QuestionEdit.Margins.Right = 10;
  QuestionEdit.Margins.Top = 10;
  QuestionEdit.Margins.Bottom = 10;
  QuestionEdit.clProSettings.BorderColor = clAlphaColor.clHexToColor('#3bf5c0');
  QuestionEdit.clProSettings.FontHorzAlign = palLeading;
  QuestionEdit.clProSettings.BorderWidth = 1;
  QuestionEdit.clProSettings.IsRound = True;
  QuestionEdit.clProSettings.RoundHeight = 10;
  QuestionEdit.clProSettings.RoundWidth = 10;
  QuestionEdit.clProSettings.WordWrap = True;
  QuestionEdit.SetclProSettings(QuestionEdit.clProSettings);
 
  SendButton = MainForm.AddNewProButton(MsjPnl,'SendButton','Send');
  SendButton.Align = AlRight;
  SendButton.Width = MsjPnl.Width/4;
  SendButton.Margins.Bottom = 10;
  SendButton.Margins.Top = 10;
  SendButton.Margins.Right = 10;
  SendButton.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#1814F3');
  SendButton.clProSettings.FontColor = clAlphaColor.clHexToColor('#ffffff');
  SendButton.clProSettings.FontSize = 16;
  SendButton.clProSettings.TextSettings.Font.Style = [fsBold];
  SendButton.clProSettings.IsRound = True;
  SendButton.clProSettings.RoundHeight = 10;
  SendButton.clProSettings.RoundWidth = 10;
  SendButton.SetclProSettings(SendButton.clProSettings);
 
  MainForm.AddNewEvent(SendButton,tbeOnClick,'BtnSendClick');
}
 
void SetBigPanel;
{
  ChatPnl=MainForm.AddNewProPanel(MainLyt,'ChatPnl');
  ChatPnl.Align = AlClient;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Left = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.clProSettings.BorderColor = clAlphaColor.clHexToColor('#008000');
  ChatPnl.clProSettings.BorderWidth = 0;
  ChatPnl.clProSettings.IsRound = True;
  ChatPnl.clProSettings.RoundHeight = 5;
  ChatPnl.clProSettings.RoundWidth = 5;
  ChatPnl.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#f7f7f7');
  ChatPnl.SetclProSettings(ChatPnl.clProSettings);
 
  MsgList= MainForm.AddNewMemo(ChatPnl,'MsgList','');
  MsgList.Align = alClient;
  MsgList.ReadOnly = True;
  MsgList.Margins.Top= 20;
  MsgList.Margins.Left= 20;
  MsgList.Margins.Bottom= 20;
  MsgList.Margins.Right =20;
  MsgList.TextSettings.Font.Size=26;
  MsgList.TextSettings.WordWrap = True;
  MsgList.EnabledScroll = True;
}
 
void SetMainTitle;
{
  MainTitleLbl= MainForm.AddNewLabel(MainForm.LytTopBar,'MainTitleLbl',' Clomosy Artificial Intelligence');
  MainTitleLbl.StyledSettings = ssFamily;
  MainTitleLbl.TextSettings.Font.Size=20;
  MainTitleLbl.Align = alLeft;
  MainTitleLbl.Margins.Left= 14;
  MainTitleLbl.Margins.Top= 10;
  MainTitleLbl.Height = 65;
  MainTitleLbl.Width = 259;
}
 
{
  MainForm = TclForm.Create(Self);
  MainForm.BtnFormMenu.Visible = False;
  MainForm.FormWaiting.Visible = False;
 
  SetMainTitle;
 
  MainLyt = MainForm.AddNewLayout(MainForm,'MainLyt');
  MainLyt.Align=alClient;
  MainLyt.Margins.Bottom = 10;
  MainLyt.Margins.Top = 10;
 
  SetBigPanel;
  SetMiddlePanel;
 
  if (Clomosy.AppUserProfile == 1 )
  {
    SendButton.Enabled = True;
  }
  else
  {
     SendButton.Enabled = False;
     QuestionEdit.Text = 'Only the administrator can write.';
     QuestionEdit.Enabled = False;
  }
 
  MainForm.Run;
}
</pre>
 
 
 
<h3>Example 4 - GEMINI API CHATBOT</h3>
 
The code creates a chatbot using the Gemini API. The user types a question in a text box (QuestionEdit) and presses the "Send" button to make a request to the Gemini API. When the API response is received, it is added to the message list (MsgList) and displayed on the screen. Requests are sent using the POST method through the TclRest component to the Gemini chat/completion endpoint. User authorization is checked, and only certain profiles are allowed to send messages.<br>
 
 
<div class="alert alert-warning" role="alert" data-bs-theme="light">
To obtain an API key (token) from the Gemini platform, you need to visit the [https://aistudio.google.com Google AI Studio] page. After logging in, click the 'GET API key' button to create a new API key. Then, click the 'Create API key' button on the page to get a new key.
</div>
 
<pre>
var
  MainForm : TclForm;
  QuestionEdit : TclProEdit;
  SendButton : TClProButton;
  ChatPnl,MsjPnl:TclProPanel;
  MsgList:TclMemo;
  MainLyt : TClLayout;
  MainTitleLbl:TclLabel;
  MyMQTT : TclMQTT;
  strIncomingData : String;
  Rest: TclRest;
  API_KEY: string;
  RequestBody: string;
 
void ACompletedProc;
{
  //ShowMessage(Rest.Response); // The data returned from the POST request in JSON format via Gemini.
  strIncomingData = Clomosy.CLParseJSON(Rest.Response,'candidates.0.content.parts.0.text');
  MsgList.Lines.Add(strIncomingData);
  MyMQTT.Send(strIncomingData);
}
 
void RestCreate(ABaseUrl, ABody :String);
{
  Rest = TclRest.Create;
  Rest.Accept = 'application/json';
  Rest.ContentType = 'application/json'; // Content-Type
  Rest.Method = rmPOST;
  Rest.ConnectTimeOut = 30000;
  Rest.BaseURL = ABaseUrl; //'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + API_KEY
  Rest.Body = ABody;
  Rest.OnCompleted = 'ACompletedProc';
  Rest.ExecuteAsync;
    
}


:'''TRObject Syntax'''
void BtnSendClick;
   var
{
     Form1 : TclForm;  
if ((Clomosy.AppUserProfile==1) && (QuestionEdit.Text <> ''))
     clRest : TCLRest;
{
     Button1 : TCLButton;
  if QuestionEdit.Text <> ''
   {
     MyMQTT.Send(QuestionEdit.Text);
     MsgList.Lines.Add(QuestionEdit.Text);
     MsgList.ScrollTo(0,MsgList.Lines.Count*MsgList.Lines.Count,True);
    
    
   void GetPostMethod;
    API_KEY = 'token';  //  Enter your own API key here.
      // Generate the JSON data to be sent
      RequestBody = '{
      "contents": [
        {
          "parts": [
            {
              "text": "'+QuestionEdit.Text+'"
            }
          ]
        }
      ]
    }';
    RestCreate('https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + API_KEY,RequestBody);
    QuestionEdit.Text = '';
   } else
   {
   {
    clRest.Execute;
     ShowMessage('Please, ask a question!');
     ShowMessage(clRest.Response);
   }
   }
}
}
void MyMQTTPublishReceived;
{
  if (MyMQTT.ReceivedAlright )
  {
    if (Clomosy.AppUserProfile <> 1 )
    {
      MsgList.Lines.Add('');
      MsgList.Lines.Add(MyMQTT.ReceivedMessage);
      MsgList.ScrollTo(0,MsgList.Lines.Count*MsgList.Lines.Count,True);
    }
  }
}
void SetMiddlePanel;
{
  MsjPnl=MainForm.AddNewProPanel(MainLyt,'MsjPnl');
  MsjPnl.Align = AlBottom;
  MsjPnl.Height = 100;
  MsjPnl.Margins.Top = 5;
  MsjPnl.Margins.Bottom = 20;
  MsjPnl.Margins.Left = 10;
  MsjPnl.Margins.Right = 10;
  MsjPnl.SetclProSettings(ChatPnl.clProSettings);
 
  QuestionEdit = MainForm.AddNewProEdit(MsjPnl,'QuestionEdit','Ask a question...');
  QuestionEdit.Align = AlClient;
  QuestionEdit.Margins.Left = 10;
  QuestionEdit.Margins.Right = 10;
  QuestionEdit.Margins.Top = 10;
  QuestionEdit.Margins.Bottom = 10;
  QuestionEdit.clProSettings.BorderColor = clAlphaColor.clHexToColor('#3bf5c0');
  QuestionEdit.clProSettings.FontHorzAlign = palLeading;
  QuestionEdit.clProSettings.BorderWidth = 1;
  QuestionEdit.clProSettings.IsRound = True;
  QuestionEdit.clProSettings.RoundHeight = 10;
  QuestionEdit.clProSettings.RoundWidth = 10;
  QuestionEdit.clProSettings.WordWrap = True;
  QuestionEdit.SetclProSettings(QuestionEdit.clProSettings);
 
  SendButton = MainForm.AddNewProButton(MsjPnl,'SendButton','SEND');
  SendButton.Align = AlRight;
  SendButton.Width = MsjPnl.Width/4;
  SendButton.Margins.Bottom = 10;
  SendButton.Margins.Top = 10;
  SendButton.Margins.Right = 10;
  SendButton.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#1814F3');
  SendButton.clProSettings.FontColor = clAlphaColor.clHexToColor('#ffffff');
  SendButton.clProSettings.FontSize = 16;
  SendButton.clProSettings.TextSettings.Font.Style = [fsBold];
  SendButton.clProSettings.IsRound = True;
  SendButton.clProSettings.RoundHeight = 10;
  SendButton.clProSettings.RoundWidth = 10;
  SendButton.SetclProSettings(SendButton.clProSettings);
    
    
  MainForm.AddNewEvent(SendButton,tbeOnClick,'BtnSendClick');
}
void SetBigPanel;
{
  ChatPnl=MainForm.AddNewProPanel(MainLyt,'ChatPnl');
  ChatPnl.Align = AlClient;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Left = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.clProSettings.BorderColor = clAlphaColor.clHexToColor('#008000');
  ChatPnl.clProSettings.BorderWidth = 0;
  ChatPnl.clProSettings.IsRound = True;
  ChatPnl.clProSettings.RoundHeight = 5;
  ChatPnl.clProSettings.RoundWidth = 5;
  ChatPnl.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#f7f7f7');
  ChatPnl.SetclProSettings(ChatPnl.clProSettings);
 
  MsgList= MainForm.AddNewMemo(ChatPnl,'MsgList','');
  MsgList.Align = alClient;
  MsgList.ReadOnly = True;
  MsgList.Margins.Top= 20;
  MsgList.Margins.Left= 20;
  MsgList.Margins.Bottom= 20;
  MsgList.Margins.Right =20;
  MsgList.TextSettings.Font.Size=26;
  MsgList.TextSettings.WordWrap = True;
  MsgList.EnabledScroll = True;
}
void SetMainTitle;
{
  MainTitleLbl= MainForm.AddNewLabel(MainForm.LytTopBar,'MainTitleLbl',' Clomosy AI');
  MainTitleLbl.StyledSettings = ssFamily;
  MainTitleLbl.TextSettings.Font.Size=20;
  MainTitleLbl.Align = alLeft;
  MainTitleLbl.Margins.Left= 14;
  MainTitleLbl.Margins.Top= 10;
  MainTitleLbl.Height = 65;
  MainTitleLbl.Width = 259;
}
void VirtualKeyboardShow;
{
  MsjPnl.Margins.Bottom = MainForm.clVKBoundsHeight;
}
void VirtualKeyboardHidden;
{
  MsjPnl.Margins.Bottom = 0;
}
{
  MainForm = TclForm.Create(Self);
 
  SetMainTitle;
 
  MainLyt = MainForm.AddNewLayout(MainForm,'MainLyt');
  MainLyt.Align=alClient;
  MainLyt.Margins.Bottom = 10;
  MainLyt.Margins.Top = 10;
 
  SetBigPanel;
  SetMiddlePanel;
  MyMQTT = MainForm.AddNewMQTTConnection(MainForm,'MyMQTT');
  MainForm.AddNewEvent(MyMQTT,tbeOnMQTTPublishReceived,'MyMQTTPublishReceived');
  MyMQTT.Channel = 'ChatAI';
  MyMQTT.Connect;
 
  if (Clomosy.AppUserProfile == 1 )
  {
    SendButton.Enabled = True;
  }
  else
   {
   {
     Form1 = TclForm.Create(Self);
     SendButton.Enabled = False;
   
     QuestionEdit.Text = 'Only the administrator can write.';
    Button1 = Form1.AddNewButton(Form1,'Button1', 'Click');
     QuestionEdit.Enabled = False;
    Form1.AddNewEvent(Button1, tbeOnClick, 'GetPostMethod');
   
    clRest=TCLRest.Create;
      
    // Post
    clRest.BaseURL = 'https://dummyjson.com/auth/login';
    clRest.Accept = 'application/json';
     clRest.Method = rmPOST;
    clRest.AddBody('{"username":"kminchelle","password":"0lelplR"}','application/json');
   
    //clRest.AddHeader('Content-Type','application/json');
   
    /*
    // Get
    clRest.BaseURL = 'https://dummyjson.com/auth/me';
    clRest.Accept = 'application/json';
    clRest.Method = rmGET;
    clRest.AddHeader('Authorization','Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTUsInVzZXJuYW1lIjoia21pbmNoZWxsZSIsImVtYWlsIjoia21pbmNoZWxsZUBxcS5jb20iLCJmaXJzdE5hbWUiOiJKZWFubmUiLCJsYXN0TmFtZSI6IkhhbHZvcnNvbiIsImdlbmRlciI6ImZlbWFsZSIsImltYWdlIjoiaHR0cHM6Ly9yb2JvaGFzaC5vcmcvSmVhbm5lLnBuZz9zZXQ9c2V0NCIsImlhdCI6MTcxMTIwOTAwMSwiZXhwIjoxNzExMjEyNjAxfQ.F_ZCpi2qdv97grmWiT3h7HcT1prRJasQXjUR4Nk1yo8');
    */
    Form1.Run;
   }
   }
  MainForm.Run;
}
</pre>
<h2> See Also </h2>
* [[Components]]
* [[Object Properties]]
* [[AddNewEvent]]
{{#seo:|title=TclRest in Clomosy - Clomosy Docs}}
{{#seo:|description= Learn TclRest in Clomosy. Simplify data exchange in your mobile apps with robust REST API integrations for improved performance.}}

Latest revision as of 07:49, 7 April 2025

In Clomosy, the TclRest component is a component that facilitates interaction with RESTful services for data transfer. REST (Representational State Transfer) is a popular architecture for data transfer between web-based services.

With the TclRest component in Clomosy, you can easily communicate with such services and exchange data.

Using the TclRest component, you can make requests to a RESTful service (GET, POST, etc.), receive responses, and process these responses.

Feature Use of Definition
TclRest clRest : TclRest; An object of the TclRest class is defined.
Create clRest = TclRest.Create; A new TclRest object is created on the form.
BaseURL clRest.BaseURL = 'https://dummyjson.com/auth/login'; The URL address to access is given.
Resource clRest.Resource = 'users/123'; Defines the API path to be used after the base URL.
AddHeader clRest.AddHeader('Custom-Header', 'Value'); //Optional additional title
clRest.AddHeader('Authorization','Bearer your_api_key');
The specified header is added to the HTTP request. It takes two parameters: the first parameter is the header name, and the second parameter provides information about the media type of the data sent to the server.

In the example, the "Authorization" header is used to carry authentication information. The value of the 'Authorization' header usually contains a Bearer token. For example, a value like Bearer your_api_key is used. You should replace your_api_key with a valid API key or token.
Another example allows you to add your custom headers as well. In the example, we added a Custom-Header header and its corresponding value. This entirely depends on the requirements of the API.

ContentType clRest.ContentType = 'application/json';
ShowMessage(clRest.ContentType)
Specifies the content type of the data to be sent (e.g., application/json, application/x-www-form-urlencoded).
RemoveHeader clRest.RemoveHeader('Authorization'); Removes a previously added header.
Accept clRest.Accept = 'application/json'; // 'text/xml' etc. Specifies the media type the server will accept in the response. It is indicated that data will be received in JSON format in the example.

The Accept property also defaults to sending values in JSON format.

Method clRest.Method = rmPOST; //rmGET,rmPUT,rmDELETE

Specifies the type of HTTP request to be made. If you want to add new data to a resource or update an existing one with a POST request, you use rmPOST. If you want to retrieve the data of a resource with a GET request, you use rmGET.

Body clRest.Body = '{"name": "Jack", "age": 35}'; Contains the body data for the request (commonly used in POST and PUT requests).
ClearBody clRest.ClearBody; Clears the previously added request body.
FormDataBody clRest.FormDataBody = 'password=123456';
ShowMessage(clRest.FormDataBody);
ShowMessage(clRest.FormDataBody.Text);
Used in requests containing form data (multipart/form-data).
AddBody clRest.AddBody('{"username":"kminchelle","password":"0lelplR"}','application/json'); Adds the provided data to the body of the specified request. This body forms the part where the data is sent in requests like POST. The data specified in the request is transmitted to the server through this body. It takes two parameters. The first parameter specifies the data to be sent in the POST request body, and the second parameter indicates the media type of the sent data.
AddQuery clRest.AddQuery('id', '123'); Adds a parameter to the query string of a URL. For example, it is used to create a URL like https://api.example.com/users?id=123.
GetQuery QueryValue = clRest.GetQuery('id'); //QueryValue : String; Returns the query string parameter with the specified AKey value.
RemoveQuery clRest.RemoveQuery('id'); Removes a previously added query parameter.
AddUrlSegment clRest.Resource = 'users/{userId}';
clRest.AddUrlSegment('userId', '123');
It is used to dynamically insert variables into a URL. For example, it fills the {userId} variable in a URL template like https://api.example.com/users/{userId}.
RemoveUrlSegment clRest.RemoveUrlSegment('userId'); Removes a previously added URL segment variable.
Execute clRest.Execute; When this method is executed, the TclRest component performs the specified request and receives the response from the server. Executes the REST request synchronously. This means the code does not proceed until this function completes.
OnCompleted clRest.OnCompleted = CompletedProc; //CompletedProc : void Triggered when the ExecuteAsync operation is completed.
CompletedTrigger clRest.CompletedTrigger; Triggers the OnCompleted event when ExecuteAsync is completed.
ExecuteAsync clRest.OnCompleted = CompletedProc; //CompletedProc : void
clRest.ExecuteAsync;
Executes the REST request asynchronously (in the background). The code continues running, and an event is triggered when the operation is complete (therefore, the OnCompleted property should be defined beforehand).
Response ShowMessage(clRest.Response); You can access the details and content of the response from the server.
ClearParams clRest.ClearParams; Clears all previously added parameters (header, query, segment).
StatusCode ShowMessage(clRest.StatusCode); Returns the HTTP status code (200, 404, 500, etc.).
StatusText ShowMessage(clRest.StatusText); Returns the description of the HTTP status code (e.g., OK, Not Found, etc.).
ConnectTimeout clRest.ConnectTimeOut = 60000; Sets the connection timeout duration in milliseconds.
ResponseHeaders ShowMessage(clRest.ResponseHeaders.Text);
ShowMessage(clRest.ResponseHeaders.Count);
ShowMessage(clRest.ResponseHeaders[0]);
Contains the response headers returned from the server.
The Text property returns the response headers from the server.

The total number of received HTTP headers is shown by Count.
A specific HTTP header can be retrieved by specifying its index.

GetHeader HeaderValue = clRest.GetHeader('Content-Type'); //HeaderValue : String; Returns the HTTP header with the specified AKey value.
ProxyServer clRest.ProxyServer = '192.168.1.100'; Specifies the address of the proxy server to be used.
ProxyUsername clRest.ProxyUsername = 'myProxyUser'; Sets the username to be used when connecting to the proxy server.
ProxyPassword clRest.ProxyPassword = 'myProxyPass'; Sets the password required to connect to the proxy server if a proxy is being used.
ProxyPort clRest.ProxyPort = 8080; Sets the port number of the proxy server.

Example 1 - GET/POST

var
  Form1 : TclForm; 
  clRest : TCLRest;
  Button1 : TCLButton;

void GetPostMethod;
{
  clRest.Execute;
  ShowMessage(clRest.Response);
}

{
  Form1 = TclForm.Create(Self);
  
  Button1 = Form1.AddNewButton(Form1,'Button1', 'Click');
  Form1.AddNewEvent(Button1, tbeOnClick, 'GetPostMethod');
  
  clRest=TCLRest.Create;
  
  // Post
  
  clRest.BaseURL = 'https://jsonplaceholder.typicode.com/posts';
  clRest.Accept = 'application/json';
  clRest.Method = rmPOST;
  clRest.AddBody('{"name":"John","job":"Developer"}','application/json');
  //clRest.AddHeader('Content-Type','application/json');
  
  // Get
  /*
  clRest.BaseURL = 'https://jsonplaceholder.typicode.com/posts/1';
  clRest.Accept = 'application/json';
  clRest.Method = rmGET;
  clRest.AddHeader('Custom-Header', 'Value'); //Optional additional title
  //clRest.AddHeader('Authorization', 'Bearer your_api_key');
  
  */
  Form1.Run;
}

Example 2 - GET/POST/PUT/DELETE

This code creates a form and adds buttons to perform "GET, POST, PUT, and DELETE" operations, setting up a REST client. The "TclRest" object sends requests to a REST API, and the response is displayed in the "Memo1" component. The "SendRequest" procedure initiates an "asynchronous request" based on the specified HTTP method ("rmGET, rmPOST, rmPUT, rmDELETE"), URL, and optionally a JSON body. When a response is received, "CompletedProc" executes to update the Memo. Clicking the buttons triggers the corresponding request function, which directs the call to "SendRequest" and performs the API request.

var
  MyForm:TCLForm;
  btnGet, btnPost, btnDelete,btnPut : TclButton;
  RestClient: TclRest;
  Memo1 : TclMemo;

void CompletedProc;
{
  Memo1.Lines.Clear;
  Memo1.Lines.Add(RestClient.Response);
  
  RestClient.Free;
  RestClient = Nil;
}
  
void SendRequest(AMethod,AURL,ABody);
{
  RestClient = TclRest.Create;
  try
    try
      RestClient.Accept = 'application/json';
      RestClient.ContentType = 'application/json';
      RestClient.ConnectTimeOut = 60000;
      RestClient.BaseURL = AURL;
      if (ABody <> '')
        RestClient.Body = ABody;
      RestClient.Method = AMethod;
      RestClient.OnCompleted = 'CompletedProc';
      RestClient.ExecuteAsync;
    except
    ShowMessage('Exception Class: '+LastExceptionClassName+' Exception Message: '+LastExceptionMessage);
    }
  finally
  }
}

//  GET Request
void GetRequest;
{
  SendRequest(rmGet,'https://jsonplaceholder.typicode.com/posts/8','');
}

//  POST Request
void PostRequest;
{
  SendRequest(rmPost,'https://jsonplaceholder.typicode.com/posts','{"title": "Hello", "body": "This is a test", "userId": 1}');
}

//  DELETE Request
void DeleteRequest;
{
  SendRequest(rmDELETE,'https://jsonplaceholder.typicode.com/posts/5','');
}

// Put Request
void PutRequest;
{
  SendRequest(rmPUT,'https://jsonplaceholder.typicode.com/posts/1','{"id": 1, "title": "Updated", "body": "New data", "userId": 1}');
}

{
  MyForm = TCLForm.Create(Self);
  
  btnGet = MyForm.AddNewButton(MyForm,'btnGet','Get');
  btnGet.ALign = alMostTop;
  btnGet.Height = 50;
  MyForm.AddNewEvent(btnGet,tbeOnClick,'GetRequest');
  
  btnPost = MyForm.AddNewButton(MyForm,'btnPost','Post');
  btnPost.ALign = alMostTop;
  btnPost.Height = 50;
  MyForm.AddNewEvent(btnPost,tbeOnClick,'PostRequest');
  
  btnDelete = MyForm.AddNewButton(MyForm,'btnDelete','Delete');
  btnDelete.ALign = alMostTop;
  btnDelete.Height = 50;
  MyForm.AddNewEvent(btnDelete,tbeOnClick,'DeleteRequest');
  
  btnPut = MyForm.AddNewButton(MyForm,'btnPut','Put');
  btnPut.Align = alMostTop;
  btnPut.Height = 50;
  MyForm.AddNewEvent(btnPut,tbeOnClick,'PutRequest');
  
  Memo1 = MyForm.AddNewMemo(MyForm,'Memo1','--');
  Memo1.ALign = alTop;
  Memo1.Margins.Top = 10;
  Memo1.Height = (MyForm.clWidth / 3);
  
  MyForm.Run;
}

Example 3 - OPENAI API CHATBOT

This code creates a chatbot using OpenAI's API. The user types their question into a text box (QuestionEdit) and presses the "Send" button to make a request to the OpenAI API. Once the API response is received, it is added to the message list (MsgList) and displayed on the screen. The requests are sent to OpenAI's chat/completions endpoint using the POST method through the TclRest object. User authorization is checked, and only certain profiles are allowed to send messages.


var
  MainForm : TclForm;
  QuestionEdit : TclProEdit;
  SendButton : TClProButton;
  ChatPnl,MsjPnl:TclProPanel;
  MsgList:TclMemo;
  MainLyt : TClLayout;
  MainTitleLbl:TclLabel;
  strIncomingData : String;
  Rest: TclRest;
  API_KEY: string;
  RequestBody: string;

void ACompletedProc;
{
  //strIncomingData = Rest.Response;
  strIncomingData = Clomosy.CLParseJSON(Rest.Response,'choices.0.message.content');
  MsgList.Lines.Add(strIncomingData);
}

void RestCreate(ABaseUrl, token,ABody :String);
{
  Rest = TclRest.Create;
  Rest.Accept = 'application/json';
  Rest.ContentType = 'application/json';
  Rest.Method = rmPOST;
  Rest.ConnectTimeOut = 30000;
  Rest.BaseURL = ABaseUrl;
  Rest.AddHeader('Authorization',token);
  Rest.Body = ABody;
  Rest.OnCompleted = 'ACompletedProc';
  Rest.ExecuteAsync;
  
}

void BtnSendClick;
{
 if ((Clomosy.AppUserProfile==1) && (QuestionEdit.Text <> '')) 
 {
  if QuestionEdit.Text <> ''
  {
    MsgList.Lines.Add(QuestionEdit.Text);
    MsgList.ScrollTo(0,MsgList.Lines.Count*MsgList.Lines.Count,True);
  
    API_KEY = 'token';  // Enter your own API key here.
    
    RequestBody = '{' +
  '  "model": "gpt-4-turbo",' +  // Change model if needed
  '  "messages": [' +
  '    {' +
  '      "role": "system",' +
  '      "content": "You are a helpful assistant."' +
  '    },' +
  '    {' +
  '      "role": "user",' +
  '      "content": "' + QuestionEdit.Text+ '"' +
  '    }' +
  '  ],' +
  '  "temperature": 0.7' +  // Adjust creativity level
  '}';

    RestCreate('https://api.openai.com/v1/chat/completions' ,API_KEY,RequestBody);
    QuestionEdit.Text = '';
  } else
  {
    ShowMessage('Please, ask a question!');
  }
 }
}


void SetMiddlePanel;
{
  MsjPnl=MainForm.AddNewProPanel(MainLyt,'MsjPnl');
  MsjPnl.Align = AlBottom;
  MsjPnl.Height = 100;
  MsjPnl.Margins.Top = 5;
  MsjPnl.Margins.Bottom = 20;
  MsjPnl.Margins.Left = 10;
  MsjPnl.Margins.Right = 10;
  MsjPnl.SetclProSettings(ChatPnl.clProSettings);
  
  QuestionEdit = MainForm.AddNewProEdit(MsjPnl,'QuestionEdit','Ask a question...');
  QuestionEdit.Align = AlClient;
  QuestionEdit.Margins.Left = 10;
  QuestionEdit.Margins.Right = 10;
  QuestionEdit.Margins.Top = 10;
  QuestionEdit.Margins.Bottom = 10;
  QuestionEdit.clProSettings.BorderColor = clAlphaColor.clHexToColor('#3bf5c0');
  QuestionEdit.clProSettings.FontHorzAlign = palLeading;
  QuestionEdit.clProSettings.BorderWidth = 1;
  QuestionEdit.clProSettings.IsRound = True;
  QuestionEdit.clProSettings.RoundHeight = 10;
  QuestionEdit.clProSettings.RoundWidth = 10;
  QuestionEdit.clProSettings.WordWrap = True;
  QuestionEdit.SetclProSettings(QuestionEdit.clProSettings);
  
  SendButton = MainForm.AddNewProButton(MsjPnl,'SendButton','Send');
  SendButton.Align = AlRight;
  SendButton.Width = MsjPnl.Width/4;
  SendButton.Margins.Bottom = 10;
  SendButton.Margins.Top = 10;
  SendButton.Margins.Right = 10;
  SendButton.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#1814F3');
  SendButton.clProSettings.FontColor = clAlphaColor.clHexToColor('#ffffff');
  SendButton.clProSettings.FontSize = 16;
  SendButton.clProSettings.TextSettings.Font.Style = [fsBold];
  SendButton.clProSettings.IsRound = True;
  SendButton.clProSettings.RoundHeight = 10;
  SendButton.clProSettings.RoundWidth = 10;
  SendButton.SetclProSettings(SendButton.clProSettings);
  
  MainForm.AddNewEvent(SendButton,tbeOnClick,'BtnSendClick');
}

void SetBigPanel;
{
  ChatPnl=MainForm.AddNewProPanel(MainLyt,'ChatPnl');
  ChatPnl.Align = AlClient;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Left = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.clProSettings.BorderColor = clAlphaColor.clHexToColor('#008000');
  ChatPnl.clProSettings.BorderWidth = 0;
  ChatPnl.clProSettings.IsRound = True;
  ChatPnl.clProSettings.RoundHeight = 5;
  ChatPnl.clProSettings.RoundWidth = 5;
  ChatPnl.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#f7f7f7');
  ChatPnl.SetclProSettings(ChatPnl.clProSettings);
  
  MsgList= MainForm.AddNewMemo(ChatPnl,'MsgList','');
  MsgList.Align = alClient;
  MsgList.ReadOnly = True;
  MsgList.Margins.Top= 20;
  MsgList.Margins.Left= 20;
  MsgList.Margins.Bottom= 20;
  MsgList.Margins.Right =20;
  MsgList.TextSettings.Font.Size=26;
  MsgList.TextSettings.WordWrap = True;
  MsgList.EnabledScroll = True;
}

void SetMainTitle;
{
  MainTitleLbl= MainForm.AddNewLabel(MainForm.LytTopBar,'MainTitleLbl',' Clomosy Artificial Intelligence');
  MainTitleLbl.StyledSettings = ssFamily;
  MainTitleLbl.TextSettings.Font.Size=20;
  MainTitleLbl.Align = alLeft;
  MainTitleLbl.Margins.Left= 14;
  MainTitleLbl.Margins.Top= 10; 
  MainTitleLbl.Height = 65;
  MainTitleLbl.Width = 259;
}

{
  MainForm = TclForm.Create(Self);
  MainForm.BtnFormMenu.Visible = False;
  MainForm.FormWaiting.Visible = False;
  
  SetMainTitle;
  
  MainLyt = MainForm.AddNewLayout(MainForm,'MainLyt');
  MainLyt.Align=alClient;
  MainLyt.Margins.Bottom = 10;
  MainLyt.Margins.Top = 10;
  
  SetBigPanel;
  SetMiddlePanel;

  if (Clomosy.AppUserProfile == 1 )
  {
    SendButton.Enabled = True;
  }
  else
  {
    SendButton.Enabled = False;
    QuestionEdit.Text = 'Only the administrator can write.';
    QuestionEdit.Enabled = False;
  }

  MainForm.Run;
}


Example 4 - GEMINI API CHATBOT

The code creates a chatbot using the Gemini API. The user types a question in a text box (QuestionEdit) and presses the "Send" button to make a request to the Gemini API. When the API response is received, it is added to the message list (MsgList) and displayed on the screen. Requests are sent using the POST method through the TclRest component to the Gemini chat/completion endpoint. User authorization is checked, and only certain profiles are allowed to send messages.


var
  MainForm : TclForm;
  QuestionEdit : TclProEdit;
  SendButton : TClProButton;
  ChatPnl,MsjPnl:TclProPanel;
  MsgList:TclMemo;
  MainLyt : TClLayout;
  MainTitleLbl:TclLabel;
  MyMQTT : TclMQTT;
  strIncomingData : String;
  Rest: TclRest;
  API_KEY: string;
  RequestBody: string;

void ACompletedProc;
{
  //ShowMessage(Rest.Response); // The data returned from the POST request in JSON format via Gemini.
  strIncomingData = Clomosy.CLParseJSON(Rest.Response,'candidates.0.content.parts.0.text');
  MsgList.Lines.Add(strIncomingData);
  MyMQTT.Send(strIncomingData);
}

void RestCreate(ABaseUrl, ABody :String);
{
  Rest = TclRest.Create;
  Rest.Accept = 'application/json';
  Rest.ContentType = 'application/json'; // Content-Type
  Rest.Method = rmPOST;
  Rest.ConnectTimeOut = 30000;
  Rest.BaseURL = ABaseUrl; //'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + API_KEY
  Rest.Body = ABody;
  Rest.OnCompleted = 'ACompletedProc';
  Rest.ExecuteAsync;
  
}

void BtnSendClick;
{
 if ((Clomosy.AppUserProfile==1) && (QuestionEdit.Text <> '')) 
 {
  if QuestionEdit.Text <> ''
  {
    MyMQTT.Send(QuestionEdit.Text);
    MsgList.Lines.Add(QuestionEdit.Text);
    MsgList.ScrollTo(0,MsgList.Lines.Count*MsgList.Lines.Count,True);
  
    API_KEY = 'token';  //  Enter your own API key here.
      // Generate the JSON data to be sent
      RequestBody = '{
      "contents": [
        {
          "parts": [
            {
              "text": "'+QuestionEdit.Text+'"
            }
          ]
        }
      ]
    }';
    RestCreate('https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + API_KEY,RequestBody);
    QuestionEdit.Text = '';
  } else
  {
    ShowMessage('Please, ask a question!');
  }
 }
}

void MyMQTTPublishReceived;
{
  if (MyMQTT.ReceivedAlright ) 
  {
    if (Clomosy.AppUserProfile <> 1 )
    {
      MsgList.Lines.Add('');
      MsgList.Lines.Add(MyMQTT.ReceivedMessage);
      MsgList.ScrollTo(0,MsgList.Lines.Count*MsgList.Lines.Count,True);
    }
  }
}

void SetMiddlePanel;
{
  MsjPnl=MainForm.AddNewProPanel(MainLyt,'MsjPnl');
  MsjPnl.Align = AlBottom;
  MsjPnl.Height = 100;
  MsjPnl.Margins.Top = 5;
  MsjPnl.Margins.Bottom = 20;
  MsjPnl.Margins.Left = 10;
  MsjPnl.Margins.Right = 10;
  MsjPnl.SetclProSettings(ChatPnl.clProSettings);
  
  QuestionEdit = MainForm.AddNewProEdit(MsjPnl,'QuestionEdit','Ask a question...');
  QuestionEdit.Align = AlClient;
  QuestionEdit.Margins.Left = 10;
  QuestionEdit.Margins.Right = 10;
  QuestionEdit.Margins.Top = 10;
  QuestionEdit.Margins.Bottom = 10;
  QuestionEdit.clProSettings.BorderColor = clAlphaColor.clHexToColor('#3bf5c0');
  QuestionEdit.clProSettings.FontHorzAlign = palLeading;
  QuestionEdit.clProSettings.BorderWidth = 1;
  QuestionEdit.clProSettings.IsRound = True;
  QuestionEdit.clProSettings.RoundHeight = 10;
  QuestionEdit.clProSettings.RoundWidth = 10;
  QuestionEdit.clProSettings.WordWrap = True;
  QuestionEdit.SetclProSettings(QuestionEdit.clProSettings);
  
  SendButton = MainForm.AddNewProButton(MsjPnl,'SendButton','SEND');
  SendButton.Align = AlRight;
  SendButton.Width = MsjPnl.Width/4;
  SendButton.Margins.Bottom = 10;
  SendButton.Margins.Top = 10;
  SendButton.Margins.Right = 10;
  SendButton.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#1814F3');
  SendButton.clProSettings.FontColor = clAlphaColor.clHexToColor('#ffffff');
  SendButton.clProSettings.FontSize = 16;
  SendButton.clProSettings.TextSettings.Font.Style = [fsBold];
  SendButton.clProSettings.IsRound = True;
  SendButton.clProSettings.RoundHeight = 10;
  SendButton.clProSettings.RoundWidth = 10;
  SendButton.SetclProSettings(SendButton.clProSettings);
  
  MainForm.AddNewEvent(SendButton,tbeOnClick,'BtnSendClick');
}

void SetBigPanel;
{
  ChatPnl=MainForm.AddNewProPanel(MainLyt,'ChatPnl');
  ChatPnl.Align = AlClient;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Left = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.clProSettings.BorderColor = clAlphaColor.clHexToColor('#008000');
  ChatPnl.clProSettings.BorderWidth = 0;
  ChatPnl.clProSettings.IsRound = True;
  ChatPnl.clProSettings.RoundHeight = 5;
  ChatPnl.clProSettings.RoundWidth = 5;
  ChatPnl.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#f7f7f7');
  ChatPnl.SetclProSettings(ChatPnl.clProSettings);
  
  MsgList= MainForm.AddNewMemo(ChatPnl,'MsgList','');
  MsgList.Align = alClient;
  MsgList.ReadOnly = True;
  MsgList.Margins.Top= 20;
  MsgList.Margins.Left= 20;
  MsgList.Margins.Bottom= 20;
  MsgList.Margins.Right =20;
  MsgList.TextSettings.Font.Size=26;
  MsgList.TextSettings.WordWrap = True;
  MsgList.EnabledScroll = True;
}

void SetMainTitle;
{
  MainTitleLbl= MainForm.AddNewLabel(MainForm.LytTopBar,'MainTitleLbl',' Clomosy AI');
  MainTitleLbl.StyledSettings = ssFamily;
  MainTitleLbl.TextSettings.Font.Size=20;
  MainTitleLbl.Align = alLeft;
  MainTitleLbl.Margins.Left= 14;
  MainTitleLbl.Margins.Top= 10; 
  MainTitleLbl.Height = 65;
  MainTitleLbl.Width = 259;
}
 
void VirtualKeyboardShow;
{
  MsjPnl.Margins.Bottom = MainForm.clVKBoundsHeight;
}

void VirtualKeyboardHidden;
{
  MsjPnl.Margins.Bottom = 0;
}

{
  MainForm = TclForm.Create(Self);
  
  SetMainTitle;
  
  MainLyt = MainForm.AddNewLayout(MainForm,'MainLyt');
  MainLyt.Align=alClient;
  MainLyt.Margins.Bottom = 10;
  MainLyt.Margins.Top = 10;
  
  SetBigPanel;
  SetMiddlePanel;

  MyMQTT = MainForm.AddNewMQTTConnection(MainForm,'MyMQTT');
  MainForm.AddNewEvent(MyMQTT,tbeOnMQTTPublishReceived,'MyMQTTPublishReceived');
  MyMQTT.Channel = 'ChatAI';
  MyMQTT.Connect;
  
  if (Clomosy.AppUserProfile == 1 )
  {
    SendButton.Enabled = True;
  }
  else
  {
    SendButton.Enabled = False;
    QuestionEdit.Text = 'Only the administrator can write.';
    QuestionEdit.Enabled = False;
  }

  MainForm.Run;
}




See Also