Skip to content

Instantly share code, notes, and snippets.

@DelphiWorlds
Created August 7, 2022 22:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DelphiWorlds/87a3dd679b0385d7c0205c7e08fce3fb to your computer and use it in GitHub Desktop.
Save DelphiWorlds/87a3dd679b0385d7c0205c7e08fce3fb to your computer and use it in GitHub Desktop.
Get public IP address using IPify
// Inspired by:
// https://en.delphipraxis.net/topic/7258-printer-ip/?do=findComment&comment=61498
//
// Implemented in the simplest way I could think of that is also practical
// Note: This was thrown together in a few minutes, so please take care. Saving it as a Gist for posterity
uses
System.Net.HttpClient, System.JSON;
const
cIPifyURL = 'https://api.ipify.org/?format=json';
type
TPublicIPResponse = record
IP: string;
StatusCode: Integer;
StatusText: string;
end;
TPublicIPResponseMethod = reference to procedure(const Response: TPublicIPResponse);
TPublicIP = record
private
class procedure InternalGet(const AHandler: TPublicIPResponseMethod); static;
public
class procedure Get(const AHandler: TPublicIPResponseMethod); static;
end;
class procedure TPublicIP.Get(const AHandler: TPublicIPResponseMethod);
begin
TThread.CreateAnonymousThread(
procedure
begin
InternalGet(AHandler);
end
).Start;
end;
class procedure TPublicIP.InternalGet(const AHandler: TPublicIPResponseMethod);
var
LHTTP: THTTPClient;
LResponse: IHTTPResponse;
LPublicIPResponse: TPublicIPResponse;
LValue: TJSONValue;
begin
try
LPublicIPResponse.IP := '';
LHTTP := THTTPClient.Create;
try
LResponse := LHTTP.Get(cIPifyURL);
LPublicIPResponse.StatusCode := LResponse.StatusCode;
LPublicIPResponse.StatusText := LResponse.StatusText;
if LResponse.StatusCode = 200 then
begin
LValue := TJSONValue.ParseJSONValue(LResponse.ContentAsString);
if LValue <> nil then
try
LValue.TryGetValue('ip', LPublicIPResponse.IP);
finally
LValue.Free;
end;
end;
finally
LHTTP.Free;
end;
except
on E: Exception do
begin
LPublicIPResponse.StatusCode := 500;
LPublicIPResponse.StatusText := Format('%s: %s', [E.ClassName, E.Message]);
end;
end;
TThread.Synchronize(nil,
procedure
begin
AHandler(LPublicIPResponse);
end
);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled := False;
TPublicIP.Get(
procedure(const AResponse: TPublicIPResponse)
begin
Button1.Enabled := True;
if AResponse.StatusCode = 200 then
ShowMessage('Public IP is: ' + AResponse.IP)
else
ShowMessage('Error: ' + AResponse.StatusText);
end
);
end;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment