unit uGigaChat;

interface

uses
  uChatAPI, SysUtils, IdHTTP, System.JSON, IdSSLOpenSSL, IdGlobal, classes;

type
  TGigaChat = class(TChatAPI)
  private
    ClientID: string;
    AutorizationCode: string;
    function getAPIKey: string;
    function GetTokenFromJson(jsonString: string): string;
  protected
    function GetOtvetFromJson(jsonString: string; isOllama:boolean = false): string; override;
  public
    constructor Create(Sender: TObject; aClientID: string; aAutorizationCode: string; aprefix: string = ''); reintroduce;
  end;

implementation

{ TGigaChat }

constructor TGigaChat.Create(Sender: TObject; aClientID: string; aAutorizationCode: string; aprefix: string = '');
var AT:string;
begin
ClientID := aClientID;
 AutorizationCode:=aAutorizationCode;
  AT:= getAPIKey;

  inherited Create(Sender, at, aprefix);

  // Дополнительная инициализация, если необходимо
end;

function TGigaChat.getAPIKey: string;
const
  url = 'https://ngw.devices.sberbank.ru:9443/api/v2/oauth';
var
  params: TStringStream;
  http: TIdHTTP;
  ssl: TIdSSLIOHandlerSocketOpenSSL;
begin
  http := TIdHTTP.Create(nil);
  ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  try
    http.IOHandler := ssl;
    ssl.SSLOptions.method := sslvSSLv23;
    http.Request.UserAgent :=
      'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
    http.Request.CustomHeaders.Clear;
    http.Request.CustomHeaders.Add
      ('Content-Type: application/x-www-form-urlencoded');
    http.Request.CustomHeaders.Add('Accept: application/json');
    http.Request.CustomHeaders.Add('RqUID: ' + ClientID);
    http.Request.CustomHeaders.Add('Authorization: Basic ' + AutorizationCode);
    params := TStringStream.Create(' scope=GIGACHAT_API_PERS');
    result := GetTokenFromJson(http.Post(url, params));
  finally
    params.Free;
    http.Free;
    ssl.Free;
  end;
end;


function TGigaChat.GetOtvetFromJson(jsonString: string; isOllama:boolean = false): string;
var
  JSON: TJSONObject;
  choicesArray: TJSONArray;
  choiceObject, messageObject: TJSONObject;
  JSONValue: TJSONValue;
begin
  Result := 'Произошла какая-то ошибка, попробуйте спрашивать по очереди!';
  JSON := TJSONObject.ParseJSONValue(jsonString) as TJSONObject;
  try
    if Assigned(JSON) then
    begin
      // Проверяем наличие ключа "choices"
      if JSON.TryGetValue('choices', JSONValue) then
      begin
        choicesArray := JSONValue as TJSONArray;
        if Assigned(choicesArray) and (choicesArray.Count > 0) then
        begin
          // Получаем первый элемент массива "choices"
          choiceObject := choicesArray.Items[0] as TJSONObject;
          if Assigned(choiceObject) then
          begin
            // Проверяем наличие ключа "message" в первом элементе "choices"
            if choiceObject.TryGetValue('message', JSONValue) then
            begin
              messageObject := JSONValue as TJSONObject;
              if Assigned(messageObject) then
              begin
                // Извлекаем значение "content" из объекта "message"
                Result := messageObject.GetValue<string>('content');
              end;
            end;
          end;
        end;
      end;
    end;
  finally
    JSON.Free;
  end;
end;

function TGigaChat.GetTokenFromJson(jsonString: string): string;
var
  JSON: TJSONObject;
  dataArray: TJSONString;
begin
  JSON := TJSONObject.ParseJSONValue(jsonString) as TJSONObject;
  try
    if Assigned(JSON) then
    begin
      if pos('access_token', jsonString) <> 0 then
      begin
        dataArray := JSON.GetValue('access_token') as TJSONString;
        if Assigned(dataArray) then
          Result := dataArray.GetValue<string>();
      end
      else
        Result := '';
    end;
  finally
    JSON.Free;
  end;
end;

end.
