ttw_fmx_v10/Services/uAPIDA.pas

136 lines
4.0 KiB
Plaintext

unit uAPIDA;
interface
uses
system.Classes, system.SysUtils, System.JSON, IdHTTP, IdSSLOpenSSL, flog;
type
TAPIClient = class(TObject)
private
FHttpClient: TIdHTTP;
FSSLHandler: TIdSSLIOHandlerSocketOpenSSL;
FToken: string;
procedure SetToken(const Value: string);
procedure CheckHTTPError(AResponseCode: Integer; const AResponse: string);
public
constructor Create;
destructor Destroy; override;
function GetAccessToken(const client_id, client_secret, redirect_uri, code: string): string;
function GetUserInfo: TJSONObject;
function SubscribeToChannel(const uid, clientUID: string): TJSONObject;
property Token: string read FToken write SetToken;
end;
implementation
const
ContentType = 'application/x-www-form-urlencoded';
UserAgent = 'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
AuthorizationHeader = 'Authorization: Bearer ';
constructor TAPIClient.Create;
begin
inherited;
FHttpClient := TIdHTTP.Create(nil);
// ñîçäà¸ì SSL handler áåç âëàäåëüöà — ÿâíîå óïðàâëåíèå
FSSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
FSSLHandler.SSLOptions.Method := sslvSSLv23;
FHttpClient.IOHandler := FSSLHandler;
FHttpClient.Request.UserAgent := UserAgent;
FHttpClient.Request.ContentType := ContentType;
FHttpClient.HandleRedirects := True;
end;
destructor TAPIClient.Destroy;
begin
// Îòêëþ÷àåì è îñâîáîæäàåì â áåçîïàñíîì ïîðÿäêå
try
if Assigned(FHttpClient) then
begin
try
// åñëè íóæíî — ïðåðâàòü àêòèâíûå ñîåäèíåíèÿ
except
end;
end;
finally
// Ñíà÷àëà îñâîáîæäàåì IOHandler (åñëè îí íå ïðèíàäëåæèò FHttpClient)
FreeAndNil(FSSLHandler);
FreeAndNil(FHttpClient);
inherited;
end;
end;
procedure TAPIClient.CheckHTTPError(AResponseCode: Integer; const AResponse: string);
begin
if AResponseCode <> 200 then
raise Exception.CreateFmt('HTTP Error %d: %s', [AResponseCode, AResponse]);
end;
function TAPIClient.GetAccessToken(const client_id, client_secret, redirect_uri, code: string): string;
var
Response: string;
Stream: TStringStream;
Json: TJSONObject;
begin
Stream := TStringStream.Create(
Format('grant_type=authorization_code&client_id=%s&client_secret=%s&redirect_uri=%s&code=%s',
[client_id, client_secret, redirect_uri, code]), TEncoding.UTF8);
try
Response := FHttpClient.Post('https://www.donationalerts.com/oauth/token', Stream);
CheckHTTPError(FHttpClient.ResponseCode, Response);
Json := TJSONObject.ParseJSONValue(Response) as TJSONObject;
try
Result := Json.GetValue<string>('access_token');
FToken := Result;
finally
Json.Free;
end;
finally
Stream.Free;
end;
end;
function TAPIClient.GetUserInfo: TJSONObject;
var
Response: string;
begin
FHttpClient.Request.CustomHeaders.Add(AuthorizationHeader + FToken);
try
Response := FHttpClient.Get('https://www.donationalerts.com/api/v1/user/oauth');
CheckHTTPError(FHttpClient.ResponseCode, Response);
Result := TJSONObject.ParseJSONValue(Response) as TJSONObject;
finally
FHttpClient.Request.CustomHeaders.Clear;
end;
end;
function TAPIClient.SubscribeToChannel(const uid, clientUID: string): TJSONObject;
var
Response: string;
Stream: TStringStream;
RequestJSON: string;
begin
RequestJSON := Format('{"channels":["$alerts:donation_%s"], "client":"%s"}', [uid, clientUID]);
Stream := TStringStream.Create(RequestJSON, TEncoding.UTF8);
try
FHttpClient.Request.CustomHeaders.Add(AuthorizationHeader + FToken);
FHttpClient.Request.ContentType := 'application/json';
Response := FHttpClient.Post('https://www.donationalerts.com/api/v1/centrifuge/subscribe', Stream);
CheckHTTPError(FHttpClient.ResponseCode, Response);
Result := TJSONObject.ParseJSONValue(Response) as TJSONObject;
finally
Stream.Free;
FHttpClient.Request.CustomHeaders.Clear;
end;
end;
procedure TAPIClient.SetToken(const Value: string);
begin
FToken := Value;
end;
end.