From a7c2879ba1287be71860a71bc4ff6eae0b2c4bb1 Mon Sep 17 00:00:00 2001 From: Maxim Sysoev Date: Sun, 3 Dec 2017 23:13:25 +0200 Subject: [PATCH 01/14] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D1=81=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80=D0=BE=D0=BC=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D0=B5=D0=B3=D1=80=D0=B0=D0=BC=D0=B0=20=D0=B2?= =?UTF-8?q?=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/EchoBot/EchoBot.dproj | 496 +++++++++++++------------- Install/TelegaPi.dpk | 4 +- Install/TelegaPi.dproj | 384 ++++++++++---------- Source/TelegAPI.Bot.Impl.pas | 112 +----- Source/TelegAPI.Utils.Params.pas | 53 +-- Source/TelegAPi.CoreAPI.Parameter.pas | 32 ++ Source/TelegAPi.CoreAPI.Request.pas | 140 ++++++++ 7 files changed, 665 insertions(+), 556 deletions(-) create mode 100644 Source/TelegAPi.CoreAPI.Parameter.pas create mode 100644 Source/TelegAPi.CoreAPI.Request.pas diff --git a/Demo/EchoBot/EchoBot.dproj b/Demo/EchoBot/EchoBot.dproj index 5110a64..e47aaa7 100644 --- a/Demo/EchoBot/EchoBot.dproj +++ b/Demo/EchoBot/EchoBot.dproj @@ -14,48 +14,48 @@ true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true + true Cfg_1 true - true + true - true - Base true + Base + true - true + true Cfg_2 true - true + true - true + true Cfg_2 true - true + true true @@ -152,6 +152,10 @@
Main
fmx + + Cfg_2 + Base + Base @@ -159,10 +163,6 @@ Cfg_1 Base - - Cfg_2 - Base - Delphi.Personality.12 @@ -180,53 +180,54 @@ - - + + + ic_launcher.png true - - + + true - - + + + ic_launcher.png true - - + + + libEchoBot.so true - + ic_launcher.png true - - - ic_launcher.png + + true - + - ic_launcher.png + splash_image.png true - - - ic_launcher.png + + true - + - ic_launcher.png + splash_image.png true @@ -236,132 +237,118 @@ true - + splash_image.png true - - - splash_image.png + + true - + - splash_image.png + ic_launcher.png true - + libEchoBot.so true - - - libEchoBot.so + + + EchoBot.exe true - + + ic_launcher.png true - - + + true - + - classes.dex + libEchoBot.so true - + - libEchoBot.so true - + + classes.dex true - + true - - - EchoBot.exe + + true - + - Contents\MacOS 0 + .dll;.bpl - + 1 + .dylib Contents\MacOS 1 + .dylib - - - - classes - 1 - - - - - library\lib\armeabi-v7a + 1 + .dylib - - - - library\lib\armeabi + 1 + .dylib - - - library\lib\mips + + + Contents\Resources 1 - + - library\lib\armeabi-v7a + classes 1 - - - res\drawable - 1 + + + Contents\MacOS + 0 - - - - res\values + 1 - - - - res\drawable + + Contents\MacOS 1 @@ -371,65 +358,47 @@ 1 - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - + - res\drawable-hdpi + library\lib\mips 1 - - - res\drawable-xhdpi + + 1 - - - - res\drawable-small + 1 - - - - res\drawable-normal + 1 - - - res\drawable-large + + 1 - - - - res\drawable-xlarge + 1 - - 0 - + 1 Contents\MacOS 1 + + library\lib\armeabi-v7a + 1 + + + 1 + @@ -441,158 +410,170 @@ .framework - + - 0 - .dll;.bpl + 1 - + 1 - .dylib - - Contents\MacOS + + + 1 - .dylib - + 1 - .dylib - + 1 - .dylib - - - 0 - .bpl + + + 1 1 - .dylib - - Contents\MacOS + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - .dylib + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - .dylib - + + + + library\lib\armeabi 1 - .dylib - - - 0 + + + 1 - 0 - - - Contents\Resources\StartUp\ - 0 + 1 - 0 - - - 0 + 1 + + - 0 + 1 - - - + 1 - - - - ..\ + 1 - - - Contents + + + 0 + + 1 - - - Contents\Resources + Contents\MacOS 1 - + + + 1 + 1 1 - - 0 - - + + + + res\drawable-normal 1 - - Contents\MacOS + + + + res\drawable-large 1 + + - library\lib\armeabi-v7a + res\drawable-xhdpi 1 - + + + + Assets + 1 + + + Assets 1 - + + Assets 1 + Assets 1 - + - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + ..\ 1 - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + ..\ 1 - - + + + library\lib\armeabi-v7a 1 - + + + + res\drawable-hdpi 1 - - - ..\ + + + Contents 1 - + + + ..\ 1 - + 1 @@ -603,7 +584,13 @@ 1 - + + + res\values + 1 + + + 1 @@ -614,27 +601,19 @@ 1 - - - Assets - 1 - - - Assets + + + res\drawable-small 1 - - - Assets - 1 - - - Assets + + + res\drawable 1 - + 1 @@ -645,65 +624,86 @@ 1 - - - 1 - - + + 1 - + + + + res\drawable 1 - - - 1 + + + 0 - 1 + 0 + + + Contents\Resources\StartUp\ + 0 - 1 + 0 + + + 0 - - - 1 + 0 - + + + + library\lib\armeabi-v7a 1 - + + + + res\drawable-mdpi 1 - - - 1 + + + 0 + .bpl 1 + .dylib - + + Contents\MacOS 1 + .dylib - - - + 1 + .dylib - + 1 + .dylib - + + + + res\drawable-xlarge 1 - - + + + res\drawable-ldpi 1 + + 1 @@ -711,13 +711,13 @@ 1 - - - - - + + + + + diff --git a/Install/TelegaPi.dpk b/Install/TelegaPi.dpk index dab6d72..457f510 100644 --- a/Install/TelegaPi.dpk +++ b/Install/TelegaPi.dpk @@ -52,6 +52,8 @@ contains TelegAPI.Utils.Json in '..\Source\TelegAPI.Utils.Json.pas', TelegAPI.Utils.Params in '..\Source\TelegAPI.Utils.Params.pas', TelegAPI.Receiver.UI in '..\Source\TelegAPI.Receiver.UI.pas', - TelegaPi.Factory in '..\Source\TelegaPi.Factory.pas'; + TelegaPi.Factory in '..\Source\TelegaPi.Factory.pas', + TelegAPi.CoreAPI.Request in '..\Source\TelegAPi.CoreAPI.Request.pas', + TelegAPi.CoreAPI.Parameter in '..\Source\TelegAPi.CoreAPI.Parameter.pas'; end. diff --git a/Install/TelegaPi.dproj b/Install/TelegaPi.dproj index 0a16b75..48aac2f 100644 --- a/Install/TelegaPi.dproj +++ b/Install/TelegaPi.dproj @@ -14,35 +14,35 @@ true
- true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true - Base true + Base + true All @@ -57,10 +57,8 @@ false true true - - - + false TelegaPi @@ -123,7 +121,7 @@ $(PreBuildEvent)]]> - + @@ -132,6 +130,12 @@ $(PreBuildEvent)]]> + + + + Cfg_2 + Base + Base @@ -139,10 +143,6 @@ $(PreBuildEvent)]]> Cfg_1 Base - - Cfg_2 - Base - Delphi.Personality.12 @@ -169,12 +169,12 @@ $(PreBuildEvent)]]> true - + true - + true @@ -185,127 +185,83 @@ $(PreBuildEvent)]]> true - + - Contents\MacOS 0 + .dll;.bpl 1 + .dylib - - - classes - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi + + + Contents\Resources 1 - + - library\lib\mips + classes 1 - - - library\lib\armeabi-v7a - 1 + + + Contents\MacOS + 0 - - - - res\drawable + 1 - + - res\values + res\drawable-xxhdpi 1 - + - res\drawable + library\lib\mips 1 - - - res\drawable-xxhdpi + + 1 - - - - res\drawable-ldpi + 1 - - - - res\drawable-mdpi + 1 - - - res\drawable-hdpi + + 1 - - - - res\drawable-xhdpi + 1 - - - - res\drawable-small - 1 + + 0 - - - - res\drawable-normal + 1 - - - - res\drawable-large + 1 - - - res\drawable-xlarge + library\lib\armeabi-v7a 1 - - - - 0 - 1 - - 1 - @@ -316,124 +272,101 @@ $(PreBuildEvent)]]> .framework - + - 0 - .dll;.bpl + 1 - + 1 - .dylib - - - 0 - .bpl - - + + 1 - .dylib - + 1 - .dylib 1 - .dylib + + 1 - .dylib - - - - - 0 - 0 - - - 0 + 1 - 0 + 1 - - 0 + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 - - 0 + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 - + + library\lib\armeabi 1 - - - - - Contents\Resources + + + 1 - - 1 1 + + 0 - + 1 1 - - library\lib\armeabi-v7a - 1 - - - 1 - - - - 1 - - + + 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - - - - - + + + res\drawable-normal 1 - + + + + res\drawable-large 1 - + + + + res\drawable-xhdpi 1 @@ -457,18 +390,22 @@ $(PreBuildEvent)]]> 1 - - - 1 - - + + + + library\lib\armeabi-v7a 1 - + + + + res\drawable-hdpi 1 - + + + 1 @@ -479,6 +416,12 @@ $(PreBuildEvent)]]> 1 + + + res\values + 1 + + 1 @@ -490,7 +433,19 @@ $(PreBuildEvent)]]> 1 - + + + res\drawable-small + 1 + + + + + res\drawable + 1 + + + 1 @@ -501,46 +456,91 @@ $(PreBuildEvent)]]> 1 - - + + 1 - + + + + res\drawable 1 + + + + 0 + + + 0 + + + 0 + + 0 + + + 0 + + + 0 + + + + + library\lib\armeabi-v7a 1 - - + + + res\drawable-mdpi 1 + + + + 0 + .bpl + 1 + .dylib + + + 1 + .dylib 1 + .dylib - - 1 + .dylib - + + + + res\drawable-xlarge 1 - + + + + res\drawable-ldpi 1 - - - - + - + + + + + @@ -555,51 +555,51 @@ $(PreBuildEvent)]]> - - False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False + + False diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index 3fe7561..3487f8f 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -12,6 +12,7 @@ interface System.Net.HttpClient, System.Generics.Collections, TelegAPI.Base, + TelegAPi.CoreAPI.Parameter, TelegAPI.Bot, TelegAPI.Types, TelegAPI.Types.Impl, @@ -19,7 +20,6 @@ interface TelegAPI.Types.ReplyMarkups, TelegAPI.Types.InlineQueryResults, TelegAPI.Exceptions, - TelegAPI.Utils.Params, TelegAPI.Utils.Json, System.Json; @@ -31,7 +31,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) FToken: string; FProxySettings: TProxySettings; FOnRawData: TtgOnReceiveRawData; - FParamLoader: TtgParamLoader; FExceptionManager: ItgExceptionHandler; function GetToken: string; procedure SetToken(const Value: string); @@ -50,9 +49,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// /// Мастер-функция для запросов на сервак /// - function RequestAPI(const Method: string; const Parameters: TDictionary): string; - function SendDataToServer(const Method: string; const Parameters: TDictionary): string; - function ParamsToFormData(const Parameters: TDictionary): TMultipartFormData; + function RequestAPI(const Method: string; const Parameters: TDictionary): string; public function ApiTest(const ARequest: string; const Parameters: TDictionary = nil): string; constructor Create(AOwner: TComponent); overload; override; @@ -1925,6 +1922,7 @@ implementation uses REST.Json, + TelegAPi.CoreAPI, TelegAPI.Helpers; { TTelegramBot } {$REGION 'Core'} @@ -1932,26 +1930,32 @@ implementation constructor TTelegramBot.Create(AOwner: TComponent); begin inherited Create(AOwner); - FParamLoader := TtgParamLoader.Create; + end; destructor TTelegramBot.Destroy; begin - FParamLoader.Free; + inherited; end; function TTelegramBot.RequestAPI(const Method: string; const Parameters: TDictionary): string; var - LTextResponse: string; + LTgRequest: TtgApiRequest; begin - LTextResponse := SendDataToServer(Method, Parameters); - if Assigned(OnReceiveRawData) then - OnReceiveRawData(Self, LTextResponse); - if LTextResponse.IsEmpty then - ExceptionManager.HaveGlobalExeption('RequestAPI', ETelegramUnknownData.Create('Can''t parse response')) - else - Result := ApiTest(LTextResponse, Parameters); + LTgRequest := TtgApiRequest.Create(Self, Method); + try + LTgRequest.Parameters := Parameters; + Result := LTgRequest.Execute.ContentAsString(TEncoding.UTF8); + if Assigned(OnReceiveRawData) then + OnReceiveRawData(Self, Result); + if Result.IsEmpty then + ExceptionManager.HaveGlobalExeption('RequestAPI', ETelegramUnknownData.Create('Can''t parse response')) + else + Result := ApiTest(Result, Parameters); + finally + LTgRequest.Free; + end; end; function TTelegramBot.ApiTest(const ARequest: string; const Parameters: TDictionary): string; @@ -1975,84 +1979,6 @@ function TTelegramBot.ApiTest(const ARequest: string; const Parameters: TDiction end; end; -function TTelegramBot.ParamsToFormData(const Parameters: TDictionary): TMultipartFormData; -var - LParameter: TPair; - LAddProc: TtgParamLoader.TLoader; - LTest: string; -begin - Result := TMultipartFormData.Create; - for LParameter in Parameters do - begin - // skip all empty params - if LParameter.Value.IsEmpty then - Continue; - // look for the given parameter type - if FParamLoader.ParamLoaders.TryGetValue(LParameter.Value.TypeInfo, LAddProc) then - begin - LAddProc(Result, LParameter.Value.TypeInfo, LParameter.Key, LParameter.Value); - end - else if LParameter.Value.Kind = tkClass then - // last variant to search - begin - { TODO -oOwner -cGeneral : Проверить че за херня тут твориться } - if not LParameter.Value.IsEmpty then - begin - if LParameter.Value.IsTypethen - begin - LTest := TJson.ObjectToJsonString(LParameter.Value.AsObject); - Result.AddField(LParameter.Key, LTest); - end - else if Assigned(ExceptionManager) then - ExceptionManager.HaveGlobalExeption('TTelegramBot.ParamsToFormData', Exception.Create('Unknown object')) - else - raise Exception.Create('Error Message'); - end - end - else if Assigned(ExceptionManager) then - ExceptionManager.HaveGlobalExeption('ParamsToFormData', ETelegramDataConvert.Create('Check parameter type ' + LParameter.Value.ToString)) - else - raise ETelegramDataConvert.Create('Check parameter type ' + LParameter.Value.ToString); - end; -end; - -function TTelegramBot.SendDataToServer(const Method: string; const Parameters: TDictionary): string; -var - LHttp: THTTPClient; - LHttpResponse: IHTTPResponse; - LFullUrl: string; - LParamToDate: TMultipartFormData; -begin - LHttp := THTTPClient.Create; - LParamToDate := nil; - Result := string.Empty; - try - LHttp.ProxySettings := FProxySettings; - LFullUrl := 'https://api.telegram.org/bot' + FToken + '/' + Method; - try - if Assigned(Parameters) then - begin - LParamToDate := ParamsToFormData(Parameters); - LHttpResponse := LHttp.Post(LFullUrl, LParamToDate); - end - else - LHttpResponse := LHttp.Get(LFullUrl); - if LHttpResponse.StatusCode = 200 then - Result := LHttpResponse.ContentAsString(TEncoding.UTF8) - else - ExceptionManager.HaveGlobalExeption('SendDataToServer', EApiRequestException.Create(LHttpResponse.StatusText, LHttpResponse.StatusCode, Parameters)) - except - on E: Exception do - begin - ExceptionManager.HaveGlobalExeption('SendDataToServer', E); - end; - end; - finally - FreeAndNil(LParamToDate); - FreeAndNil(LHttp); - end; -end; - procedure TTelegramBot.SetToken(const Value: string); begin FToken := Value; diff --git a/Source/TelegAPI.Utils.Params.pas b/Source/TelegAPI.Utils.Params.pas index ce20a7c..3d2ccc6 100644 --- a/Source/TelegAPI.Utils.Params.pas +++ b/Source/TelegAPI.Utils.Params.pas @@ -8,29 +8,32 @@ interface System.rtti, System.SysUtils, System.TypInfo, - TelegAPI.Types; + TelegAPI.Types, + TelegAPi.CoreAPI; type /// /// This class is used by func. TTelegramBotCore.ParamsToFormData to locate /// suitable param loader for API request parameters preparation. /// - TtgParamLoader = class + TtgParamConverter = class public type //parameter loader method - TLoader = procedure(var AFormData: TMultipartFormData; TypeInfo: PTypeInfo; const AKey: string; AValue: TValue) of object; - public - ParamLoaders: TDictionary; + TLoader = procedure(var AFormData: TMultipartFormData; AParam: TtgApiParameter) of object; + private + FFormData: TMultipartFormData; protected - procedure AddInteger(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); - procedure AddString(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); - procedure AddInt64(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); - procedure AddBoolean(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); - procedure AddClass_TtgFileToSend(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); + procedure AddInteger(var AFormData: TMultipartFormData; AParam: TtgApiParameter); + procedure AddString(var AFormData: TMultipartFormData; AParam: TtgApiParameter); + procedure AddInt64(var AFormData: TMultipartFormData; AParam: TtgApiParameter); + procedure AddBoolean(var AFormData: TMultipartFormData; AParam: TtgApiParameter); + procedure AddClass_TtgFileToSend(var AFormData: TMultipartFormData; AParam: TtgApiParameter); public + ParamLoaders: TDictionary; constructor Create; destructor Destroy; override; + function ApplyParamToFormData(const AParam: TtgApiParameter; var Form: TMultipartFormData): Boolean; end; implementation @@ -38,22 +41,28 @@ implementation uses TelegAPI.Helpers; -procedure TtgParamLoader.AddInteger(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); +procedure TtgParamConverter.AddInteger(var AFormData: TMultipartFormData; AParam: TtgApiParameter); +begin + AFormData.AddField(AParam.Key, AParam.Value.AsInteger.ToString); +end; + +procedure TtgParamConverter.AddString(var AFormData: TMultipartFormData; AParam: TtgApiParameter); begin - if AValue.AsInteger <> 0 then - AFormData.AddField(AKey, AValue.AsInteger.ToString); + AFormData.AddField(AParam.Key, AParam.Value.AsString); end; -procedure TtgParamLoader.AddString(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); +function TtgParamConverter.ApplyParamToFormData(const AParam: TtgApiParameter; var Form: TMultipartFormData): Boolean; begin - if not AValue.AsString.IsEmpty then - AFormData.AddField(AKey, AValue.AsString); + Result := ParamLoaders.ContainsKey(AParam.Value.TypeInfo); + if not Result then + Exit; + ParamLoaders[AParam.Value.TypeInfo](Form, AParam); end; -constructor TtgParamLoader.Create; +constructor TtgParamConverter.Create; begin //init type-lookup dictionary - ParamLoaders := TDictionary.Create; + ParamLoaders := TDictionary.Create; //primitive types ParamLoaders.Add(PTypeInfo(TypeInfo(Integer)), AddInteger); ParamLoaders.Add(PTypeInfo(TypeInfo(string)), AddString); @@ -63,25 +72,25 @@ constructor TtgParamLoader.Create; ParamLoaders.Add(PTypeInfo(TypeInfo(TtgFileToSend)), AddClass_TtgFileToSend); end; -destructor TtgParamLoader.Destroy; +destructor TtgParamConverter.Destroy; begin ParamLoaders.Free; inherited; end; -procedure TtgParamLoader.AddInt64(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); +procedure TtgParamConverter.AddInt64(var AFormData: TMultipartFormData; AParam: TtgApiParameter); begin if AValue.AsInt64 <> 0 then AFormData.AddField(AKey, AValue.AsInt64.ToString); end; -procedure TtgParamLoader.AddBoolean(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); +procedure TtgParamConverter.AddBoolean(var AFormData: TMultipartFormData; AParam: TtgApiParameter); begin if AValue.AsBoolean then AFormData.AddField(AKey, AValue.AsBoolean.ToString(TUseBoolStrs.True)); end; -procedure TtgParamLoader.AddClass_TtgFileToSend(var AFormData: TMultipartFormData; ATypeInfo: PTypeInfo; const AKey: string; AValue: TValue); +procedure TtgParamConverter.AddClass_TtgFileToSend(var AFormData: TMultipartFormData; AParam: TtgApiParameter); var LFileToSent: TtgFileToSend; begin diff --git a/Source/TelegAPi.CoreAPI.Parameter.pas b/Source/TelegAPi.CoreAPI.Parameter.pas new file mode 100644 index 0000000..5e2c32f --- /dev/null +++ b/Source/TelegAPi.CoreAPI.Parameter.pas @@ -0,0 +1,32 @@ +unit TelegAPi.CoreAPI.Parameter; + +interface + +uses + System.Rtti; + +type + TtgApiParameter = class + Key: string; + Value: TValue; + DefaultValue: TValue; + Required: Boolean; + function IsDefaultValue: Boolean; + function Skip: Boolean; + end; + +implementation +{ TtgApiParameter } + +function TtgApiParameter.IsDefaultValue: Boolean; +begin + Result := Value.GetReferenceToRawData = DefaultValue.GetReferenceToRawData; +end; + +function TtgApiParameter.Skip: Boolean; +begin + Result := (not Required) and (IsDefaultValue or Value.IsEmpty); +end; + +end. + diff --git a/Source/TelegAPi.CoreAPI.Request.pas b/Source/TelegAPi.CoreAPI.Request.pas new file mode 100644 index 0000000..c196c71 --- /dev/null +++ b/Source/TelegAPi.CoreAPI.Request.pas @@ -0,0 +1,140 @@ +unit TelegAPi.CoreAPI.Request; + +interface + +uses + System.Rtti, + System.Net.HttpClient, + System.Generics.Collections, + System.Net.URLClient, + System.Net.Mime, + System.SysUtils, + TelegAPi.CoreAPI.Parameter, + TelegAPI.Bot.Impl; + +type + TtgApiRequest = class + private + const + SERVER_URL = 'https://api.telegram.org/bot'; + private + FMethod: string; + FParams: TObjectList; + FHttp: THTTPClient; + FOnReceive: TProc; + FTelega: TTelegramBot; + protected + function DoPost: IHTTPResponse; + function DoGet: IHTTPResponse; + procedure FillFormData(var AForm: TMultipartFormData); + public + constructor Create(Sender: TTelegramBot; const AMethod: string); + function Execute: IHttpResponse; + function GetUrl: string; + destructor Destroy; override; + property Parameters: TObjectList read FParams write FParams; + property OnReceive: TProc read FOnReceive write FOnReceive; + end; + +implementation + +uses + TelegAPi.Types, + TelegAPi.Types.ReplyMarkups, + REST.Json, + TelegaPi.Exceptions; + +{ TtgApiRequest } + +constructor TtgApiRequest.Create(Sender: TTelegramBot; const AMethod: string); +begin + FMethod := AMethod; + FTelega := Sender; + FParams := TObjectList.Create; + FHttp := THTTPClient.Create; +end; + +destructor TtgApiRequest.Destroy; +begin + FHttp.Free; + FParams.Free; + inherited; +end; + +function TtgApiRequest.DoGet: IHTTPResponse; +begin + Result := FHttp.Get(GetUrl); +end; + +function TtgApiRequest.DoPost: IHTTPResponse; +var + PostData: TMultiPartFormData; +begin + PostData := TMultiPartFormData.Create; + try + FillFormData(PostData); + Result := FHttp.Post(GetUrl, PostData); + finally + PostData.Free; + end; +end; + +function TtgApiRequest.Execute: IHttpResponse; +begin + FHttp.ProxySettings := FTelega.ProxySettings; + if Parameters.Count > 0 then + Result := DoPost + else + Result := DoGet; +end; + +procedure TtgApiRequest.FillFormData(var AForm: TMultipartFormData); +var + LParam: TtgApiParameter; +begin + for LParam in Parameters do + begin + // skip all empty params + if LParam.Skip then + Continue; + if LParam.Required and LParam.IsDefaultValue then + FTelega.ExceptionManager.HaveGlobalExeption('TtgApiRequest.FillFormData', ETelegramException.Create('Not assigned required data')); + if LParam.Value.IsTypethen + begin + AForm.AddField(LParam.Key, LParam.Value.AsString); + end + else if LParam.Value.IsTypethen // or Integer + begin + AForm.AddField(LParam.Key, LParam.Value.AsInt64.ToString); + end + else if LParam.Value.IsTypethen + begin + AForm.AddField(LParam.Key, LParam.Value.AsBoolean.ToString(TUseBoolStrs.True)); + end + else if LParam.Value.IsTypethen + begin + AForm.AddField(LParam.Key, LParam.Value.AsBoolean.ToString(TUseBoolStrs.True)); + end + else if LParam.Value.Kind = tkClass then // last variant to search + begin + { TODO -oOwner -cGeneral : } + if not LParam.Value.IsEmpty then + begin + if LParam.Value.IsTypethen + AForm.AddField(LParam.Key, TJson.ObjectToJsonString(LParam.Value.AsObject)) + else + FTelega.ExceptionManager.HaveGlobalExeption('TTelegramBot.ParamsToFormData', Exception.Create('Unknown object')); + end; + end + else + FTelega.ExceptionManager.HaveGlobalExeption('ParamsToFormData', ETelegramDataConvert.Create('Check parameter type ' + LParam.Value.ToString)) + end; +end; + +function TtgApiRequest.GetUrl: string; +begin + Result := SERVER_URL + FTelega.Token + '/' + FMethod; +end; + +end. + From fa1c5ae44d246f79d5c19b86d0ba29bb70d935b4 Mon Sep 17 00:00:00 2001 From: Sysoev Maxim Date: Mon, 4 Dec 2017 16:51:53 +0200 Subject: [PATCH 02/14] =?UTF-8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=81=D0=BA=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=20=D0=BD=D0=B0=20=D0=B0=D1=80=D0=B3=D1=83?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=85=20(=D0=BD=D0=B5=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BA=D0=BE=D0=BD=D1=87=D0=B8=D0=BB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/EchoBot/EchoBot.dproj | 496 +++++++++--------- Install/TelegaPi.dpk | 2 +- Install/TelegaPi.dproj | 382 +++++++------- Source/TelegAPI.Bot.Impl.pas | 414 ++++++--------- ...> TelegAPI.CoreAPI.ParameterConverter.pas} | 18 +- Source/TelegAPi.CoreAPI.Parameter.pas | 9 + Source/TelegAPi.CoreAPI.Request.pas | 8 +- 7 files changed, 621 insertions(+), 708 deletions(-) rename Source/{TelegAPI.Utils.Params.pas => TelegAPI.CoreAPI.ParameterConverter.pas} (86%) diff --git a/Demo/EchoBot/EchoBot.dproj b/Demo/EchoBot/EchoBot.dproj index e47aaa7..5110a64 100644 --- a/Demo/EchoBot/EchoBot.dproj +++ b/Demo/EchoBot/EchoBot.dproj @@ -14,48 +14,48 @@ true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true + true Cfg_1 true - true + true - true - Base true + Base + true - true + true Cfg_2 true - true + true - true + true Cfg_2 true - true + true true @@ -152,10 +152,6 @@
Main
fmx
- - Cfg_2 - Base - Base @@ -163,6 +159,10 @@ Cfg_1 Base + + Cfg_2 + Base + Delphi.Personality.12 @@ -180,54 +180,53 @@ - - - ic_launcher.png + + true - - + + true - - - ic_launcher.png + + true - - - libEchoBot.so + + true - + ic_launcher.png true - - + + + ic_launcher.png true - + - splash_image.png + ic_launcher.png true - - + + + ic_launcher.png true - + - splash_image.png + ic_launcher.png true @@ -237,60 +236,55 @@ true - + splash_image.png true - - + + + splash_image.png true - + - ic_launcher.png + splash_image.png true - + libEchoBot.so true - - - EchoBot.exe - true - - - + - ic_launcher.png + libEchoBot.so true - - + + true - + - libEchoBot.so true - + + classes.dex true - + - classes.dex + libEchoBot.so true @@ -304,51 +298,70 @@ true - + + + EchoBot.exe + true + + + + Contents\MacOS 0 - .dll;.bpl - + 1 - .dylib Contents\MacOS 1 - .dylib - + + + + classes 1 - .dylib - + + + + library\lib\armeabi-v7a 1 - .dylib - - - Contents\Resources + + + library\lib\armeabi 1 - + - classes + library\lib\mips 1 - - - Contents\MacOS - 0 + + + library\lib\armeabi-v7a + 1 - + + + + res\drawable 1 - - Contents\MacOS + + + + res\values + 1 + + + + + res\drawable 1 @@ -358,47 +371,65 @@ 1 - + - library\lib\mips + res\drawable-ldpi 1 - - + + + res\drawable-mdpi 1 - + + + + res\drawable-hdpi 1 - + + + + res\drawable-xhdpi 1 - - + + + res\drawable-small 1 - + + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge 1 + + 0 - + 1 Contents\MacOS 1 - - library\lib\armeabi-v7a - 1 - - - 1 - @@ -410,170 +441,158 @@ .framework - + - 1 - - - 1 + 0 + .dll;.bpl - - - + 1 + .dylib - + + Contents\MacOS 1 + .dylib 1 + .dylib - - 1 + .dylib - - 1 + + + + 0 + .bpl - + 1 + .dylib - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + + Contents\MacOS 1 + .dylib - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 + .dylib - - - - library\lib\armeabi + 1 + .dylib - - - 1 + + + 0 - 1 + 0 + + + Contents\Resources\StartUp\ + 0 - 1 + 0 - - - - 1 + + 0 - - 1 + + 0 - + + + 1 - - - 0 - - + + + ..\ 1 + + - Contents\MacOS + Contents 1 - - + + + Contents\Resources 1 + + 1 1 - - - - res\drawable-normal - 1 + + 0 - - - - res\drawable-large + 1 - - - - res\drawable-xhdpi + + Contents\MacOS 1 - - - - Assets + + library\lib\armeabi-v7a 1 - - Assets + 1 - + - Assets 1 - Assets 1 - + - ..\ + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - ..\ + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - - - library\lib\armeabi-v7a + + 1 - - - - res\drawable-hdpi + 1 - - - Contents + + + ..\ 1 - - - + ..\ 1 - + 1 @@ -584,13 +603,7 @@ 1 - - - res\values - 1 - - - + 1 @@ -601,19 +614,27 @@ 1 - - - res\drawable-small + + + Assets + 1 + + + Assets 1 - - - res\drawable + + + Assets + 1 + + + Assets 1 - + 1 @@ -624,86 +645,65 @@ 1 - - + + 1 - - - - res\drawable + + 1 + + 1 - - - 0 + + + 1 - 0 - - - Contents\Resources\StartUp\ - 0 + 1 - 0 - - - 0 + 1 + + - 0 + 1 - - - - library\lib\armeabi-v7a + 1 - - - - res\drawable-mdpi + 1 - - - 0 - .bpl - - + + 1 - .dylib - - Contents\MacOS + 1 - .dylib 1 - .dylib + + 1 - .dylib - - - - res\drawable-xlarge + 1 - - - - res\drawable-ldpi + 1 - + + + 1 + 1 @@ -711,13 +711,13 @@ 1 - - - + - - + + + + diff --git a/Install/TelegaPi.dpk b/Install/TelegaPi.dpk index 457f510..44f9caf 100644 --- a/Install/TelegaPi.dpk +++ b/Install/TelegaPi.dpk @@ -50,7 +50,7 @@ contains TelegAPi.Types in '..\Source\TelegAPi.Types.pas', TelegaPi.Types.ReplyMarkups in '..\Source\TelegaPi.Types.ReplyMarkups.pas', TelegAPI.Utils.Json in '..\Source\TelegAPI.Utils.Json.pas', - TelegAPI.Utils.Params in '..\Source\TelegAPI.Utils.Params.pas', + TelegAPI.CoreAPI.ParameterConverter in '..\Source\TelegAPI.CoreAPI.ParameterConverter.pas', TelegAPI.Receiver.UI in '..\Source\TelegAPI.Receiver.UI.pas', TelegaPi.Factory in '..\Source\TelegaPi.Factory.pas', TelegAPi.CoreAPI.Request in '..\Source\TelegAPi.CoreAPI.Request.pas', diff --git a/Install/TelegaPi.dproj b/Install/TelegaPi.dproj index 48aac2f..0dd20d7 100644 --- a/Install/TelegaPi.dproj +++ b/Install/TelegaPi.dproj @@ -14,35 +14,35 @@ true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true - Base true + Base + true All @@ -57,8 +57,10 @@ false true true - + + + false TelegaPi @@ -127,15 +129,11 @@ $(PreBuildEvent)]]> - + - - Cfg_2 - Base - Base @@ -143,6 +141,10 @@ $(PreBuildEvent)]]> Cfg_1 Base + + Cfg_2 + Base + Delphi.Personality.12 @@ -169,12 +171,12 @@ $(PreBuildEvent)]]> true - + true - + true @@ -185,20 +187,13 @@ $(PreBuildEvent)]]> true - + + Contents\MacOS 0 - .dll;.bpl 1 - .dylib - - - - - Contents\Resources - 1 @@ -207,18 +202,15 @@ $(PreBuildEvent)]]> 1 - - - Contents\MacOS - 0 - - + + + library\lib\armeabi-v7a 1 - + - res\drawable-xxhdpi + library\lib\armeabi 1 @@ -228,40 +220,94 @@ $(PreBuildEvent)]]> 1 - - + + + library\lib\armeabi-v7a 1 - + + + + res\drawable 1 - + + + + res\values 1 - - + + + res\drawable 1 - + + + + res\drawable-xxhdpi 1 - - 0 + + + + res\drawable-ldpi + 1 - + + + + res\drawable-mdpi 1 - + + + + res\drawable-hdpi 1 + + - library\lib\armeabi-v7a + res\drawable-xhdpi + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable-normal 1 + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + + + 0 + 1 + + 1 + @@ -272,101 +318,124 @@ $(PreBuildEvent)]]> .framework - + - 1 + 0 + .dll;.bpl - + 1 + .dylib - - - 1 + + + 0 + .bpl 1 + .dylib + + + 1 + .dylib 1 + .dylib - - 1 + .dylib + + + + + 0 - 1 + 0 + + + 0 - 1 + 0 - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 + + 0 - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 + + 0 - + - library\lib\armeabi 1 - - - + + + + + Contents\Resources 1 + + 1 1 - - 0 - + 1 1 - - + + library\lib\armeabi-v7a + 1 + 1 + + + + 1 + + + 1 + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - - - res\drawable-normal + + + + + 1 - - - - res\drawable-large + 1 - - - - res\drawable-xhdpi + 1 @@ -390,22 +459,18 @@ $(PreBuildEvent)]]> 1 - - - - library\lib\armeabi-v7a + + 1 - - - - res\drawable-hdpi + + 1 + + 1 - - - + 1 @@ -416,12 +481,6 @@ $(PreBuildEvent)]]> 1 - - - res\values - 1 - - 1 @@ -433,19 +492,7 @@ $(PreBuildEvent)]]> 1 - - - res\drawable-small - 1 - - - - - res\drawable - 1 - - - + 1 @@ -456,91 +503,46 @@ $(PreBuildEvent)]]> 1 - - - 1 - - - - - res\drawable + + 1 - - - - 0 - - 0 - - - 0 + 1 - 0 - - - 0 - - - 0 - - - - - library\lib\armeabi-v7a 1 - - - res\drawable-mdpi + + 1 - - - - 0 - .bpl - 1 - .dylib - - - 1 - .dylib 1 - .dylib + + 1 - .dylib - - - - res\drawable-xlarge + 1 - - - - res\drawable-ldpi + 1 - - - - + - - + + + + @@ -555,51 +557,51 @@ $(PreBuildEvent)]]> + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index 3487f8f..842d89e 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -12,7 +12,7 @@ interface System.Net.HttpClient, System.Generics.Collections, TelegAPI.Base, - TelegAPi.CoreAPI.Parameter, + TelegAPI.CoreAPI.Parameter, TelegAPI.Bot, TelegAPI.Types, TelegAPI.Types.Impl, @@ -35,25 +35,23 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) function GetToken: string; procedure SetToken(const Value: string); // Returns TJSONValue as method request result - function GetJSONFromMethod(const Method: string; const Parameters: TDictionary): TJSONValue; + function GetJSONFromMethod(const AValue: string): TJSONValue; // Returns TJSONArray as method request result - function GetJSONArrayFromMethod(const Method: string; const Parameters: TDictionary): TJSONArray; + function GetJSONArrayFromMethod(const AValue: string): TJSONArray; // Returns true when given Method executed successfully - function ExecuteMethod(const Method: string; const Parameters: TDictionary): Boolean; + function ExtractBool(const AValue: string): Boolean; // Returns response JSON from server as result of request - function GetArrayFromMethod(const TgClass: TBaseJsonClass; const Method: string; const Parameters: TDictionary): TArray; - function GetValueFromMethod(const Method: string; const Parameters: TDictionary): string; + function GetArrayFromMethod(const TgClass: TBaseJsonClass; const AValue: string): TArray; + function GetValueFromMethod(const AValue: string): string; function GetExceptionManager: ItgExceptionHandler; procedure SetExceptionManager(const Value: ItgExceptionHandler); protected /// /// Мастер-функция для запросов на сервак /// - function RequestAPI(const Method: string; const Parameters: TDictionary): string; + function RequestAPI(const Method: string; const Parameters: TArray): string; public - function ApiTest(const ARequest: string; const Parameters: TDictionary = nil): string; - constructor Create(AOwner: TComponent); overload; override; - destructor Destroy; override; + function ApiTest(const ARequest: string; const Parameters: TArray = nil): string; {$REGION 'Getting updates'} /// /// @@ -1298,7 +1296,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// function SendInvoice(// const ChatId: Int64; // - const title: string; // + const Title: string; // const Description: string; // const Payload: string; // const ProviderToken: string; // @@ -1834,7 +1832,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// function createNewStickerSet(// const UserId: Int64; // - const Name, title: string; // + const Name, Title: string; // const PngSticker: TValue; // const Emojis: string; // const ContainsMasks: Boolean = False; // @@ -1922,30 +1920,18 @@ implementation uses REST.Json, - TelegAPi.CoreAPI, - TelegAPI.Helpers; + TelegAPI.Helpers, + TelegAPI.CoreAPI.Request; { TTelegramBot } {$REGION 'Core'} -constructor TTelegramBot.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - -end; - -destructor TTelegramBot.Destroy; -begin - - inherited; -end; - -function TTelegramBot.RequestAPI(const Method: string; const Parameters: TDictionary): string; +function TTelegramBot.RequestAPI(const Method: string; const Parameters: TArray): string; var LTgRequest: TtgApiRequest; begin LTgRequest := TtgApiRequest.Create(Self, Method); try - LTgRequest.Parameters := Parameters; + LTgRequest.Parameters.AddRange(Parameters); Result := LTgRequest.Execute.ContentAsString(TEncoding.UTF8); if Assigned(OnReceiveRawData) then OnReceiveRawData(Self, Result); @@ -1958,7 +1944,7 @@ function TTelegramBot.RequestAPI(const Method: string; const Parameters: TDictio end; end; -function TTelegramBot.ApiTest(const ARequest: string; const Parameters: TDictionary): string; +function TTelegramBot.ApiTest(const ARequest: string; const Parameters: TArray): string; var FJSON: TJSONObject; begin @@ -1970,7 +1956,7 @@ function TTelegramBot.ApiTest(const ARequest: string; const Parameters: TDiction if FJSON.GetValue('ok') is TJSONFalse then if ExceptionManager <> nil then begin - ExceptionManager.HaveApiExeption('TTelegramBot.ApiTest', EApiRequestException.Create(ARequest, 0, Parameters)); + ExceptionManager.HaveApiExeption('TTelegramBot.ApiTest', EApiRequestException.Create(ARequest, 0)); Exit; end; Result := FJSON.GetValue('result').ToJSON; @@ -1979,44 +1965,21 @@ function TTelegramBot.ApiTest(const ARequest: string; const Parameters: TDiction end; end; -procedure TTelegramBot.SetToken(const Value: string); -begin - FToken := Value; -end; -{$ENDREGION} -{$REGION 'Getting updates'} - -function TTelegramBot.SetWebhook(const Url: string; const Certificate: TtgFileToSend; const MaxConnections: Int64; const AllowedUpdates: TAllowedUpdates): Boolean; -var - Parameters: TDictionary; -begin - Parameters := TDictionary.Create; - try - Parameters.Add('url', Url); - Parameters.Add('certificate', Certificate); - Parameters.Add('max_connections', MaxConnections); - Parameters.Add('allowed_updates', AllowedUpdates.ToString); - Result := ExecuteMethod('setWebhook', Parameters); - finally - Parameters.Free; - end; -end; - -function TTelegramBot.GetJSONFromMethod(const Method: string; const Parameters: TDictionary): TJSONValue; +function TTelegramBot.GetJSONFromMethod(const AValue: string): TJSONValue; begin - Result := TJSONObject.ParseJSONValue(RequestAPI(Method, Parameters)); + Result := TJSONObject.ParseJSONValue(AValue); end; -function TTelegramBot.GetJSONArrayFromMethod(const Method: string; const Parameters: TDictionary): TJSONArray; +function TTelegramBot.GetJSONArrayFromMethod(const AValue: string): TJSONArray; begin - Result := TJSONObject.ParseJSONValue(RequestAPI(Method, Parameters)) as TJSONArray; + Result := TJSONObject.ParseJSONValue(AValue) as TJSONArray; end; -function TTelegramBot.ExecuteMethod(const Method: string; const Parameters: TDictionary): Boolean; +function TTelegramBot.ExtractBool(const AValue: string): Boolean; var LJson: TJSONValue; begin - LJson := GetJSONFromMethod(Method, Parameters); + LJson := TJSONObject.ParseJSONValue(AValue); try Result := LJson is TJSONTrue; finally @@ -2024,11 +1987,11 @@ function TTelegramBot.ExecuteMethod(const Method: string; const Parameters: TDic end; end; -function TTelegramBot.GetValueFromMethod(const Method: string; const Parameters: TDictionary): string; +function TTelegramBot.GetValueFromMethod(const AValue: string): string; var LJson: TJSONValue; begin - LJson := GetJSONFromMethod(Method, Parameters); + LJson := GetJSONFromMethod(AValue); try Result := LJson.Value; finally @@ -2036,7 +1999,7 @@ function TTelegramBot.GetValueFromMethod(const Method: string; const Parameters: end; end; -function TTelegramBot.GetArrayFromMethod(const TgClass: TBaseJsonClass; const Method: string; const Parameters: TDictionary): TArray; +function TTelegramBot.GetArrayFromMethod(const TgClass: TBaseJsonClass; const AValue: string): TArray; var LJsonArr: TJSONArray; I: Integer; @@ -2049,239 +2012,199 @@ function TTelegramBot.GetArrayFromMethod(const TgClass: TBaseJsonClass; cons if TgClass.GetInterfaceEntry(GUID) = nil then raise Exception.Create('GetArrayFromMethod: unsupported interface for ' + TgClass.ClassName); // stage 2: proceed data - LJsonArr := GetJSONArrayFromMethod(Method, Parameters); + LJsonArr := GetJSONArrayFromMethod(AValue); if (not Assigned(LJsonArr)) or LJsonArr.Null then Exit(nil); try SetLength(Result, LJsonArr.Count); for I := 0 to High(Result) do - begin TgClass.GetTgClass.Create(LJsonArr.Items[I].ToJSON).GetInterface(GUID, Result[I]); - end; finally LJsonArr.Free; end; end; -function TTelegramBot.stopMessageLiveLocation(const ChatId: TValue; const MessageId: Int64; const ReplyMarkup: IReplyMarkup): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.GetToken: string; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := ExecuteMethod('stopMessageLiveLocation', Parameters); - finally - Parameters.Free; - end; + Result := FToken; end; -function TTelegramBot.stopMessageLiveLocation(const InlineMessageId: string; const ReplyMarkup: IReplyMarkup): Boolean; -var - Parameters: TDictionary; +procedure TTelegramBot.SetToken(const Value: string); begin - Parameters := TDictionary.Create; - try - Parameters.Add('inline_message_id', InlineMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := ExecuteMethod('stopMessageLiveLocation', Parameters); - finally - Parameters.Free; - end; + FToken := Value; +end; + +function TTelegramBot.GetExceptionManager: ItgExceptionHandler; +begin + if FExceptionManager = nil then + FExceptionManager := TtgExceptionManagerConsole.Create; + Result := FExceptionManager; +end; + +procedure TTelegramBot.SetExceptionManager(const Value: ItgExceptionHandler); +begin + FExceptionManager := Value; +end; +{$ENDREGION} +{$REGION 'Getting updates'} + +function TTelegramBot.SetWebhook(const Url: string; const Certificate: TtgFileToSend; const MaxConnections: Int64; const AllowedUpdates: TAllowedUpdates): Boolean; +begin + Result := ExtractBool(RequestAPI('setWebhook', [// + TtgApiParameter.Create('url', Url, '', True), // + TtgApiParameter.Create('certificate', Certificate, nil, False), // + TtgApiParameter.Create('max_connections', MaxConnections, 0, False), // + TtgApiParameter.Create('allowed_updates', AllowedUpdates.ToString, '[]', False) // + ])); end; function TTelegramBot.GetWebhookInfo: ItgWebhookInfo; begin - Result := TtgWebhookInfo.Create(GetJSONFromMethod('getWebhookInfo', nil).ToJSON); + Result := TtgWebhookInfo.Create(RequestAPI('getWebhookInfo', nil)); end; function TTelegramBot.GetUpdates(const Offset, Limit, Timeout: Int64; const AllowedUpdates: TAllowedUpdates): TArray; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('offset', Offset); - Parameters.Add('limit', Limit); - Parameters.Add('timeout', Timeout); - Parameters.Add('allowed_updates', AllowedUpdates.ToString); - Result := GetArrayFromMethod(TtgUpdate, 'getUpdates', Parameters); - finally - Parameters.Free; - end; + Result := GetArrayFromMethod(TtgUpdate, RequestAPI('getUpdates', [// + TtgApiParameter.Create('offset', Offset, 0, False), // + TtgApiParameter.Create('limit', Limit, 100, False), // + TtgApiParameter.Create('timeout', Timeout, 0, False), // + TtgApiParameter.Create('allowed_updates', AllowedUpdates.ToString, '[]', False) // + ])); end; function TTelegramBot.DeleteWebhook: Boolean; begin - Result := ExecuteMethod('deleteWebhook', nil); + Result := ExtractBool(RequestAPI('deleteWebhook', nil)); end; {$ENDREGION} {$REGION 'Basic methods'} +function TTelegramBot.stopMessageLiveLocation(const ChatId: TValue; const MessageId: Int64; const ReplyMarkup: IReplyMarkup): Boolean; +begin + Result := ExtractBool(RequestAPI('stopMessageLiveLocation', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, 0, True), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); +end; + +function TTelegramBot.stopMessageLiveLocation(const InlineMessageId: string; const ReplyMarkup: IReplyMarkup): Boolean; +begin + Result := ExtractBool(RequestAPI('stopMessageLiveLocation', [// + TtgApiParameter.Create('inline_message_id', InlineMessageId, '', True), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); +end; + function TTelegramBot.UnbanChatMember(const ChatId: TValue; const UserId: Int64): Boolean; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('user_id', UserId); - Result := ExecuteMethod('unbanChatMember', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('unbanChatMember', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('user_id', UserId, 0, True) // + ])); end; function TTelegramBot.SendLocation(const ChatId: TValue; const Location: TtgLocation; const LivePeriod: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('latitude', Location.Latitude); - Parameters.Add('longitude', Location.Longitude); - Parameters.Add('live_period', LivePeriod); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendLocation', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendLocation', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('latitude', Location.Latitude, 0.0, True), // + TtgApiParameter.Create('longitude', Location.Longitude, 0.0, True), // + TtgApiParameter.Create('live_period', LivePeriod, 0, False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.sendMediaGroup(const ChatId: TValue; const AMedia: TArray; const ADisableNotification: Boolean; const ReplyToMessageId: Int64): TArray; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('media', TJsonUtils.ArrayToJString(AMedia)); - Parameters.Add('disable_notification', ADisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Result := GetArrayFromMethod(TTgMessage, 'sendMediaGroup', Parameters); - finally - Parameters.Free; - end; + Result := GetArrayFromMethod(TTgMessage, RequestAPI('sendMediaGroup', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('media', TJsonUtils.ArrayToJString(AMedia), '[]', True), // + TtgApiParameter.Create('disable_notification', ADisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False) // + ])); end; function TTelegramBot.SendPhoto(const ChatId, Photo: TValue; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('photo', Photo); - Parameters.Add('caption', Caption); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendPhoto', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendPhoto', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('photo', Photo, '', True), // + TtgApiParameter.Create('caption', Caption, '', False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendSticker(const ChatId, Sticker: TValue; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('sticker', Sticker); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendSticker', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendSticker', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('sticker', Sticker, '', True), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendMessage(const ChatId: TValue; const Text: string; const ParseMode: TtgParseMode; const DisableWebPagePreview, DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('text', Text); - Parameters.Add('parse_mode', ParseMode.ToString); - Parameters.Add('disable_web_page_preview', DisableWebPagePreview); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendMessage', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendMessage', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('text', Text, '', True), // + TtgApiParameter.Create('parse_mode', ParseMode.ToString, '', False), // + TtgApiParameter.Create('disable_web_page_preview', DisableWebPagePreview, False, False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendVenue(const ChatId: TValue; const Venue: TtgVenue; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('latitude', Venue.Location.Latitude); - Parameters.Add('longitude', Venue.Location.Longitude); - Parameters.Add('title', Venue.title); - Parameters.Add('address', Venue.Address); - Parameters.Add('foursquare_id', Venue.FoursquareId); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendVenue', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendVenue', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('latitude', Venue.Location.Latitude, '', True), // + TtgApiParameter.Create('longitude', Venue.Location.Longitude, '', True), // + TtgApiParameter.Create('title', Venue.Title, '', True), // + TtgApiParameter.Create('address', Venue.Address, '', True), // + TtgApiParameter.Create('foursquare_id', Venue.FoursquareId, False, False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendVideo(const ChatId, Video: TValue; const Caption: string; const Duration, Width, Height: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('video', Video); - Parameters.Add('duration', Duration); - Parameters.Add('width', Width); - Parameters.Add('height', Height); - Parameters.Add('caption', Caption); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendVideo', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendVideo', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('video', Video, '', True), // + TtgApiParameter.Create('duration', Duration, 0, False), // + TtgApiParameter.Create('width', Width, 0, False), // + TtgApiParameter.Create('height', Height, 0, False), // + TtgApiParameter.Create('caption', Caption, '', False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendVideoNote(const ChatId, VideoNote: TValue; const Duration, Length: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - LParameters: TDictionary; begin - LParameters := TDictionary.Create; - try - LParameters.Add('chat_id', ChatId); - LParameters.Add('video_note', VideoNote); - LParameters.Add('duration', Duration); - LParameters.Add('length', Length); - LParameters.Add('disable_notification', DisableNotification); - LParameters.Add('reply_to_message_id', ReplyToMessageId); - LParameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendVoice', LParameters)); - finally - LParameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendVideoNote', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('video_note', VideoNote, '', True), // + TtgApiParameter.Create('duration', Duration, 0, False), // + TtgApiParameter.Create('length', Length, 0, False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendVoice(const ChatId, Voice: TValue; const Caption: string; const Duration: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; @@ -2324,17 +2247,11 @@ function TTelegramBot.SendAudio(const ChatId, Audio: TValue; const Caption: stri end; function TTelegramBot.SendChatAction(const ChatId: TValue; const Action: TtgSendChatAction): Boolean; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('action', Action.ToString); - Result := ExecuteMethod('sendChatAction', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('', [])); + Parameters.Add('chat_id', ChatId); + Parameters.Add('action', Action.ToString); + Result := ExecuteMethod('sendChatAction', Parameters); end; function TTelegramBot.SendContact(const ChatId: TValue; const Contact: TtgContact; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; @@ -2422,11 +2339,6 @@ function TTelegramBot.GetMe: ItgUser; Result := TtgUser.Create(RequestAPI('getMe', nil)); end; -function TTelegramBot.GetToken: string; -begin - Result := FToken; -end; - function TTelegramBot.getStickerSet(const Name: string): TtgStickerSet; var Parameters: TDictionary; @@ -2516,13 +2428,6 @@ function TTelegramBot.GetChatMembersCount(const ChatId: TValue): Int64; end; end; -function TTelegramBot.GetExceptionManager: ItgExceptionHandler; -begin - if FExceptionManager = nil then - FExceptionManager := TtgExceptionManagerConsole.Create; - Result := FExceptionManager; -end; - function TTelegramBot.GetFile(const FileId: string): ItgFile; var Parameters: TDictionary; @@ -3022,11 +2927,6 @@ function TTelegramBot.SetChatTitle(const ChatId: TValue; const Title: string): B end; end; -procedure TTelegramBot.SetExceptionManager(const Value: ItgExceptionHandler); -begin - FExceptionManager := Value; -end; - function TTelegramBot.UnpinChatMessage(const ChatId: TValue): Boolean; var Parameters: TDictionary; diff --git a/Source/TelegAPI.Utils.Params.pas b/Source/TelegAPI.CoreAPI.ParameterConverter.pas similarity index 86% rename from Source/TelegAPI.Utils.Params.pas rename to Source/TelegAPI.CoreAPI.ParameterConverter.pas index 3d2ccc6..d144c73 100644 --- a/Source/TelegAPI.Utils.Params.pas +++ b/Source/TelegAPI.CoreAPI.ParameterConverter.pas @@ -1,4 +1,4 @@ -unit TelegAPI.Utils.Params; +unit TelegAPI.CoreAPI.ParameterConverter; interface @@ -9,7 +9,7 @@ interface System.SysUtils, System.TypInfo, TelegAPI.Types, - TelegAPi.CoreAPI; + TelegAPi.CoreAPI.Parameter; type /// @@ -21,8 +21,6 @@ TtgParamConverter = class type //parameter loader method TLoader = procedure(var AFormData: TMultipartFormData; AParam: TtgApiParameter) of object; - private - FFormData: TMultipartFormData; protected procedure AddInteger(var AFormData: TMultipartFormData; AParam: TtgApiParameter); procedure AddString(var AFormData: TMultipartFormData; AParam: TtgApiParameter); @@ -80,25 +78,23 @@ destructor TtgParamConverter.Destroy; procedure TtgParamConverter.AddInt64(var AFormData: TMultipartFormData; AParam: TtgApiParameter); begin - if AValue.AsInt64 <> 0 then - AFormData.AddField(AKey, AValue.AsInt64.ToString); + AFormData.AddField(AParam.Key, AParam.Value.AsInt64.ToString); end; procedure TtgParamConverter.AddBoolean(var AFormData: TMultipartFormData; AParam: TtgApiParameter); begin - if AValue.AsBoolean then - AFormData.AddField(AKey, AValue.AsBoolean.ToString(TUseBoolStrs.True)); + AFormData.AddField(AParam.Key, AParam.Value.AsBoolean.ToString(TUseBoolStrs.True)); end; procedure TtgParamConverter.AddClass_TtgFileToSend(var AFormData: TMultipartFormData; AParam: TtgApiParameter); var LFileToSent: TtgFileToSend; begin - LFileToSent := AValue.AsType; + LFileToSent := AParam.Value.AsType; if Assigned(LFileToSent.Content) then - AFormData.AddStream(AKey, LFileToSent.Content, LFileToSent.FileName) + AFormData.AddStream(AParam.Key, LFileToSent.Content, LFileToSent.FileName) else - AFormData.AddFile(AKey, LFileToSent.FileName); + AFormData.AddFile(AParam.Key, LFileToSent.FileName); end; end. diff --git a/Source/TelegAPi.CoreAPI.Parameter.pas b/Source/TelegAPi.CoreAPI.Parameter.pas index 5e2c32f..0104087 100644 --- a/Source/TelegAPi.CoreAPI.Parameter.pas +++ b/Source/TelegAPi.CoreAPI.Parameter.pas @@ -13,11 +13,20 @@ TtgApiParameter = class Required: Boolean; function IsDefaultValue: Boolean; function Skip: Boolean; + constructor Create(const AKey: string; AValue, ADefaultValue: TValue; ARequired: Boolean = False); end; implementation { TtgApiParameter } +constructor TtgApiParameter.Create(const AKey: string; AValue, ADefaultValue: TValue; ARequired: Boolean); +begin + Key := AKey; + Value := AValue; + DefaultValue := ADefaultValue; + Required := ARequired; +end; + function TtgApiParameter.IsDefaultValue: Boolean; begin Result := Value.GetReferenceToRawData = DefaultValue.GetReferenceToRawData; diff --git a/Source/TelegAPi.CoreAPI.Request.pas b/Source/TelegAPi.CoreAPI.Request.pas index c196c71..af5feda 100644 --- a/Source/TelegAPi.CoreAPI.Request.pas +++ b/Source/TelegAPi.CoreAPI.Request.pas @@ -30,6 +30,7 @@ TtgApiRequest = class public constructor Create(Sender: TTelegramBot; const AMethod: string); function Execute: IHttpResponse; + function ExecuteAsString: string; function GetUrl: string; destructor Destroy; override; property Parameters: TObjectList read FParams write FParams; @@ -88,6 +89,11 @@ function TtgApiRequest.Execute: IHttpResponse; Result := DoGet; end; +function TtgApiRequest.ExecuteAsString: string; +begin + Result := Execute.ContentAsString(TEncoding.UTF8); +end; + procedure TtgApiRequest.FillFormData(var AForm: TMultipartFormData); var LParam: TtgApiParameter; @@ -97,7 +103,7 @@ procedure TtgApiRequest.FillFormData(var AForm: TMultipartFormData); // skip all empty params if LParam.Skip then Continue; - if LParam.Required and LParam.IsDefaultValue then + if LParam.Required and (LParam.IsDefaultValue or LParam.Value.IsEmpty) then FTelega.ExceptionManager.HaveGlobalExeption('TtgApiRequest.FillFormData', ETelegramException.Create('Not assigned required data')); if LParam.Value.IsTypethen begin From fd4b540593e3f764d583b332f74c0523f4b91e87 Mon Sep 17 00:00:00 2001 From: Maxim Sysoev Date: Mon, 4 Dec 2017 23:19:12 +0200 Subject: [PATCH 03/14] =?UTF-8?q?[=20wip=20]=20=D0=A0=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=20=D1=81=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BE=D0=BC=20=D1=82=D0=B5=D0=BB=D0=B5=D0=B3=D1=80=D0=B0=D0=BC?= =?UTF-8?q?=D0=B0=20=D0=B2=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=BE=D0=BC=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/EchoBot/EchoBot.dproj | 496 +++++++++++++++++------------------ Install/TelegaPi.dproj | 380 +++++++++++++-------------- Source/TelegAPI.Bot.Impl.pas | 187 +++++-------- 3 files changed, 499 insertions(+), 564 deletions(-) diff --git a/Demo/EchoBot/EchoBot.dproj b/Demo/EchoBot/EchoBot.dproj index 5110a64..e47aaa7 100644 --- a/Demo/EchoBot/EchoBot.dproj +++ b/Demo/EchoBot/EchoBot.dproj @@ -14,48 +14,48 @@ true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true + true Cfg_1 true - true + true - true - Base true + Base + true - true + true Cfg_2 true - true + true - true + true Cfg_2 true - true + true true @@ -152,6 +152,10 @@
Main
fmx + + Cfg_2 + Base + Base @@ -159,10 +163,6 @@ Cfg_1 Base - - Cfg_2 - Base - Delphi.Personality.12 @@ -180,53 +180,54 @@ - - + + + ic_launcher.png true - - + + true - - + + + ic_launcher.png true - - + + + libEchoBot.so true - + ic_launcher.png true - - - ic_launcher.png + + true - + - ic_launcher.png + splash_image.png true - - - ic_launcher.png + + true - + - ic_launcher.png + splash_image.png true @@ -236,132 +237,118 @@ true - + splash_image.png true - - - splash_image.png + + true - + - splash_image.png + ic_launcher.png true - + libEchoBot.so true - - - libEchoBot.so + + + EchoBot.exe true - + + ic_launcher.png true - - + + true - + - classes.dex + libEchoBot.so true - + - libEchoBot.so true - + + classes.dex true - + true - - - EchoBot.exe + + true - + - Contents\MacOS 0 + .dll;.bpl - + 1 + .dylib Contents\MacOS 1 + .dylib - - - - classes - 1 - - - - - library\lib\armeabi-v7a + 1 + .dylib - - - - library\lib\armeabi + 1 + .dylib - - - library\lib\mips + + + Contents\Resources 1 - + - library\lib\armeabi-v7a + classes 1 - - - res\drawable - 1 + + + Contents\MacOS + 0 - - - - res\values + 1 - - - - res\drawable + + Contents\MacOS 1 @@ -371,65 +358,47 @@ 1 - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - + - res\drawable-hdpi + library\lib\mips 1 - - - res\drawable-xhdpi + + 1 - - - - res\drawable-small + 1 - - - - res\drawable-normal + 1 - - - res\drawable-large + + 1 - - - - res\drawable-xlarge + 1 - - 0 - + 1 Contents\MacOS 1 + + library\lib\armeabi-v7a + 1 + + + 1 + @@ -441,158 +410,170 @@ .framework - + - 0 - .dll;.bpl + 1 - + 1 - .dylib - - Contents\MacOS + + + 1 - .dylib - + 1 - .dylib - + 1 - .dylib - - - 0 - .bpl + + + 1 1 - .dylib - - Contents\MacOS + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - .dylib + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - .dylib - + + + + library\lib\armeabi 1 - .dylib - - - 0 + + + 1 - 0 - - - Contents\Resources\StartUp\ - 0 + 1 - 0 - - - 0 + 1 + + - 0 + 1 - - - + 1 - - - - ..\ + 1 - - - Contents + + + 0 + + 1 - - - Contents\Resources + Contents\MacOS 1 - + + + 1 + 1 1 - - 0 - - + + + + res\drawable-normal 1 - - Contents\MacOS + + + + res\drawable-large 1 + + - library\lib\armeabi-v7a + res\drawable-xhdpi 1 - + + + + Assets + 1 + + + Assets 1 - + + Assets 1 + Assets 1 - + - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + ..\ 1 - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + ..\ 1 - - + + + library\lib\armeabi-v7a 1 - + + + + res\drawable-hdpi 1 - - - ..\ + + + Contents 1 - + + + ..\ 1 - + 1 @@ -603,7 +584,13 @@ 1 - + + + res\values + 1 + + + 1 @@ -614,27 +601,19 @@ 1 - - - Assets - 1 - - - Assets + + + res\drawable-small 1 - - - Assets - 1 - - - Assets + + + res\drawable 1 - + 1 @@ -645,65 +624,86 @@ 1 - - - 1 - - + + 1 - + + + + res\drawable 1 - - - 1 + + + 0 - 1 + 0 + + + Contents\Resources\StartUp\ + 0 - 1 + 0 + + + 0 - - - 1 + 0 - + + + + library\lib\armeabi-v7a 1 - + + + + res\drawable-mdpi 1 - - - 1 + + + 0 + .bpl 1 + .dylib - + + Contents\MacOS 1 + .dylib - - - + 1 + .dylib - + 1 + .dylib - + + + + res\drawable-xlarge 1 - - + + + res\drawable-ldpi 1 + + 1 @@ -711,13 +711,13 @@ 1 - - - - - + + + + + diff --git a/Install/TelegaPi.dproj b/Install/TelegaPi.dproj index 0dd20d7..c64b504 100644 --- a/Install/TelegaPi.dproj +++ b/Install/TelegaPi.dproj @@ -14,35 +14,35 @@ true
- true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true - Base true + Base + true All @@ -57,10 +57,8 @@ false true true - - - + false TelegaPi @@ -134,6 +132,10 @@ $(PreBuildEvent)]]> + + Cfg_2 + Base + Base @@ -141,10 +143,6 @@ $(PreBuildEvent)]]> Cfg_1 Base - - Cfg_2 - Base - Delphi.Personality.12 @@ -171,12 +169,12 @@ $(PreBuildEvent)]]> true - + true - + true @@ -187,127 +185,83 @@ $(PreBuildEvent)]]> true - + - Contents\MacOS 0 + .dll;.bpl 1 + .dylib - - - classes - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi + + + Contents\Resources 1 - + - library\lib\mips + classes 1 - - - library\lib\armeabi-v7a - 1 + + + Contents\MacOS + 0 - - - - res\drawable + 1 - + - res\values + res\drawable-xxhdpi 1 - + - res\drawable + library\lib\mips 1 - - - res\drawable-xxhdpi + + 1 - - - - res\drawable-ldpi + 1 - - - - res\drawable-mdpi + 1 - - - res\drawable-hdpi + + 1 - - - - res\drawable-xhdpi + 1 - - - - res\drawable-small - 1 + + 0 - - - - res\drawable-normal + 1 - - - - res\drawable-large + 1 - - - res\drawable-xlarge + library\lib\armeabi-v7a 1 - - - - 0 - 1 - - 1 - @@ -318,124 +272,101 @@ $(PreBuildEvent)]]> .framework - + - 0 - .dll;.bpl + 1 - + 1 - .dylib - - - 0 - .bpl - - + + 1 - .dylib - + 1 - .dylib 1 - .dylib + + 1 - .dylib - - - - - 0 - 0 - - - 0 + 1 - 0 + 1 - - 0 + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 - - 0 + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 - + + library\lib\armeabi 1 - - - - - Contents\Resources + + + 1 - - 1 1 + + 0 - + 1 1 - - library\lib\armeabi-v7a - 1 - - - 1 - - - - 1 - - + + 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - - - - - + + + res\drawable-normal 1 - + + + + res\drawable-large 1 - + + + + res\drawable-xhdpi 1 @@ -459,18 +390,22 @@ $(PreBuildEvent)]]> 1 - - - 1 - - + + + + library\lib\armeabi-v7a 1 - + + + + res\drawable-hdpi 1 - + + + 1 @@ -481,6 +416,12 @@ $(PreBuildEvent)]]> 1 + + + res\values + 1 + + 1 @@ -492,7 +433,19 @@ $(PreBuildEvent)]]> 1 - + + + res\drawable-small + 1 + + + + + res\drawable + 1 + + + 1 @@ -503,46 +456,91 @@ $(PreBuildEvent)]]> 1 - - + + 1 - + + + + res\drawable 1 + + + + 0 + + + 0 + + + 0 + + 0 + + + 0 + + + 0 + + + + + library\lib\armeabi-v7a 1 - - + + + res\drawable-mdpi 1 + + + + 0 + .bpl + 1 + .dylib + + + 1 + .dylib 1 + .dylib - - 1 + .dylib - + + + + res\drawable-xlarge 1 - + + + + res\drawable-ldpi 1 - - - - + - + + + + + @@ -557,51 +555,51 @@ $(PreBuildEvent)]]> - - False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False + + False diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index 842d89e..e420e9a 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -2208,130 +2208,87 @@ function TTelegramBot.SendVideoNote(const ChatId, VideoNote: TValue; const Durat end; function TTelegramBot.SendVoice(const ChatId, Voice: TValue; const Caption: string; const Duration: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('voice', Voice); - Parameters.Add('caption', Caption); - Parameters.Add('duration', Duration); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendVoice', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendVoice', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('voice', Voice, '', True), // + TtgApiParameter.Create('caption', Caption, 0, False), // + TtgApiParameter.Create('duration', Duration, 0, False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendAudio(const ChatId, Audio: TValue; const Caption: string; const Duration: Int64; const Performer: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('audio', Audio); - Parameters.Add('duration', Duration); - Parameters.Add('performer', Performer); - Parameters.Add('caption', Caption); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendAudio', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendAudio', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('audio', Audio, '', True), // + TtgApiParameter.Create('duration', Duration, 0, False), // + TtgApiParameter.Create('performer', Performer, '', False), // + TtgApiParameter.Create('caption', Caption, 0, False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendChatAction(const ChatId: TValue; const Action: TtgSendChatAction): Boolean; begin - Result := ExtractBool(RequestAPI('', [])); - Parameters.Add('chat_id', ChatId); - Parameters.Add('action', Action.ToString); - Result := ExecuteMethod('sendChatAction', Parameters); + Result := ExtractBool(RequestAPI('sendChatAction', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('action', Action.ToString, '', True)// + ])); end; function TTelegramBot.SendContact(const ChatId: TValue; const Contact: TtgContact; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('phone_number', Contact.PhoneNumber); - Parameters.Add('first_name', Contact.FirstName); - Parameters.Add('last_name', Contact.LastName); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendContact', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendContact', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('phone_number', Contact.PhoneNumber, '', True), // + TtgApiParameter.Create('first_name', Contact.FirstName, '', True), // + TtgApiParameter.Create('last_name', Contact.LastName, '', False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.SendDocument(const ChatId, Document: TValue; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('document', Document); - Parameters.Add('caption', Caption); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendDocument', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendDocument', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('document', Document, nil, True), // + TtgApiParameter.Create('caption', Caption, '', False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.KickChatMember(const ChatId: TValue; const UserId, UntilDate: Int64): Boolean; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('user_id', UserId); - Parameters.Add('until_date', UntilDate); - Result := ExecuteMethod('kickChatMember', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('kickChatMember', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('until_date', UntilDate, '', False)// + ])); end; function TTelegramBot.LeaveChat(const ChatId: TValue): Boolean; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Result := ExecuteMethod('leaveChat', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('leaveChat', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True)])); end; function TTelegramBot.GetUserProfilePhotos(const ChatId: TValue; const Offset, Limit: Int64): ItgUserProfilePhotos; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('offset', Offset); - Parameters.Add('limit', Limit); - Result := TtgUserProfilePhotos.Create(RequestAPI('getUserProfilePhotos', Parameters)); - finally - Parameters.Free; - end; + Result := TtgUserProfilePhotos.Create(RequestAPI('getUserProfilePhotos', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('offset', Offset, 0, True), // + TtgApiParameter.Create('limit', Limit, 100, False) // + ])); end; function TTelegramBot.GetMe: ItgUser; @@ -2340,45 +2297,25 @@ function TTelegramBot.GetMe: ItgUser; end; function TTelegramBot.getStickerSet(const Name: string): TtgStickerSet; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('name', Name); - Result := TtgStickerSet.Create(RequestAPI('getStickerSet', Parameters)); - finally - Parameters.Free; - end; + Result := TtgStickerSet.Create(RequestAPI('getStickerSet', [// + TtgApiParameter.Create('name', Name, 0, True) // + ])); end; function TTelegramBot.ForwardMessage(const ChatId, FromChatId: TValue; const MessageId: Int64; const DisableNotification: Boolean): ITgMessage; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('from_chat_id', FromChatId); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('message_id', MessageId); - Result := TTgMessage.Create(RequestAPI('forwardMessage', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('forwardMessage', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('from_chat_id', FromChatId, 0, True), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('message_id', MessageId, 0, False)])); end; function TTelegramBot.GetChat(const ChatId: TValue): ItgChat; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Result := TtgChat.Create(RequestAPI('getChat', Parameters)); - finally - Parameters.Free; - end; + Result := TtgChat.Create(RequestAPI('getChat', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True)])); end; function TTelegramBot.GetChatAdministrators(const ChatId: TValue): TArray; From 7df6c6e64d8f6773126f404e1efcf46f258774d3 Mon Sep 17 00:00:00 2001 From: Maxim Sysoev Date: Wed, 6 Dec 2017 23:24:24 +0200 Subject: [PATCH 04/14] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D0=B1=D0=B0=D0=B3=20=D1=81=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=BE=D0=B9=20=D1=81=D0=BE=D0=BE?= =?UTF-8?q?=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=20=D0=BA=D0=BB?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=B0=D1=82=D1=83=D1=80=D0=BE=D0=B9(=D0=BD?= =?UTF-8?q?=D1=83=D0=B6=D0=BD=D0=BE=20=D0=BF=D0=BE=D0=B4=D1=82=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5).=20=D0=A0=D0=B5?= =?UTF-8?q?=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=20=D0=BE=D1=82?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BC=D0=BE=D0=B4?= =?UTF-8?q?=D1=83=D0=BB=D1=8C=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D1=8B=20=D1=81=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BE=D0=BC;=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=BE=D0=BD=D0=B0=D0=BB=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE=D1=82=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BD=D0=B0=20=D1=81?= =?UTF-8?q?=D0=B5=D1=80=D0=B2=D0=B5=D1=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/EchoBot/EchoBot.dproj | 44 +- Install/TelegaPi.dpk | 3 +- Install/TelegaPi.dproj | 23 +- Source/TelegAPI.Bot.Impl.pas | 926 ++++++++++---------------- Source/TelegAPI.Bot.pas | 79 ++- Source/TelegAPi.CoreAPI.Parameter.pas | 5 +- Source/TelegAPi.CoreAPI.Request.pas | 30 +- 7 files changed, 477 insertions(+), 633 deletions(-) diff --git a/Demo/EchoBot/EchoBot.dproj b/Demo/EchoBot/EchoBot.dproj index e47aaa7..c6b145b 100644 --- a/Demo/EchoBot/EchoBot.dproj +++ b/Demo/EchoBot/EchoBot.dproj @@ -186,11 +186,6 @@ true - - - true - - ic_launcher.png @@ -243,6 +238,11 @@ true + + + true + + true @@ -304,27 +304,12 @@ true - - - 0 - .dll;.bpl - + 1 - .dylib - - - Contents\MacOS - 1 - .dylib 1 - .dylib - - - 1 - .dylib @@ -703,12 +688,27 @@ 1 - + + + 0 + .dll;.bpl + 1 + .dylib + + + Contents\MacOS + 1 + .dylib 1 + .dylib + + + 1 + .dylib diff --git a/Install/TelegaPi.dpk b/Install/TelegaPi.dpk index 44f9caf..302f8ac 100644 --- a/Install/TelegaPi.dpk +++ b/Install/TelegaPi.dpk @@ -31,7 +31,8 @@ package TelegaPi; requires rtl, - RESTComponents; + RESTComponents, + fmx; contains TelegAPI.Base in '..\Source\TelegAPI.Base.pas', diff --git a/Install/TelegaPi.dproj b/Install/TelegaPi.dproj index c64b504..5de5fb2 100644 --- a/Install/TelegaPi.dproj +++ b/Install/TelegaPi.dproj @@ -111,6 +111,7 @@ $(PreBuildEvent)]]> + @@ -185,16 +186,7 @@ $(PreBuildEvent)]]> true - - - 0 - .dll;.bpl - - - 1 - .dylib - - + Contents\Resources @@ -533,7 +525,16 @@ $(PreBuildEvent)]]> 1 - + + + 0 + .dll;.bpl + + + 1 + .dylib + + diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index e420e9a..27db8be 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -248,7 +248,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableWebPagePreview: Boolean = False; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to forward messages of any kind. /// @@ -325,7 +325,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Caption: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send audio files, if you want Telegram clients to /// display them in the music player. Your audio must be in the .mp3 @@ -379,7 +379,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Performer: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send general files. /// @@ -422,7 +422,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Caption: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send video files, Telegram clients support mp4 /// videos (other formats may be sent as Document). @@ -477,7 +477,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Height: Int64 = 0; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send audio files, if you want Telegram clients to @@ -524,7 +524,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Duration: Int64 = 0; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// As of /// v.4.0, Telegram clients support rounded square mp4 videos of up @@ -573,7 +573,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Length: Int64 = 0; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send point on the map. @@ -608,7 +608,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const LivePeriod: Int64 = 0; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send information about a venue. /// @@ -649,7 +649,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Venue: TtgVenue; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send phone contacts. /// @@ -683,7 +683,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Contact: TtgContact; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method when you need to tell the user that something is /// happening on the bot's side. The status is set for 5 seconds or less @@ -943,13 +943,13 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Text: string; // const ParseMode: TtgParseMode = TtgParseMode.Default; // const DisableWebPagePreview: Boolean = False; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; function EditMessageText(// const InlineMessageId: string; // const Text: string; // const ParseMode: TtgParseMode = TtgParseMode.Default; // const DisableWebPagePreview: Boolean = False; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; /// /// Use this method to edit captions of messages sent by the bot or via /// the bot (for inline bots). @@ -982,12 +982,12 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const ChatId: TValue; // const MessageId: Int64; // const Caption: string; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; { TODO -oM.E.Sysoev -cGeneral : Create Documentatiom } function EditMessageCaption(// const InlineMessageId: string; // const Caption: string; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to edit live location messages sent by the bot or via @@ -1018,7 +1018,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const ChatId: TValue; // const MessageId: Int64; // const Location: TtgLocation; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to edit live location messages sent by the bot or via /// the bot (for inline bots). A location can be edited until its @@ -1048,10 +1048,10 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// On success, if the edited message was sent by the bot, the edited /// Message is returned, otherwise True is returned. /// - function editMessageLiveLocation(// + function EditMessageLiveLocation(// const InlineMessageId: string; // const Location: TtgLocation; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to stop updating a live location message sent by the @@ -1076,7 +1076,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) function stopMessageLiveLocation(// const ChatId: TValue; // const MessageId: Int64; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to stop updating a live location message sent by the /// bot or via the bot (for inline bots) before live_period expires. @@ -1094,7 +1094,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// function stopMessageLiveLocation(// const InlineMessageId: string; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to edit only the reply markup of messages sent by the /// bot or via the bot (for inline bots). @@ -1118,7 +1118,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) function EditMessageReplyMarkup(// const ChatId: TValue; // const MessageId: Int64; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; /// /// Use this method to edit only the reply markup of messages sent by the /// bot or via the bot (for inline bots). @@ -1136,7 +1136,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// function EditMessageReplyMarkup(// const InlineMessageId: string; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; /// /// Use this method to delete a message. /// @@ -1315,7 +1315,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const IsFlexible: Boolean = False; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// If you sent an invoice requesting a shipping address and the /// parameter is_flexible was specified, the Bot API will send an Update @@ -1341,10 +1341,11 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// unavailable'). Telegram will display this message to the user. /// /// - function AnswerShippingQuery(// + function AnswerShippingQueryGood(// + const ShippingQueryId: string; // + const ShippingOptions: TArray): Boolean; + function AnswerShippingQueryBad(// const ShippingQueryId: string; // - const Ok: Boolean; // - const ShippingOptions: TArray; // const ErrorMessage: string): Boolean; /// /// Once the user has confirmed their payment and shipping details, the @@ -1376,10 +1377,11 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// after the pre-checkout query was sent. /// /// - function AnswerPreCheckoutQuery(// + function AnswerPreCheckoutQueryGood(// + const PreCheckoutQueryId: string): Boolean; + function AnswerPreCheckoutQueryBad(// const PreCheckoutQueryId: string; // - const Ok: Boolean; // - const ErrorMessage: string = ''): Boolean; + const ErrorMessage: string): Boolean; {$ENDREGION} {$REGION 'Games'} /// @@ -1414,7 +1416,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const GameShortName: string; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to set the score of the specified user in a game. /// @@ -1454,11 +1456,16 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) function SetGameScore(// const UserId: Int64; // const Score: Int64; // + const InlineMessageId: string; // const Force: Boolean = False; // - const DisableEditMessage: Boolean = False; // - const ChatId: Int64 = 0; // - const MessageId: Int64 = 0; // - const InlineMessageId: string = ''): ITgMessage; + const DisableEditMessage: Boolean = False): ITgMessage; overload; + function SetGameScore(// + const UserId: Int64; // + const Score: Int64; // + const ChatId: Int64; // + const MessageId: Int64; // + const Force: Boolean = False; // + const DisableEditMessage: Boolean = False): ITgMessage; overload; /// /// Use this method to get data for high score tables. Will return the /// score of the specified user and several of his neighbors in a game. @@ -1491,11 +1498,13 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// /// Official API /// + function GetGameHighScores(// + const UserId: Int64; // + const InlineMessageId: string = ''): TArray; overload; function GetGameHighScores(// const UserId: Int64; // const ChatId: Int64 = 0; // - const MessageId: Int64 = 0; // - const InlineMessageId: string = ''): TArray; + const MessageId: Int64 = 0): TArray; overload; {$ENDREGION} {$REGION 'Manage groups and channels'} /// @@ -1761,7 +1770,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Sticker: TValue; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to get a sticker set. /// @@ -1920,6 +1929,7 @@ implementation uses REST.Json, + FMX.Types, TelegAPI.Helpers, TelegAPI.CoreAPI.Request; { TTelegramBot } @@ -1931,6 +1941,16 @@ function TTelegramBot.RequestAPI(const Method: string; const Parameters: TArray< begin LTgRequest := TtgApiRequest.Create(Self, Method); try + LTgRequest.OnSend := + procedure(Url, Data: string) + begin + Log.d('%s - %s', [Url, Data]); + end; + LTgRequest.OnReceive := + procedure(Data: string) + begin + Log.d('%s', [Data]); + end; LTgRequest.Parameters.AddRange(Parameters); Result := LTgRequest.Execute.ContentAsString(TEncoding.UTF8); if Assigned(OnReceiveRawData) then @@ -2045,6 +2065,8 @@ procedure TTelegramBot.SetExceptionManager(const Value: ItgExceptionHandler); begin FExceptionManager := Value; end; + + {$ENDREGION} {$REGION 'Getting updates'} @@ -2080,7 +2102,7 @@ function TTelegramBot.DeleteWebhook: Boolean; {$ENDREGION} {$REGION 'Basic methods'} -function TTelegramBot.stopMessageLiveLocation(const ChatId: TValue; const MessageId: Int64; const ReplyMarkup: IReplyMarkup): Boolean; +function TTelegramBot.stopMessageLiveLocation(const ChatId: TValue; const MessageId: Int64; ReplyMarkup: IReplyMarkup): Boolean; begin Result := ExtractBool(RequestAPI('stopMessageLiveLocation', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2089,7 +2111,7 @@ function TTelegramBot.stopMessageLiveLocation(const ChatId: TValue; const Messag ])); end; -function TTelegramBot.stopMessageLiveLocation(const InlineMessageId: string; const ReplyMarkup: IReplyMarkup): Boolean; +function TTelegramBot.stopMessageLiveLocation(const InlineMessageId: string; ReplyMarkup: IReplyMarkup): Boolean; begin Result := ExtractBool(RequestAPI('stopMessageLiveLocation', [// TtgApiParameter.Create('inline_message_id', InlineMessageId, '', True), // @@ -2105,7 +2127,7 @@ function TTelegramBot.UnbanChatMember(const ChatId: TValue; const UserId: Int64) ])); end; -function TTelegramBot.SendLocation(const ChatId: TValue; const Location: TtgLocation; const LivePeriod: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendLocation(const ChatId: TValue; const Location: TtgLocation; const LivePeriod: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendLocation', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2128,7 +2150,7 @@ function TTelegramBot.sendMediaGroup(const ChatId: TValue; const AMedia: TArray< ])); end; -function TTelegramBot.SendPhoto(const ChatId, Photo: TValue; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendPhoto(const ChatId, Photo: TValue; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendPhoto', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2140,18 +2162,7 @@ function TTelegramBot.SendPhoto(const ChatId, Photo: TValue; const Caption: stri ])); end; -function TTelegramBot.SendSticker(const ChatId, Sticker: TValue; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -begin - Result := TTgMessage.Create(RequestAPI('sendSticker', [// - TtgApiParameter.Create('chat_id', ChatId, 0, True), // - TtgApiParameter.Create('sticker', Sticker, '', True), // - TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // - TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // - TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // - ])); -end; - -function TTelegramBot.SendMessage(const ChatId: TValue; const Text: string; const ParseMode: TtgParseMode; const DisableWebPagePreview, DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendMessage(const ChatId: TValue; const Text: string; const ParseMode: TtgParseMode; const DisableWebPagePreview, DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendMessage', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2164,7 +2175,7 @@ function TTelegramBot.SendMessage(const ChatId: TValue; const Text: string; cons ])); end; -function TTelegramBot.SendVenue(const ChatId: TValue; const Venue: TtgVenue; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendVenue(const ChatId: TValue; const Venue: TtgVenue; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendVenue', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2179,7 +2190,7 @@ function TTelegramBot.SendVenue(const ChatId: TValue; const Venue: TtgVenue; con ])); end; -function TTelegramBot.SendVideo(const ChatId, Video: TValue; const Caption: string; const Duration, Width, Height: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendVideo(const ChatId, Video: TValue; const Caption: string; const Duration, Width, Height: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendVideo', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2194,7 +2205,7 @@ function TTelegramBot.SendVideo(const ChatId, Video: TValue; const Caption: stri ])); end; -function TTelegramBot.SendVideoNote(const ChatId, VideoNote: TValue; const Duration, Length: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendVideoNote(const ChatId, VideoNote: TValue; const Duration, Length: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendVideoNote', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2207,12 +2218,12 @@ function TTelegramBot.SendVideoNote(const ChatId, VideoNote: TValue; const Durat ])); end; -function TTelegramBot.SendVoice(const ChatId, Voice: TValue; const Caption: string; const Duration: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendVoice(const ChatId, Voice: TValue; const Caption: string; const Duration: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendVoice', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // TtgApiParameter.Create('voice', Voice, '', True), // - TtgApiParameter.Create('caption', Caption, 0, False), // + TtgApiParameter.Create('caption', Caption, '', False), // TtgApiParameter.Create('duration', Duration, 0, False), // TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // @@ -2220,7 +2231,7 @@ function TTelegramBot.SendVoice(const ChatId, Voice: TValue; const Caption: stri ])); end; -function TTelegramBot.SendAudio(const ChatId, Audio: TValue; const Caption: string; const Duration: Int64; const Performer: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendAudio(const ChatId, Audio: TValue; const Caption: string; const Duration: Int64; const Performer: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendAudio', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2242,7 +2253,7 @@ function TTelegramBot.SendChatAction(const ChatId: TValue; const Action: TtgSend ])); end; -function TTelegramBot.SendContact(const ChatId: TValue; const Contact: TtgContact; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendContact(const ChatId: TValue; const Contact: TtgContact; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendContact', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2255,7 +2266,7 @@ function TTelegramBot.SendContact(const ChatId: TValue; const Contact: TtgContac ])); end; -function TTelegramBot.SendDocument(const ChatId, Document: TValue; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendDocument(const ChatId, Document: TValue; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendDocument', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2296,13 +2307,6 @@ function TTelegramBot.GetMe: ItgUser; Result := TtgUser.Create(RequestAPI('getMe', nil)); end; -function TTelegramBot.getStickerSet(const Name: string): TtgStickerSet; -begin - Result := TtgStickerSet.Create(RequestAPI('getStickerSet', [// - TtgApiParameter.Create('name', Name, 0, True) // - ])); -end; - function TTelegramBot.ForwardMessage(const ChatId, FromChatId: TValue; const MessageId: Int64; const DisableNotification: Boolean): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('forwardMessage', [// @@ -2319,619 +2323,421 @@ function TTelegramBot.GetChat(const ChatId: TValue): ItgChat; end; function TTelegramBot.GetChatAdministrators(const ChatId: TValue): TArray; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Result := GetArrayFromMethod(TtgChatMember, 'getChatAdministrators', Parameters); - finally - Parameters.Free; - end; + Result := GetArrayFromMethod(TtgChatMember, // + RequestAPI('getChatAdministrators', // + [TtgApiParameter.Create('chat_id', ChatId, 0, true)])); end; function TTelegramBot.GetChatMember(const ChatId: TValue; const UserId: Int64): ItgChatMember; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('user_id', UserId); - Result := TtgChatMember.Create(RequestAPI('getChatMember', Parameters)); - finally - Parameters.Free; - end; + Result := TtgChatMember.Create(RequestAPI('getChatMember', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('user_id', UserId, 0, True)])); end; function TTelegramBot.GetChatMembersCount(const ChatId: TValue): Int64; var - Parameters: TDictionary; LJson: TJSONValue; begin - Parameters := TDictionary.Create; + LJson := TJSONObject.ParseJSONValue(RequestAPI('getChatMembersCount', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True)])); try - Parameters.Add('chat_id', ChatId); - LJson := TJSONObject.ParseJSONValue(RequestAPI('getChatMembersCount', Parameters)); - try - if not LJson.TryGetValue(Result) then - Result := 0; - finally - LJson.Free; - end; + if not LJson.TryGetValue(Result) then + Result := 0; finally - Parameters.Free; + LJson.Free; end; end; function TTelegramBot.GetFile(const FileId: string): ItgFile; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('file_id', FileId); - Result := TtgFile.Create(RequestAPI('getFile', Parameters)); - finally - Parameters.Free; - end; -end; - -function TTelegramBot.addStickerToSet(const UserId: Int64; const Name: string; const PngSticker: TValue; const Emojis: string; const MaskPosition: TtgMaskPosition): Boolean; -var - Parameters: TDictionary; -begin - Parameters := TDictionary.Create; - try - Parameters.Add('user_id', UserId); - Parameters.Add('name', Name); - Parameters.Add('png_sticker', PngSticker); - Parameters.Add('emojis', Emojis); - Parameters.Add('mask_position', MaskPosition); - Result := ExecuteMethod('addStickerToSet', Parameters); - finally - Parameters.Free; - end; + Result := TtgFile.Create(RequestAPI('getFile', [// + TtgApiParameter.Create('file_id', FileId, 0, True)])); end; function TTelegramBot.AnswerCallbackQuery(const CallbackQueryId, Text: string; const ShowAlert: Boolean; const Url: string; const CacheTime: Int64): Boolean; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('callback_query_id', CallbackQueryId); - Parameters.Add('text', Text); - Parameters.Add('show_alert', ShowAlert); - Parameters.Add('url', Url); - Parameters.Add('cache_time', CacheTime); - Result := ExecuteMethod('answerCallbackQuery', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('answerCallbackQuery', [// + TtgApiParameter.Create('callback_query_id', CallbackQueryId, '', True), // + TtgApiParameter.Create('text', Text, '', True), // + TtgApiParameter.Create('show_alert', ShowAlert, False, False), // + TtgApiParameter.Create('url', Url, '', False), // + TtgApiParameter.Create('cache_time', CacheTime, 0, False)])); end; {$ENDREGION} {$REGION 'Updating messages'} -function TTelegramBot.EditMessageText(const InlineMessageId, Text: string; const ParseMode: TtgParseMode; const DisableWebPagePreview: Boolean; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; +function TTelegramBot.EditMessageText(const InlineMessageId, Text: string; const ParseMode: TtgParseMode; const DisableWebPagePreview: Boolean; ReplyMarkup: IReplyMarkup): ITgMessage; begin - Parameters := TDictionary.Create; - try - Parameters.Add('inline_message_id', InlineMessageId); - Parameters.Add('text', Text); - Parameters.Add('parse_mode', ParseMode.ToString); - Parameters.Add('disable_web_page_preview', DisableWebPagePreview); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('editMessageText', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage(RequestAPI('editMessageText', [// + TtgApiParameter.Create('inline_message_id', InlineMessageId, 0, True), // + TtgApiParameter.Create('text', Text, 0, True), // + TtgApiParameter.Create('parse_mode', ParseMode.ToString, False, False), // + TtgApiParameter.Create('disable_web_page_preview', DisableWebPagePreview, False, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), 0, False)])); end; -function TTelegramBot.EditMessageText(const ChatId: TValue; const MessageId: Int64; const Text: string; const ParseMode: TtgParseMode; const DisableWebPagePreview: Boolean; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; +function TTelegramBot.EditMessageText(const ChatId: TValue; const MessageId: Int64; const Text: string; const ParseMode: TtgParseMode; const DisableWebPagePreview: Boolean; ReplyMarkup: IReplyMarkup): ITgMessage; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Parameters.Add('text', Text); - Parameters.Add('parse_mode', ParseMode.ToString); - Parameters.Add('disable_web_page_preview', DisableWebPagePreview); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('editMessageText', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('editMessageText', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, nil, True), // + TtgApiParameter.Create('text', Text, '', False), // + TtgApiParameter.Create('parse_mode', ParseMode.ToString, False, False), // + TtgApiParameter.Create('disable_web_page_preview', DisableWebPagePreview, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; function TTelegramBot.DeleteMessage(const ChatId: TValue; const MessageId: Int64): Boolean; -var - Parameters: TDictionary; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Result := ExecuteMethod('deleteMessage', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('deleteMessage', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, nil, True) // + ])); end; -function TTelegramBot.deleteStickerFromSet(const Sticker: string): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.EditMessageCaption(const ChatId: TValue; const MessageId: Int64; const Caption: string; ReplyMarkup: IReplyMarkup): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('sticker', Sticker); - Result := ExecuteMethod('deleteStickerFromSet', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('editMessageCaption', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, nil, True), // + TtgApiParameter.Create('caption', Caption, '', False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; -function TTelegramBot.EditMessageCaption(const ChatId: TValue; const MessageId: Int64; const Caption: string; const ReplyMarkup: IReplyMarkup): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.EditMessageCaption(const InlineMessageId, Caption: string; ReplyMarkup: IReplyMarkup): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Parameters.Add('caption', Caption); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := ExecuteMethod('editMessageCaption', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('editMessageCaption', [// + TtgApiParameter.Create('inline_message_id', InlineMessageId, nil, True), // + TtgApiParameter.Create('caption', Caption, '', False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; -function TTelegramBot.EditMessageCaption(const InlineMessageId, Caption: string; const ReplyMarkup: IReplyMarkup): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.editMessageLiveLocation(const ChatId: TValue; const MessageId: Int64; const Location: TtgLocation; ReplyMarkup: IReplyMarkup): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('caption', Caption); - Parameters.Add('inline_message_id', InlineMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := ExecuteMethod('editMessageCaption', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('editMessageLiveLocation', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, nil, True), // + TtgApiParameter.Create('latitude', Location.Latitude, '', False), // + TtgApiParameter.Create('longitude', Location.Longitude, False, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; -function TTelegramBot.editMessageLiveLocation(const ChatId: TValue; const MessageId: Int64; const Location: TtgLocation; const ReplyMarkup: IReplyMarkup): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.EditMessageLiveLocation(const InlineMessageId: string; const Location: TtgLocation; ReplyMarkup: IReplyMarkup): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Parameters.Add('latitude', Location.Latitude); - Parameters.Add('longitude', Location.Longitude); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := ExecuteMethod('editMessageLiveLocation', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('editMessageLiveLocation', [// + TtgApiParameter.Create('inline_message_id', InlineMessageId, 0, True), // + TtgApiParameter.Create('latitude', Location.Latitude, '', False), // + TtgApiParameter.Create('longitude', Location.Longitude, False, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; -function TTelegramBot.editMessageLiveLocation(const InlineMessageId: string; const Location: TtgLocation; const ReplyMarkup: IReplyMarkup): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.EditMessageReplyMarkup(const ChatId: TValue; const MessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin - Parameters := TDictionary.Create; - try - Parameters.Add('inline_message_id', InlineMessageId); - Parameters.Add('latitude', Location.Latitude); - Parameters.Add('longitude', Location.Longitude); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := ExecuteMethod('editMessageLiveLocation', Parameters); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('editMessageReplyMarkup', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, '', False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; -function TTelegramBot.EditMessageReplyMarkup(const ChatId: TValue; const MessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; +function TTelegramBot.EditMessageReplyMarkup(const InlineMessageId: string; ReplyMarkup: IReplyMarkup): ITgMessage; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('editMessageReplyMarkup', Parameters)); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('editMessageReplyMarkup', [// + TtgApiParameter.Create('inline_message_id', InlineMessageId, 0, True), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; +{$ENDREGION} -function TTelegramBot.EditMessageReplyMarkup(const InlineMessageId: string; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; + + +{$REGION 'Manage groups and channels'} + +function TTelegramBot.DeleteChatPhoto(const ChatId: TValue): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('inline_message_id', InlineMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('editMessageReplyMarkup', Parameters)); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('deleteChatPhoto', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True)])); end; -{$ENDREGION} -{$REGION 'Inline mode'} -function TTelegramBot.AnswerInlineQuery(const InlineQueryId: string; const Results: TArray; const CacheTime: Int64; const IsPersonal: Boolean; const NextOffset, SwitchPmText, SwitchPmParameter: string): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.deleteChatStickerSet(const ChatId: TValue): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('inline_query_id', InlineQueryId); - Parameters.Add('results', TJsonUtils.ArrayToJString(Results)); - Parameters.Add('cache_time', CacheTime); - Parameters.Add('is_personal', IsPersonal); - Parameters.Add('next_offset', NextOffset); - Parameters.Add('switch_pm_text', SwitchPmText); - Parameters.Add('switch_pm_parameter', SwitchPmParameter); - Result := ExecuteMethod('answerInlineQuery', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('deleteChatStickerSet', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True)])); end; -{$ENDREGION} -{$REGION 'Payments'} -function TTelegramBot.SendInvoice(const ChatId: Int64; const title: string; const Description: string; const Payload: string; const ProviderToken: string; const StartParameter: string; const Currency: string; const Prices: TArray; const ProviderData: string; const PhotoUrl: string; const PhotoSize: Int64; const PhotoWidth: Int64; const PhotoHeight: Int64; const NeedName: Boolean; const NeedPhoneNumber: Boolean; const NeedEmail: Boolean; const NeedShippingAddress: Boolean; const IsFlexible: Boolean; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - LParameters: TDictionary; +function TTelegramBot.ExportChatInviteLink(const ChatId: TValue): string; begin - LParameters := TDictionary.Create; - try - LParameters.Add('chat_id', ChatId); - LParameters.Add('title', title); - LParameters.Add('description', Description); - LParameters.Add('payload', Payload); - LParameters.Add('provider_token', ProviderToken); - LParameters.Add('start_parameter', StartParameter); - LParameters.Add('currency', Currency); - LParameters.Add('prices', TJsonUtils.ArrayToJString(Prices)); - LParameters.Add('provider_data', ProviderData); - LParameters.Add('photo_url', PhotoUrl); - LParameters.Add('photo_size', PhotoSize); - LParameters.Add('photo_width', PhotoWidth); - LParameters.Add('photo_height', PhotoHeight); - LParameters.Add('need_name', NeedName); - LParameters.Add('need_phone_number', NeedPhoneNumber); - LParameters.Add('need_email', NeedEmail); - LParameters.Add('need_shipping_address', NeedShippingAddress); - LParameters.Add('is_flexible', IsFlexible); - LParameters.Add('disable_notification', DisableNotification); - LParameters.Add('reply_to_message_id', ReplyToMessageId); - LParameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendInvoice', LParameters)); - finally - LParameters.Free; - end; + Result := GetValueFromMethod(RequestAPI('exportChatInviteLink', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True)])); end; -function TTelegramBot.AnswerPreCheckoutQuery(const PreCheckoutQueryId: string; const Ok: Boolean; const ErrorMessage: string): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.PinChatMessage(const ChatId: TValue; const MessageId: Int64; const DisableNotification: Boolean): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('Pre_checkout_query_id', PreCheckoutQueryId); - Parameters.Add('Ok', Ok); - Parameters.Add('Error_message', ErrorMessage); - Result := ExecuteMethod('AnswerPreCheckoutQuery', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('pinChatMessage', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, 0, True), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False)])); end; -function TTelegramBot.AnswerShippingQuery(const ShippingQueryId: string; const Ok: Boolean; const ShippingOptions: TArray; const ErrorMessage: string): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.SetChatDescription(const ChatId: TValue; const Description: string): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('Shipping_query_id', ShippingQueryId); - Parameters.Add('Ok', Ok); - Parameters.Add('Shipping_options', TJsonUtils.ArrayToJString(ShippingOptions)); - Parameters.Add('Error_message', ErrorMessage); - Result := ExecuteMethod('answerShippingQuery', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('setChatDescription', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('description', Description, '', True)])); end; -function TTelegramBot.createNewStickerSet(const UserId: Int64; const Name, Title: string; const PngSticker: TValue; const Emojis: string; const ContainsMasks: Boolean; const MaskPosition: TtgMaskPosition): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.SetChatPhoto(const ChatId: TValue; const Photo: TtgFileToSend): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('user_id', UserId); - Parameters.Add('name', Name); - Parameters.Add('title', Title); - Parameters.Add('png_sticker', PngSticker); - Parameters.Add('emojis', Emojis); - Parameters.Add('contains_masks', ContainsMasks); - Parameters.Add('mask_position', MaskPosition); - Result := ExecuteMethod('createNewStickerSet', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('setChatPhoto', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('photo', Photo, nil, True)])); end; -{$ENDREGION} -{$REGION 'Games'} -function TTelegramBot.SetGameScore(const UserId, Score: Int64; const Force, DisableEditMessage: Boolean; const ChatId, MessageId: Int64; const InlineMessageId: string): ITgMessage; -var - Parameters: TDictionary; +function TTelegramBot.setChatStickerSet(const ChatId: TValue; const StickerSetName: string): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('user_id', UserId); - Parameters.Add('score', Score); - Parameters.Add('force', Force); - Parameters.Add('disable_edit_message', DisableEditMessage); - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Parameters.Add('inline_message_id', InlineMessageId); - Result := TTgMessage.Create(RequestAPI('setGameScore', Parameters)); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('setChatStickerSet', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('sticker_set_name', StickerSetName, '', True)])); end; -function TTelegramBot.setStickerPositionInSet(const Sticker: string; const Position: Int64): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.SetChatTitle(const ChatId: TValue; const Title: string): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('sticker', Sticker); - Parameters.Add('position', Position); - Result := ExecuteMethod('setStickerPositionInSet', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('setChatTitle', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('title', Title, '', True)])); end; -function TTelegramBot.SendGame(const ChatId: Int64; const GameShortName: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; const ReplyMarkup: IReplyMarkup): ITgMessage; -var - Parameters: TDictionary; +function TTelegramBot.UnpinChatMessage(const ChatId: TValue): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('game_short_name', GameShortName); - Parameters.Add('disable_notification', DisableNotification); - Parameters.Add('reply_to_message_id', ReplyToMessageId); - Parameters.Add('reply_markup', TInterfacedObject(ReplyMarkup)); - Result := TTgMessage.Create(RequestAPI('sendGame', Parameters)); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('unpinChatMessage', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True)])); end; -function TTelegramBot.GetGameHighScores(const UserId, ChatId, MessageId: Int64; const InlineMessageId: string): TArray; -var - Parameters: TDictionary; - LJson: TJSONArray; - I: Integer; + +{$ENDREGION} +{$REGION 'Manage users and admins'} + +function TTelegramBot.PromoteChatMember(const ChatId: TValue; const UserId: Int64; const CanChangeInfo, CanPostMessages, CanEditMessages, CanDeleteMessages, CanInviteUsers, CanRestrictMembers, CanPinMessages, CanPromoteMembers: Boolean): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('user_id', UserId); - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Parameters.Add('inline_message_id', InlineMessageId); - LJson := TJSONObject.ParseJSONValue(RequestAPI('getGameHighScores', Parameters)) as TJSONArray; - try - SetLength(Result, LJson.Count); - for I := 0 to High(Result) do - Result[I] := TtgGameHighScore.Create(LJson.Items[I].ToJSON); - finally - LJson.Free; - end; - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('promoteChatMember', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('can_change_info', CanChangeInfo, False, False), // + TtgApiParameter.Create('can_post_messages', CanPostMessages, False, False), // + TtgApiParameter.Create('can_edit_messages', CanEditMessages, False, False), // + TtgApiParameter.Create('can_delete_messages', CanDeleteMessages, False, False), // + TtgApiParameter.Create('can_invite_users', CanInviteUsers, False, False), // + TtgApiParameter.Create('can_restrict_members', CanRestrictMembers, False, False), // + TtgApiParameter.Create('can_pin_messages', CanPinMessages, False, False), // + TtgApiParameter.Create('can_promote_members', CanPromoteMembers, False, False)])); +end; + +function TTelegramBot.RestrictChatMember(const ChatId: TValue; const UserId, UntilDate: Int64; const CanSendMessages, CanSendMediaMessages, CanSendOtherMessages, CanAddWebPagePreviews: Boolean): Boolean; +begin + Result := ExtractBool(RequestAPI('restrictChatMember', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('until_date', UntilDate, 0, False), // + TtgApiParameter.Create('can_send_messages', CanSendMessages, False, False), // + TtgApiParameter.Create('can_send_media_messages', CanSendMediaMessages, False, False), // + TtgApiParameter.Create('can_send_other_messages', CanSendOtherMessages, False, False), // + TtgApiParameter.Create('can_add_web_page_previews', CanAddWebPagePreviews, False, False)])); end; {$ENDREGION} -{$REGION 'Manage groups and channels'} +{$REGION 'Stickers'} -function TTelegramBot.DeleteChatPhoto(const ChatId: TValue): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.addStickerToSet(const UserId: Int64; const Name: string; const PngSticker: TValue; const Emojis: string; const MaskPosition: TtgMaskPosition): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Result := ExecuteMethod('deleteChatPhoto', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('addStickerToSet', [// + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('name', Name, 0, True), // + TtgApiParameter.Create('png_sticker', PngSticker, False, False), // + TtgApiParameter.Create('emojis', Emojis, False, False), // + TtgApiParameter.Create('mask_position', MaskPosition, 0, False)])); end; -function TTelegramBot.deleteChatStickerSet(const ChatId: TValue): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.createNewStickerSet(const UserId: Int64; const Name, Title: string; const PngSticker: TValue; const Emojis: string; const ContainsMasks: Boolean; const MaskPosition: TtgMaskPosition): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Result := ExecuteMethod('deleteChatStickerSet', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('createNewStickerSet', [// + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('name', Name, nil, True), // + TtgApiParameter.Create('title', Title, 0, True), // + TtgApiParameter.Create('png_sticker', PngSticker, 0, True), // + TtgApiParameter.Create('emojis', Emojis, nil, True), // + TtgApiParameter.Create('contains_masks', ContainsMasks, 0, True), // + TtgApiParameter.Create('mask_position', MaskPosition, '', False)])); end; -function TTelegramBot.ExportChatInviteLink(const ChatId: TValue): string; -var - Parameters: TDictionary; +function TTelegramBot.deleteStickerFromSet(const Sticker: string): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Result := GetValueFromMethod('exportChatInviteLink', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('deleteStickerFromSet', [// + TtgApiParameter.Create('sticker', Sticker, 0, True)])); end; -function TTelegramBot.PinChatMessage(const ChatId: TValue; const MessageId: Int64; const DisableNotification: Boolean): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.getStickerSet(const Name: string): TtgStickerSet; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('message_id', MessageId); - Parameters.Add('disable_notification', DisableNotification); - Result := ExecuteMethod('pinChatMessage', Parameters); - finally - Parameters.Free; - end; + Result := TtgStickerSet.Create(RequestAPI('getStickerSet', [// + TtgApiParameter.Create('name', Name, 0, True)])); end; -function TTelegramBot.SetChatDescription(const ChatId: TValue; const Description: string): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.SendSticker(const ChatId, Sticker: TValue; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('description', Description); - Result := ExecuteMethod('setChatDescription', Parameters); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendSticker', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('sticker', Sticker, '', True), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; -function TTelegramBot.SetChatPhoto(const ChatId: TValue; const Photo: TtgFileToSend): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.setStickerPositionInSet(const Sticker: string; const Position: Int64): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('photo', Photo); - Result := ExecuteMethod('setChatPhoto', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('setStickerPositionInSet', [// + TtgApiParameter.Create('sticker', Sticker, 0, True), // + TtgApiParameter.Create('position', Position, nil, True)])); end; -function TTelegramBot.setChatStickerSet(const ChatId: TValue; const StickerSetName: string): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.uploadStickerFile(const UserId: Int64; const PngSticker: TtgFileToSend): ItgFile; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('sticker_set_name', StickerSetName); - Result := ExecuteMethod('setChatStickerSet', Parameters); - finally - Parameters.Free; - end; + Result := TtgFile.Create(RequestAPI('uploadStickerFile', [// + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('png_sticker', PngSticker, nil, True)])); end; +{$ENDREGION} +{$REGION 'Inline mode'} -function TTelegramBot.SetChatTitle(const ChatId: TValue; const Title: string): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.AnswerInlineQuery(const InlineQueryId: string; const Results: TArray; const CacheTime: Int64; const IsPersonal: Boolean; const NextOffset, SwitchPmText, SwitchPmParameter: string): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('title', Title); - Result := ExecuteMethod('setChatTitle', Parameters); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('answerInlineQuery', [// + TtgApiParameter.Create('inline_query_id', InlineQueryId, '', True), // + TtgApiParameter.Create('results', TJsonUtils.ArrayToJString(Results), nil, True), // + TtgApiParameter.Create('cache_time', CacheTime, 0, False), // + TtgApiParameter.Create('is_personal', IsPersonal, False, False), // + TtgApiParameter.Create('next_offset', NextOffset, '', False), // + TtgApiParameter.Create('switch_pm_text', SwitchPmText, '', False), // + TtgApiParameter.Create('switch_pm_parameter', SwitchPmParameter, '', False) // + ])); end; -function TTelegramBot.UnpinChatMessage(const ChatId: TValue): Boolean; -var - Parameters: TDictionary; + +{$ENDREGION} +{$REGION 'Payments'} + +function TTelegramBot.SendInvoice(const ChatId: Int64; const title: string; const Description: string; const Payload: string; const ProviderToken: string; const StartParameter: string; const Currency: string; const Prices: TArray; const ProviderData: string; const PhotoUrl: string; const PhotoSize: Int64; const PhotoWidth: Int64; const PhotoHeight: Int64; const NeedName: Boolean; const NeedPhoneNumber: Boolean; const NeedEmail: Boolean; const NeedShippingAddress: Boolean; const IsFlexible: Boolean; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Result := ExecuteMethod('unpinChatMessage', Parameters); - finally - Parameters.Free; - end; + Result := TTgMessage.Create(RequestAPI('sendInvoice', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('title', title, '', True), // + TtgApiParameter.Create('description', Description, '', True), // + TtgApiParameter.Create('payload', Payload, '', True), // + TtgApiParameter.Create('provider_token', ProviderToken, '', True), // + TtgApiParameter.Create('start_parameter', StartParameter, '', True), // + TtgApiParameter.Create('currency', Currency, '', True), // + TtgApiParameter.Create('prices', TJsonUtils.ArrayToJString(Prices), nil, True), // + TtgApiParameter.Create('provider_data', ProviderData, '', False), // + TtgApiParameter.Create('photo_url', PhotoUrl, '', False), // + TtgApiParameter.Create('photo_size', PhotoSize, 0, False), // + TtgApiParameter.Create('photo_width', PhotoWidth, 0, False), // + TtgApiParameter.Create('photo_height', PhotoHeight, 0, False), // + TtgApiParameter.Create('need_name', NeedName, False, False), // + TtgApiParameter.Create('need_phone_number', NeedPhoneNumber, False, False), // + TtgApiParameter.Create('need_email', NeedEmail, False, False), // + TtgApiParameter.Create('need_shipping_address', NeedShippingAddress, False, False), // + TtgApiParameter.Create('is_flexible', IsFlexible, False, False), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, False, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + ])); end; -function TTelegramBot.uploadStickerFile(const UserId: Int64; const PngSticker: TtgFileToSend): ItgFile; -var - Parameters: TDictionary; +function TTelegramBot.AnswerPreCheckoutQueryBad(const PreCheckoutQueryId, ErrorMessage: string): Boolean; begin - Parameters := TDictionary.Create; - try - Parameters.Add('user_id', UserId); - Parameters.Add('png_sticker', PngSticker); - Result := TtgFile.Create(RequestAPI('uploadStickerFile', Parameters)); - finally - Parameters.Free; - end; + Result := ExtractBool(RequestAPI('AnswerPreCheckoutQuery', [// + TtgApiParameter.Create('Pre_checkout_query_id', PreCheckoutQueryId, 0, True), // + TtgApiParameter.Create('Ok', False, True, False), // + TtgApiParameter.Create('Error_message', ErrorMessage, '', True)])); end; + +function TTelegramBot.AnswerPreCheckoutQueryGood(const PreCheckoutQueryId: string): Boolean; +begin + Result := ExtractBool(RequestAPI('AnswerPreCheckoutQuery', [// + TtgApiParameter.Create('Pre_checkout_query_id', PreCheckoutQueryId, 0, True), // + TtgApiParameter.Create('Ok', True, False, False)])); +end; + +function TTelegramBot.AnswerShippingQueryBad(const ShippingQueryId, ErrorMessage: string): Boolean; +begin + Result := ExtractBool(RequestAPI('answerShippingQuery', [// + TtgApiParameter.Create('Shipping_query_id', ShippingQueryId, 0, True), // + TtgApiParameter.Create('Ok', False, False, False), // + TtgApiParameter.Create('Error_message', ErrorMessage, '', False) // + ])); +end; + +function TTelegramBot.AnswerShippingQueryGood(const ShippingQueryId: string; const ShippingOptions: TArray): Boolean; +begin + Result := ExtractBool(RequestAPI('answerShippingQuery', [// + TtgApiParameter.Create('Shipping_query_id', ShippingQueryId, 0, True), // + TtgApiParameter.Create('Ok', True, False, False), // + TtgApiParameter.Create('Shipping_options', TJsonUtils.ArrayToJString(ShippingOptions), nil, True)])); +end; + {$ENDREGION} -{$REGION 'Manage users and admins'} -function TTelegramBot.PromoteChatMember(const ChatId: TValue; const UserId: Int64; const CanChangeInfo, CanPostMessages, CanEditMessages, CanDeleteMessages, CanInviteUsers, CanRestrictMembers, CanPinMessages, CanPromoteMembers: Boolean): Boolean; -var - Parameters: TDictionary; +{$REGION 'Games'} + +function TTelegramBot.GetGameHighScores(const UserId: Int64; const InlineMessageId: string): TArray; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('user_id', UserId); - Parameters.Add('can_change_info', CanChangeInfo); - Parameters.Add('can_post_messages', CanPostMessages); - Parameters.Add('can_edit_messages', CanEditMessages); - Parameters.Add('can_delete_messages', CanDeleteMessages); - Parameters.Add('can_invite_users', CanInviteUsers); - Parameters.Add('can_restrict_members', CanRestrictMembers); - Parameters.Add('can_pin_messages', CanPinMessages); - Parameters.Add('can_promote_members', CanPromoteMembers); - Result := ExecuteMethod('promoteChatMember', Parameters); - finally - Parameters.Free; - end; + Result := GetArrayFromMethod(TtgGameHighScore, RequestAPI('getGameHighScores', [// + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('inline_message_id', InlineMessageId, 0, True)])) end; -function TTelegramBot.RestrictChatMember(const ChatId: TValue; const UserId, UntilDate: Int64; const CanSendMessages, CanSendMediaMessages, CanSendOtherMessages, CanAddWebPagePreviews: Boolean): Boolean; -var - Parameters: TDictionary; +function TTelegramBot.GetGameHighScores(const UserId, ChatId, MessageId: Int64): TArray; begin - Parameters := TDictionary.Create; - try - Parameters.Add('chat_id', ChatId); - Parameters.Add('user_id', UserId); - Parameters.Add('until_date', UntilDate); - Parameters.Add('can_send_messages', CanSendMessages); - Parameters.Add('can_send_media_messages', CanSendMediaMessages); - Parameters.Add('can_send_other_messages', CanSendOtherMessages); - Parameters.Add('can_add_web_page_previews', CanAddWebPagePreviews); - Result := ExecuteMethod('restrictChatMember', Parameters); - finally - Parameters.Free; - end; + Result := GetArrayFromMethod(TtgGameHighScore, RequestAPI('getGameHighScores', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, 0, True)])) +end; + +function TTelegramBot.SendGame(const ChatId: Int64; const GameShortName: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; +begin + Result := TTgMessage.Create(RequestAPI('sendGame', [// + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('game_short_name', GameShortName, '', True), // + TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // + TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, False, False), // + TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False)])); +end; + +function TTelegramBot.SetGameScore(const UserId, Score: Int64; const InlineMessageId: string; const Force, DisableEditMessage: Boolean): ITgMessage; +begin + Result := TTgMessage.Create(RequestAPI('setGameScore', [// + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('score', Score, 0, True), // + TtgApiParameter.Create('force', Force, False, False), // + TtgApiParameter.Create('disable_edit_message', DisableEditMessage, False, False), // + TtgApiParameter.Create('inline_message_id', InlineMessageId, 0, True)])); +end; + +function TTelegramBot.SetGameScore(const UserId, Score, ChatId, MessageId: Int64; const Force, DisableEditMessage: Boolean): ITgMessage; +begin + Result := TTgMessage.Create(RequestAPI('setGameScore', [// + TtgApiParameter.Create('user_id', UserId, 0, True), // + TtgApiParameter.Create('score', Score, nil, True), // + TtgApiParameter.Create('force', Force, False, False), // + TtgApiParameter.Create('disable_edit_message', DisableEditMessage, False, False), // + TtgApiParameter.Create('chat_id', ChatId, 0, True), // + TtgApiParameter.Create('message_id', MessageId, 0, True)])); end; {$ENDREGION} diff --git a/Source/TelegAPI.Bot.pas b/Source/TelegAPI.Bot.pas index a922070..63830fb 100644 --- a/Source/TelegAPI.Bot.pas +++ b/Source/TelegAPI.Bot.pas @@ -216,7 +216,7 @@ interface const DisableWebPagePreview: Boolean = False; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to forward messages of any kind. /// @@ -293,7 +293,7 @@ interface const Caption: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send audio files, if you want Telegram clients to /// display them in the music player. Your audio must be in the .mp3 @@ -347,7 +347,7 @@ interface const Performer: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send general files. /// @@ -390,7 +390,7 @@ interface const Caption: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send video files, Telegram clients support mp4 /// videos (other formats may be sent as Document). @@ -445,7 +445,7 @@ interface const Height: Int64 = 0; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send audio files, if you want Telegram clients to @@ -492,7 +492,7 @@ interface const Duration: Int64 = 0; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// As of /// v.4.0, Telegram clients support rounded square mp4 videos of up @@ -541,7 +541,7 @@ interface const Length: Int64 = 0; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send point on the map. @@ -576,7 +576,7 @@ interface const LivePeriod: Int64 = 0; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send information about a venue. /// @@ -617,7 +617,7 @@ interface const Venue: TtgVenue; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to send phone contacts. /// @@ -651,7 +651,7 @@ interface const Contact: TtgContact; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method when you need to tell the user that something is /// happening on the bot's side. The status is set for 5 seconds or less @@ -911,13 +911,13 @@ interface const Text: string; // const ParseMode: TtgParseMode = TtgParseMode.Default; // const DisableWebPagePreview: Boolean = False; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; function EditMessageText(// const InlineMessageId: string; // const Text: string; // const ParseMode: TtgParseMode = TtgParseMode.Default; // const DisableWebPagePreview: Boolean = False; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; /// /// Use this method to edit captions of messages sent by the bot or via /// the bot (for inline bots). @@ -950,12 +950,12 @@ interface const ChatId: TValue; // const MessageId: Int64; // const Caption: string; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; { TODO -oM.E.Sysoev -cGeneral : Create Documentatiom } function EditMessageCaption(// const InlineMessageId: string; // const Caption: string; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to edit live location messages sent by the bot or via @@ -986,7 +986,7 @@ interface const ChatId: TValue; // const MessageId: Int64; // const Location: TtgLocation; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to edit live location messages sent by the bot or via /// the bot (for inline bots). A location can be edited until its @@ -1019,7 +1019,7 @@ interface function editMessageLiveLocation(// const InlineMessageId: string; // const Location: TtgLocation; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to stop updating a live location message sent by the @@ -1044,7 +1044,7 @@ interface function stopMessageLiveLocation(// const ChatId: TValue; // const MessageId: Int64; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to stop updating a live location message sent by the /// bot or via the bot (for inline bots) before live_period expires. @@ -1062,7 +1062,7 @@ interface /// function stopMessageLiveLocation(// const InlineMessageId: string; // - const ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; /// /// Use this method to edit only the reply markup of messages sent by the /// bot or via the bot (for inline bots). @@ -1086,7 +1086,7 @@ interface function EditMessageReplyMarkup(// const ChatId: TValue; // const MessageId: Int64; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; /// /// Use this method to edit only the reply markup of messages sent by the /// bot or via the bot (for inline bots). @@ -1104,7 +1104,7 @@ interface /// function EditMessageReplyMarkup(// const InlineMessageId: string; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; /// /// Use this method to delete a message. /// @@ -1283,7 +1283,7 @@ interface const IsFlexible: Boolean = False; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// If you sent an invoice requesting a shipping address and the /// parameter is_flexible was specified, the Bot API will send an Update @@ -1309,10 +1309,11 @@ interface /// unavailable'). Telegram will display this message to the user. /// /// - function AnswerShippingQuery(// + function AnswerShippingQueryGood(// + const ShippingQueryId: string; // + const ShippingOptions: TArray): Boolean; + function AnswerShippingQueryBad(// const ShippingQueryId: string; // - const Ok: Boolean; // - const ShippingOptions: TArray; // const ErrorMessage: string): Boolean; /// /// Once the user has confirmed their payment and shipping details, the @@ -1344,10 +1345,11 @@ interface /// after the pre-checkout query was sent. /// /// - function AnswerPreCheckoutQuery(// + function AnswerPreCheckoutQueryGood(// + const PreCheckoutQueryId: string): Boolean; + function AnswerPreCheckoutQueryBad(// const PreCheckoutQueryId: string; // - const Ok: Boolean; // - const ErrorMessage: string = ''): Boolean; + const ErrorMessage: string): Boolean; {$ENDREGION} {$REGION 'Games'} /// @@ -1382,7 +1384,7 @@ interface const GameShortName: string; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to set the score of the specified user in a game. /// @@ -1422,11 +1424,16 @@ interface function SetGameScore(// const UserId: Int64; // const Score: Int64; // + const InlineMessageId: string; // const Force: Boolean = False; // - const DisableEditMessage: Boolean = False; // - const ChatId: Int64 = 0; // - const MessageId: Int64 = 0; // - const InlineMessageId: string = ''): ITgMessage; + const DisableEditMessage: Boolean = False): ITgMessage; overload; + function SetGameScore(// + const UserId: Int64; // + const Score: Int64; // + const ChatId: Int64; // + const MessageId: Int64; // + const Force: Boolean = False; // + const DisableEditMessage: Boolean = False): ITgMessage; overload; /// /// Use this method to get data for high score tables. Will return the /// score of the specified user and several of his neighbors in a game. @@ -1459,11 +1466,13 @@ interface /// /// Official API /// + function GetGameHighScores(// + const UserId: Int64; // + const InlineMessageId: string = ''): TArray; overload; function GetGameHighScores(// const UserId: Int64; // const ChatId: Int64 = 0; // - const MessageId: Int64 = 0; // - const InlineMessageId: string = ''): TArray; + const MessageId: Int64 = 0): TArray; overload; {$ENDREGION} {$REGION 'Manage groups and channels'} /// @@ -1729,7 +1738,7 @@ interface const Sticker: TValue; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // - const ReplyMarkup: IReplyMarkup = nil): ITgMessage; + ReplyMarkup: IReplyMarkup = nil): ITgMessage; /// /// Use this method to get a sticker set. /// diff --git a/Source/TelegAPi.CoreAPI.Parameter.pas b/Source/TelegAPi.CoreAPI.Parameter.pas index 0104087..f1ffeaa 100644 --- a/Source/TelegAPi.CoreAPI.Parameter.pas +++ b/Source/TelegAPi.CoreAPI.Parameter.pas @@ -17,6 +17,9 @@ TtgApiParameter = class end; implementation + +uses + System.SysUtils; { TtgApiParameter } constructor TtgApiParameter.Create(const AKey: string; AValue, ADefaultValue: TValue; ARequired: Boolean); @@ -29,7 +32,7 @@ constructor TtgApiParameter.Create(const AKey: string; AValue, ADefaultValue: TV function TtgApiParameter.IsDefaultValue: Boolean; begin - Result := Value.GetReferenceToRawData = DefaultValue.GetReferenceToRawData; + Result := Value.AsVariant = DefaultValue.AsVariant; // <-- DANGER end; function TtgApiParameter.Skip: Boolean; diff --git a/Source/TelegAPi.CoreAPI.Request.pas b/Source/TelegAPi.CoreAPI.Request.pas index af5feda..8a6c1ec 100644 --- a/Source/TelegAPi.CoreAPI.Request.pas +++ b/Source/TelegAPi.CoreAPI.Request.pas @@ -10,7 +10,8 @@ interface System.Net.Mime, System.SysUtils, TelegAPi.CoreAPI.Parameter, - TelegAPI.Bot.Impl; + TelegAPI.Bot.Impl, + System.Classes; type TtgApiRequest = class @@ -21,12 +22,14 @@ TtgApiRequest = class FMethod: string; FParams: TObjectList; FHttp: THTTPClient; - FOnReceive: TProc; + FOnReceive: TProc; FTelega: TTelegramBot; + FOnSend: TProc; protected function DoPost: IHTTPResponse; function DoGet: IHTTPResponse; procedure FillFormData(var AForm: TMultipartFormData); + function StreamToString(Stream: TMemoryStream): string; public constructor Create(Sender: TTelegramBot; const AMethod: string); function Execute: IHttpResponse; @@ -34,7 +37,8 @@ TtgApiRequest = class function GetUrl: string; destructor Destroy; override; property Parameters: TObjectList read FParams write FParams; - property OnReceive: TProc read FOnReceive write FOnReceive; + property OnReceive: TProc read FOnReceive write FOnReceive; + property OnSend: TProc read FOnSend write FOnSend; end; implementation @@ -65,6 +69,8 @@ destructor TtgApiRequest.Destroy; function TtgApiRequest.DoGet: IHTTPResponse; begin Result := FHttp.Get(GetUrl); + if Assigned(OnSend) then + OnSend(GetUrl, ''); end; function TtgApiRequest.DoPost: IHTTPResponse; @@ -75,6 +81,8 @@ function TtgApiRequest.DoPost: IHTTPResponse; try FillFormData(PostData); Result := FHttp.Post(GetUrl, PostData); + if Assigned(OnSend) then + OnSend(GetUrl, StreamToString(PostData.Stream)); finally PostData.Free; end; @@ -87,6 +95,8 @@ function TtgApiRequest.Execute: IHttpResponse; Result := DoPost else Result := DoGet; + if Assigned(OnReceive) then + OnReceive(Result.ContentAsString); end; function TtgApiRequest.ExecuteAsString: string; @@ -142,5 +152,19 @@ function TtgApiRequest.GetUrl: string; Result := SERVER_URL + FTelega.Token + '/' + FMethod; end; +function TtgApiRequest.StreamToString(Stream: TMemoryStream): string; +var + LStrings: TStringList; +begin + LStrings := TStringList.Create; + try + Stream.Position := 0; + LStrings.LoadFromStream(Stream, TEncoding.UTF8); + Result := LStrings.Text; + finally + LStrings.Free; + end; +end; + end. From 1e4b56a3cdd49617a69265a1438880379af5b771 Mon Sep 17 00:00:00 2001 From: Sysoev Maxim Date: Thu, 7 Dec 2017 10:20:40 +0200 Subject: [PATCH 05/14] =?UTF-8?q?[=20WIP=20]=20=D0=A3=D0=BB=D1=83=D1=87?= =?UTF-8?q?=D1=88=D0=B5=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BB=D0=B0=D1=81?= =?UTF-8?q?=D1=81=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BE=D0=BA=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2.=20?= =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BF=D0=BE=D0=B4=D0=B4?= =?UTF-8?q?=D0=B5=D1=80=D0=B6=D0=B8=D0=B2=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20=D0=A4=D0=B0?= =?UTF-8?q?=D0=B9=D0=BB=D0=BE=D0=B2,=20=D0=9F=D0=BE=D1=82=D0=BE=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2,=20=D0=A1=D1=81=D1=8B=D0=BB=D0=BE=D0=BA=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B8=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20=D0=98=D0=94=20=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=D0=B5=D0=B5=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/Console/ConsoleBot.dproj | 2 +- Demo/EchoBot/EchoBot.Main.fmx | 1 - Demo/EchoBot/EchoBot.Main.pas | 18 +- Demo/EchoBot/EchoBot.dproj | 517 +++++++++--------- Install/TelegaPi.dproj | 386 ++++++------- Source/TelegAPI.Bot.Impl.pas | 7 +- Source/TelegAPI.Bot.pas | 3 +- .../TelegAPI.CoreAPI.ParameterConverter.pas | 24 +- Source/TelegAPi.CoreAPI.Request.pas | 75 ++- Source/TelegAPi.Types.pas | 94 ++-- 10 files changed, 577 insertions(+), 550 deletions(-) diff --git a/Demo/Console/ConsoleBot.dproj b/Demo/Console/ConsoleBot.dproj index 9c7c9bb..559b537 100644 --- a/Demo/Console/ConsoleBot.dproj +++ b/Demo/Console/ConsoleBot.dproj @@ -37,7 +37,7 @@ ..\..\dcu\$(Platform)-$(Config) false - ..\..\Bin\$(Platform)-$(Config) + ..\..\..\Bin\$(Platform)-$(Config) false false false diff --git a/Demo/EchoBot/EchoBot.Main.fmx b/Demo/EchoBot/EchoBot.Main.fmx index 487a3d9..acd1742 100644 --- a/Demo/EchoBot/EchoBot.Main.fmx +++ b/Demo/EchoBot/EchoBot.Main.fmx @@ -44,7 +44,6 @@ object Main: TMain Touch.InteractiveGestures = [LongTap, DoubleTap] Align = Client TabOrder = 1 - Text = '283107814:AAF9VZC6TRv6qKmOMCsLFoI8SBlV_xFMI80' Margins.Right = 5.000000000000000000 Size.Width = 346.000000000000000000 Size.Height = 23.000000000000000000 diff --git a/Demo/EchoBot/EchoBot.Main.pas b/Demo/EchoBot/EchoBot.Main.pas index 17e8499..521363e 100644 --- a/Demo/EchoBot/EchoBot.Main.pas +++ b/Demo/EchoBot/EchoBot.Main.pas @@ -150,9 +150,9 @@ procedure TMain.swtchTokenSwitch(Sender: TObject); procedure TMain.SendPhoto(Msg: ITgMessage); const - PATH_PHOTO = 'C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg'; -var - LFile: TtgFileToSend; + PATH_PHOTO = 'D:\git\Мои проекты\ms301-TelegAPI\Install\pJNqeRflXYU.png'; +//var +// LFile: TtgFileToSend; begin tgBot.SendChatAction(Msg.Chat.Id, TtgSendChatAction.UploadPhoto); if not TFile.Exists(PATH_PHOTO) then @@ -160,12 +160,12 @@ procedure TMain.SendPhoto(Msg: ITgMessage); WriteLine('Change path to photo in metod: TMain.SendPhoto'); Exit; end; - LFile := TtgFileToSend.Create(PATH_PHOTO); - try - tgBot.SendPhoto(Msg.Chat.Id, LFile, 'Nice Picture'); - finally - LFile.Free; - end; +// LFile := TtgFileToSend.Create(PATH_PHOTO); +// try + tgBot.SendPhoto(Msg.Chat.Id, TtgFileToSend.FromFile(PATH_PHOTO), 'Nice Picture'); +// finally +// LFile.Free; +// end; end; procedure TMain.SendInline; diff --git a/Demo/EchoBot/EchoBot.dproj b/Demo/EchoBot/EchoBot.dproj index c6b145b..bde90b4 100644 --- a/Demo/EchoBot/EchoBot.dproj +++ b/Demo/EchoBot/EchoBot.dproj @@ -14,48 +14,48 @@ true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true + true Cfg_1 true - true + true - true - Base true + Base + true - true + true Cfg_2 true - true + true - true + true Cfg_2 true - true + true true @@ -70,7 +70,7 @@ true ..\..\DCU\$(Platform)-$(Config) false - ..\..\Bin\$(Platform)-$(Config) + ..\..\..\Bin\$(Platform)-$(Config) false false false @@ -101,7 +101,6 @@ Debug - ..\bin\$(Platform)-$(Config) Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;TelegaPiBot;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;emshosting;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) $(BDS)\bin\default_app.manifest @@ -152,10 +151,6 @@
Main
fmx - - Cfg_2 - Base - Base @@ -163,6 +158,10 @@ Cfg_1 Base + + Cfg_2 + Base + Delphi.Personality.12 @@ -175,54 +174,56 @@ Microsoft Office 2000 Sample Automation Server Wrapper Components Microsoft Office XP Sample Automation Server Wrapper Components - Component Tray - (untitled) - - - ic_launcher.png + + true - - - ic_launcher.png + + true - - - libEchoBot.so + + true - + + + true + + + ic_launcher.png true - - + + + ic_launcher.png true - + - splash_image.png + ic_launcher.png true - - + + + ic_launcher.png true - + - splash_image.png + ic_launcher.png true @@ -232,108 +233,132 @@ true - + splash_image.png true - + + splash_image.png true - - + + + splash_image.png true - + - ic_launcher.png + libEchoBot.so true - + libEchoBot.so true - - - EchoBot.exe + + true - + - ic_launcher.png true - - + + + classes.dex true - + libEchoBot.so true - + true - + - classes.dex true - - + + + EchoBot.exe true - + + + Contents\MacOS + 0 + + + 1 + + + Contents\MacOS + 1 + + + - true + classes + 1 - - - + + + + library\lib\armeabi-v7a 1 - + + + + library\lib\armeabi 1 - - - Contents\Resources + + + library\lib\mips 1 - + - classes + library\lib\armeabi-v7a 1 - - - Contents\MacOS - 0 + + + res\drawable + 1 - + + + + res\values 1 - - Contents\MacOS + + + + res\drawable 1 @@ -343,47 +368,65 @@ 1 - + - library\lib\mips + res\drawable-ldpi 1 - - + + + res\drawable-mdpi 1 - + + + + res\drawable-hdpi 1 - + + + + res\drawable-xhdpi 1 - - + + + res\drawable-small 1 - + + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge 1 + + 0 - + 1 Contents\MacOS 1 - - library\lib\armeabi-v7a - 1 - - - 1 - @@ -395,170 +438,158 @@ .framework - + - 1 - - - 1 + 0 + .dll;.bpl - - - + 1 + .dylib - + + Contents\MacOS 1 + .dylib 1 + .dylib - - 1 + .dylib - - 1 + + + + 0 + .bpl - + 1 + .dylib - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + + Contents\MacOS 1 + .dylib - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 + .dylib - - - - library\lib\armeabi + 1 + .dylib - - - 1 + + + 0 - 1 + 0 + + + Contents\Resources\StartUp\ + 0 - 1 + 0 - - - - 1 + + 0 - - 1 + + 0 - + + + 1 - - - 0 - - + + + ..\ 1 + + - Contents\MacOS + Contents 1 - - + + + Contents\Resources 1 + + 1 1 - - - - res\drawable-normal - 1 + + 0 - - - - res\drawable-large + 1 - - - - res\drawable-xhdpi + + Contents\MacOS 1 - - - - Assets + + library\lib\armeabi-v7a 1 - - Assets + 1 - + - Assets 1 - Assets 1 - + - ..\ + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - ..\ + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - - - library\lib\armeabi-v7a + + 1 - - - - res\drawable-hdpi + 1 - - - Contents + + + ..\ 1 - - - + ..\ 1 - + 1 @@ -569,13 +600,7 @@ 1 - - - res\values - 1 - - - + 1 @@ -586,19 +611,27 @@ 1 - - - res\drawable-small + + + Assets + 1 + + + Assets 1 - - - res\drawable + + + Assets + 1 + + + Assets 1 - + 1 @@ -609,115 +642,79 @@ 1 - - + + 1 - - - - res\drawable + + 1 + + 1 - - - 0 + + + 1 - 0 - - - Contents\Resources\StartUp\ - 0 + 1 - 0 - - - 0 + 1 + + - 0 + 1 - - - - library\lib\armeabi-v7a + 1 - - - - res\drawable-mdpi + 1 - - - 0 - .bpl - - + + 1 - .dylib - - Contents\MacOS + 1 - .dylib 1 - .dylib + + 1 - .dylib - - - - res\drawable-xlarge + 1 - - - - res\drawable-ldpi + 1 - - - 0 - .dll;.bpl - - + + 1 - .dylib - - Contents\MacOS + 1 - .dylib 1 - .dylib - - - 1 - .dylib - - - + - - + + + + diff --git a/Install/TelegaPi.dproj b/Install/TelegaPi.dproj index 5de5fb2..c22f718 100644 --- a/Install/TelegaPi.dproj +++ b/Install/TelegaPi.dproj @@ -14,35 +14,35 @@ true
- true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true - Base true + Base + true All @@ -57,8 +57,10 @@ false true true - + + + false TelegaPi @@ -133,10 +135,6 @@ $(PreBuildEvent)]]> - - Cfg_2 - Base - Base @@ -144,6 +142,10 @@ $(PreBuildEvent)]]> Cfg_1 Base + + Cfg_2 + Base + Delphi.Personality.12 @@ -170,12 +172,12 @@ $(PreBuildEvent)]]> true - + true - + true @@ -186,10 +188,12 @@ $(PreBuildEvent)]]> true - - + + + Contents\MacOS + 0 + - Contents\Resources 1 @@ -199,18 +203,15 @@ $(PreBuildEvent)]]> 1 - - - Contents\MacOS - 0 - - + + + library\lib\armeabi-v7a 1 - + - res\drawable-xxhdpi + library\lib\armeabi 1 @@ -220,40 +221,94 @@ $(PreBuildEvent)]]> 1 - - + + + library\lib\armeabi-v7a 1 - + + + + res\drawable 1 - + + + + res\values 1 - - + + + res\drawable 1 - + + + + res\drawable-xxhdpi 1 - - 0 + + + + res\drawable-ldpi + 1 - + + + + res\drawable-mdpi 1 - + + + + res\drawable-hdpi 1 + + - library\lib\armeabi-v7a + res\drawable-xhdpi + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge 1 + + + + 0 + 1 + + 1 + @@ -264,101 +319,124 @@ $(PreBuildEvent)]]> .framework - + - 1 + 0 + .dll;.bpl - + 1 + .dylib - - - 1 + + + 0 + .bpl 1 + .dylib + + + 1 + .dylib 1 + .dylib - - 1 + .dylib + + + + + 0 - 1 + 0 + + + 0 - 1 + 0 - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 + + 0 - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 + + 0 - + - library\lib\armeabi 1 - - - + + + + + Contents\Resources 1 + + 1 1 - - 0 - + 1 1 - - + + library\lib\armeabi-v7a + 1 + 1 + + + + 1 + + + 1 + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - - - res\drawable-normal + + + + + 1 - - - - res\drawable-large + 1 - - - - res\drawable-xhdpi + 1 @@ -382,22 +460,18 @@ $(PreBuildEvent)]]> 1 - - - - library\lib\armeabi-v7a + + 1 - - - - res\drawable-hdpi + + 1 + + 1 - - - + 1 @@ -408,12 +482,6 @@ $(PreBuildEvent)]]> 1 - - - res\values - 1 - - 1 @@ -425,19 +493,7 @@ $(PreBuildEvent)]]> 1 - - - res\drawable-small - 1 - - - - - res\drawable - 1 - - - + 1 @@ -448,100 +504,46 @@ $(PreBuildEvent)]]> 1 - - - 1 - - - - - res\drawable + + 1 - - - - 0 - - 0 - - - 0 + 1 - 0 - - - 0 - - - 0 - - - - - library\lib\armeabi-v7a 1 - - - res\drawable-mdpi + + 1 - - - - 0 - .bpl - 1 - .dylib - - - 1 - .dylib 1 - .dylib - - - 1 - .dylib - - - res\drawable-xlarge + + 1 - - - - res\drawable-ldpi + 1 - - - - 0 - .dll;.bpl - - + 1 - .dylib - - - + - - + + + + @@ -556,51 +558,51 @@ $(PreBuildEvent)]]> + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index 27db8be..decfb32 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -321,7 +321,8 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// End; /// function SendPhoto(// - const ChatId, Photo: TValue; // + const ChatId: TValue; // + const Photo: TtgFileToSend; // const Caption: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // @@ -2150,11 +2151,11 @@ function TTelegramBot.sendMediaGroup(const ChatId: TValue; const AMedia: TArray< ])); end; -function TTelegramBot.SendPhoto(const ChatId, Photo: TValue; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendPhoto(const ChatId: TValue; const Photo: TtgFileToSend; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendPhoto', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // - TtgApiParameter.Create('photo', Photo, '', True), // + TtgApiParameter.Create('photo', Photo, nil, True), // TtgApiParameter.Create('caption', Caption, '', False), // TtgApiParameter.Create('disable_notification', DisableNotification, False, False), // TtgApiParameter.Create('reply_to_message_id', ReplyToMessageId, 0, False), // diff --git a/Source/TelegAPI.Bot.pas b/Source/TelegAPI.Bot.pas index 63830fb..2063562 100644 --- a/Source/TelegAPI.Bot.pas +++ b/Source/TelegAPI.Bot.pas @@ -289,7 +289,8 @@ interface /// End; /// function SendPhoto(// - const ChatId, Photo: TValue; // + const ChatId: TValue; // + const Photo: TtgFileToSend; // const Caption: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // diff --git a/Source/TelegAPI.CoreAPI.ParameterConverter.pas b/Source/TelegAPI.CoreAPI.ParameterConverter.pas index d144c73..23913a5 100644 --- a/Source/TelegAPI.CoreAPI.ParameterConverter.pas +++ b/Source/TelegAPI.CoreAPI.ParameterConverter.pas @@ -9,7 +9,7 @@ interface System.SysUtils, System.TypInfo, TelegAPI.Types, - TelegAPi.CoreAPI.Parameter; + TelegAPI.CoreAPI.Parameter; type /// @@ -31,6 +31,7 @@ TtgParamConverter = class ParamLoaders: TDictionary; constructor Create; destructor Destroy; override; + function IsSupported(Param: TtgApiParameter): Boolean; function ApplyParamToFormData(const AParam: TtgApiParameter; var Form: TMultipartFormData): Boolean; end; @@ -76,6 +77,11 @@ destructor TtgParamConverter.Destroy; inherited; end; +function TtgParamConverter.IsSupported(Param: TtgApiParameter): Boolean; +begin + Result := ParamLoaders.ContainsKey(Param.Value.TypeInfo); +end; + procedure TtgParamConverter.AddInt64(var AFormData: TMultipartFormData; AParam: TtgApiParameter); begin AFormData.AddField(AParam.Key, AParam.Value.AsInt64.ToString); @@ -91,10 +97,18 @@ procedure TtgParamConverter.AddClass_TtgFileToSend(var AFormData: TMultipartForm LFileToSent: TtgFileToSend; begin LFileToSent := AParam.Value.AsType; - if Assigned(LFileToSent.Content) then - AFormData.AddStream(AParam.Key, LFileToSent.Content, LFileToSent.FileName) - else - AFormData.AddFile(AParam.Key, LFileToSent.FileName); + try + if LFileToSent.Tag = TtgFileToSend.FILE_TO_SEND_STREAM then + AFormData.AddStream(AParam.Key, LFileToSent.Content, LFileToSent.Data) + else if LFileToSent.Tag = TtgFileToSend.FILE_TO_SEND_FILE then + AFormData.AddFile(AParam.Key, LFileToSent.Data) + else if (LFileToSent.Tag = TtgFileToSend.FILE_TO_SEND_ID) or (LFileToSent.Tag = TtgFileToSend.FILE_TO_SEND_URL) then + AFormData.AddField(AParam.Key, LFileToSent.Data) + else + raise Exception.Create('Cant convert TTgFileToSend: Unknown prototype tag'); + finally + LFileToSent.Free; + end; end; end. diff --git a/Source/TelegAPi.CoreAPI.Request.pas b/Source/TelegAPi.CoreAPI.Request.pas index 8a6c1ec..f17c546 100644 --- a/Source/TelegAPi.CoreAPI.Request.pas +++ b/Source/TelegAPi.CoreAPI.Request.pas @@ -10,7 +10,7 @@ interface System.Net.Mime, System.SysUtils, TelegAPi.CoreAPI.Parameter, - TelegAPI.Bot.Impl, + TelegAPi.Bot.Impl, System.Classes; type @@ -32,7 +32,7 @@ TtgApiRequest = class function StreamToString(Stream: TMemoryStream): string; public constructor Create(Sender: TTelegramBot; const AMethod: string); - function Execute: IHttpResponse; + function Execute: IHTTPResponse; function ExecuteAsString: string; function GetUrl: string; destructor Destroy; override; @@ -47,7 +47,8 @@ implementation TelegAPi.Types, TelegAPi.Types.ReplyMarkups, REST.Json, - TelegaPi.Exceptions; + TelegAPi.Exceptions, + TelegAPi.CoreAPI.ParameterConverter; { TtgApiRequest } @@ -75,9 +76,9 @@ function TtgApiRequest.DoGet: IHTTPResponse; function TtgApiRequest.DoPost: IHTTPResponse; var - PostData: TMultiPartFormData; + PostData: TMultipartFormData; begin - PostData := TMultiPartFormData.Create; + PostData := TMultipartFormData.Create; try FillFormData(PostData); Result := FHttp.Post(GetUrl, PostData); @@ -88,7 +89,7 @@ function TtgApiRequest.DoPost: IHTTPResponse; end; end; -function TtgApiRequest.Execute: IHttpResponse; +function TtgApiRequest.Execute: IHTTPResponse; begin FHttp.ProxySettings := FTelega.ProxySettings; if Parameters.Count > 0 then @@ -107,43 +108,35 @@ function TtgApiRequest.ExecuteAsString: string; procedure TtgApiRequest.FillFormData(var AForm: TMultipartFormData); var LParam: TtgApiParameter; + ParamConverter: TtgParamConverter; begin - for LParam in Parameters do - begin - // skip all empty params - if LParam.Skip then - Continue; - if LParam.Required and (LParam.IsDefaultValue or LParam.Value.IsEmpty) then - FTelega.ExceptionManager.HaveGlobalExeption('TtgApiRequest.FillFormData', ETelegramException.Create('Not assigned required data')); - if LParam.Value.IsTypethen - begin - AForm.AddField(LParam.Key, LParam.Value.AsString); - end - else if LParam.Value.IsTypethen // or Integer - begin - AForm.AddField(LParam.Key, LParam.Value.AsInt64.ToString); - end - else if LParam.Value.IsTypethen - begin - AForm.AddField(LParam.Key, LParam.Value.AsBoolean.ToString(TUseBoolStrs.True)); - end - else if LParam.Value.IsTypethen - begin - AForm.AddField(LParam.Key, LParam.Value.AsBoolean.ToString(TUseBoolStrs.True)); - end - else if LParam.Value.Kind = tkClass then // last variant to search + ParamConverter := TtgParamConverter.Create; + try + for LParam in Parameters do begin - { TODO -oOwner -cGeneral : } - if not LParam.Value.IsEmpty then + // skip all empty params + if LParam.Skip then + Continue; + if LParam.Required and (LParam.IsDefaultValue or LParam.Value.IsEmpty) then + FTelega.ExceptionManager.HaveGlobalExeption('TtgApiRequest.FillFormData', ETelegramException.Create('Not assigned required data')); + if ParamConverter.IsSupported(LParam) then + ParamConverter.ApplyParamToFormData(LParam, AForm) + else if LParam.Value.Kind = tkClass then // last variant to search begin - if LParam.Value.IsTypethen - AForm.AddField(LParam.Key, TJson.ObjectToJsonString(LParam.Value.AsObject)) - else - FTelega.ExceptionManager.HaveGlobalExeption('TTelegramBot.ParamsToFormData', Exception.Create('Unknown object')); - end; - end - else - FTelega.ExceptionManager.HaveGlobalExeption('ParamsToFormData', ETelegramDataConvert.Create('Check parameter type ' + LParam.Value.ToString)) + { TODO -oOwner -cGeneral : } + if not LParam.Value.IsEmpty then + begin + if LParam.Value.IsTypethen + AForm.AddField(LParam.Key, TJson.ObjectToJsonString(LParam.Value.AsObject)) + else + FTelega.ExceptionManager.HaveGlobalExeption('TTelegramBot.ParamsToFormData', Exception.Create('Unknown object')); + end; + end + else + FTelega.ExceptionManager.HaveGlobalExeption('ParamsToFormData', ETelegramDataConvert.Create('Check parameter type ' + LParam.Value.ToString)) + end; + finally + ParamConverter.Free; end; end; @@ -159,7 +152,7 @@ function TtgApiRequest.StreamToString(Stream: TMemoryStream): string; LStrings := TStringList.Create; try Stream.Position := 0; - LStrings.LoadFromStream(Stream, TEncoding.UTF8); + LStrings.LoadFromStream(Stream); Result := LStrings.Text; finally LStrings.Free; diff --git a/Source/TelegAPi.Types.pas b/Source/TelegAPi.Types.pas index 0d94f00..9d753fd 100644 --- a/Source/TelegAPi.Types.pas +++ b/Source/TelegAPi.Types.pas @@ -379,19 +379,6 @@ interface function AllowedUpdates: TArray; end; - ItgFileToSend = interface - ['{91FF9D95-7BF3-49B3-B7CB-6C836305FEC2}'] - function getContent: TStream; - end; - - TtgFileToSend = class - public - FileName: string; - Content: TStream; - constructor Create(const AFileName: string); overload; - constructor Create(AContent: TStream; const AFileName: string); overload; - end; - TtgInputMedia = class private FType: string; @@ -414,35 +401,30 @@ TtgInputMediaVideo = class(TtgInputMedia) constructor Create(AMedia: TValue; const ACaption: string = ''; AWidth: Integer = 0; AHeight: Integer = 0; ADuration: Integer = 0); reintroduce; end; + TtgFileToSend = class + public + const + FILE_TO_SEND_ERROR = 254; + FILE_TO_SEND_ID = 0; + FILE_TO_SEND_URL = 1; + FILE_TO_SEND_FILE = 2; + FILE_TO_SEND_STREAM = 3; + public + Data: string; + Content: TStream; + Tag: Byte; + constructor Create(const ATag: Byte = FILE_TO_SEND_ERROR; AData: string = ''; AContent: TStream = nil); + class function FromFile(const AFileName: string): TtgFileToSend; + class function FromID(const AID: string): TtgFileToSend; + class function FromURL(const AURL: string): TtgFileToSend; + class function FromStream(const AContent: TStream; const AFileName: string): TtgFileToSend; + end; + implementation uses System.SysUtils; -{ TtgFileToSend } -constructor TtgFileToSend.Create(const AFileName: string); -begin - Content := nil; - FileName := AFileName; - if not FileExists(AFileName) then - raise EFileNotFoundException.CreateFmt('File %S not found!', [AFileName]); -end; - -constructor TtgFileToSend.Create(AContent: TStream; const AFileName: string); -begin - FileName := AFileName; - Content := AContent; - // I guess, in most cases, AFilename param should contain a non-empty string. - // It is odd to receive a file with filename and - // extension which both are not connected with its content. - if AFileName.IsEmpty then - raise Exception.Create('TtgFileToSend: Filename is empty!'); - if not Assigned(AContent) then - raise EStreamError.Create('Stream not assigned!'); - FileName := AFileName; - Content := AContent; -end; - { TtgInputMedia } constructor TtgInputMedia.Create(AMedia: TValue; const ACaption: string); @@ -470,5 +452,43 @@ constructor TtgInputMediaVideo.Create(AMedia: TValue; const ACaption: string; AW Duration := ADuration; end; +{ TtgFileToSend } + +constructor TtgFileToSend.Create(const ATag: Byte; AData: string; AContent: TStream); +begin + Tag := ATag; + Data := AData; + Content := Content; +end; + +class function TtgFileToSend.FromFile(const AFileName: string): TtgFileToSend; +begin + if not FileExists(AFileName) then + raise EFileNotFoundException.CreateFmt('File %S not found!', [AFileName]); + Result := TtgFileToSend.Create(FILE_TO_SEND_FILE, AFileName, nil); +end; + +class function TtgFileToSend.FromID(const AID: string): TtgFileToSend; +begin + Result := TtgFileToSend.Create(FILE_TO_SEND_ID, AID, nil); +end; + +class function TtgFileToSend.FromStream(const AContent: TStream; const AFileName: string): TtgFileToSend; +begin + // I guess, in most cases, AFilename param should contain a non-empty string. + // It is odd to receive a file with filename and + // extension which both are not connected with its content. + if AFileName.IsEmpty then + raise Exception.Create('TtgFileToSend: Filename is empty!'); + if not Assigned(AContent) then + raise EStreamError.Create('Stream not assigned!'); + Result := TtgFileToSend.Create(FILE_TO_SEND_STREAM, AFileName, AContent); +end; + +class function TtgFileToSend.FromURL(const AURL: string): TtgFileToSend; +begin + Result := TtgFileToSend.Create(FILE_TO_SEND_URL, AURL, nil); +end; + end. From cbe2f731bdee90811a5071fa9c5bddbc50805f44 Mon Sep 17 00:00:00 2001 From: Sysoev Maxim Date: Thu, 7 Dec 2017 12:48:20 +0200 Subject: [PATCH 06/14] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BE?= =?UTF-8?q?=D0=BA=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2.=20=D0=A2=D0=B5?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=B8=D0=B2=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20=D0=A4=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2,=20=D0=9F=D0=BE=D1=82=D0=BE=D0=BA=D0=BE=D0=B2,=20?= =?UTF-8?q?=D0=A1=D1=81=D1=8B=D0=BB=D0=BE=D0=BA=20=D0=BD=D0=B0=20=D1=84?= =?UTF-8?q?=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B8=20=D0=BE=D1=82=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BA=D0=B0=20=D0=98=D0=94=20=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=B5=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/TelegAPI.Bot.Impl.pas | 26 +++++++++++-------- Source/TelegAPI.Bot.pas | 14 ++++++---- .../TelegAPI.CoreAPI.ParameterConverter.pas | 12 ++++----- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index decfb32..933d8b7 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -374,7 +374,8 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// sendVoice method instead. /// function SendAudio(// - const ChatId, Audio: TValue; // + const ChatId: TValue; // + const Audio: TtgFileToSend; // const Caption: string = ''; // const Duration: Int64 = 0; // const Performer: string = ''; // @@ -419,7 +420,8 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// this limit may be changed in the future. /// function SendDocument(// - const ChatId, Document: TValue; // + const ChatId: TValue; // + const Document: TtgFileToSend; // const Caption: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // @@ -471,7 +473,8 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// limit may be changed in the future. /// function SendVideo(// - const ChatId, Video: TValue; // + const ChatId: TValue; // + const Video: TtgFileToSend; // const Caption: string = ''; // const Duration: Int64 = 0; // const Width: Int64 = 0; // @@ -520,7 +523,8 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// limit may be changed in the future. /// function SendVoice(// - const ChatId, Voice: TValue; // + const ChatId: TValue; // + const Voice: TtgFileToSend; // const Caption: string = ''; // const Duration: Int64 = 0; // const DisableNotification: Boolean = False; // @@ -569,7 +573,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) /// function SendVideoNote(// const ChatId: TValue; // - const VideoNote: TValue; // + const VideoNote: TtgFileToSend; // const Duration: Int64 = 0; // const Length: Int64 = 0; // const DisableNotification: Boolean = False; // @@ -2191,7 +2195,7 @@ function TTelegramBot.SendVenue(const ChatId: TValue; const Venue: TtgVenue; con ])); end; -function TTelegramBot.SendVideo(const ChatId, Video: TValue; const Caption: string; const Duration, Width, Height: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendVideo(const ChatId: TValue; const Video: TtgFileToSend; const Caption: string; const Duration, Width, Height: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendVideo', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2206,7 +2210,7 @@ function TTelegramBot.SendVideo(const ChatId, Video: TValue; const Caption: stri ])); end; -function TTelegramBot.SendVideoNote(const ChatId, VideoNote: TValue; const Duration, Length: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendVideoNote(const ChatId: TValue; const VideoNote: TtgFileToSend; const Duration, Length: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendVideoNote', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2219,7 +2223,7 @@ function TTelegramBot.SendVideoNote(const ChatId, VideoNote: TValue; const Durat ])); end; -function TTelegramBot.SendVoice(const ChatId, Voice: TValue; const Caption: string; const Duration: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendVoice(const ChatId: TValue; const Voice: TtgFileToSend; const Caption: string; const Duration: Int64; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendVoice', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // @@ -2232,11 +2236,11 @@ function TTelegramBot.SendVoice(const ChatId, Voice: TValue; const Caption: stri ])); end; -function TTelegramBot.SendAudio(const ChatId, Audio: TValue; const Caption: string; const Duration: Int64; const Performer: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendAudio(const ChatId: TValue; const Audio: TtgFileToSend; const Caption: string; const Duration: Int64; const Performer: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendAudio', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // - TtgApiParameter.Create('audio', Audio, '', True), // + TtgApiParameter.Create('audio', Audio, nil, True), // TtgApiParameter.Create('duration', Duration, 0, False), // TtgApiParameter.Create('performer', Performer, '', False), // TtgApiParameter.Create('caption', Caption, 0, False), // @@ -2267,7 +2271,7 @@ function TTelegramBot.SendContact(const ChatId: TValue; const Contact: TtgContac ])); end; -function TTelegramBot.SendDocument(const ChatId, Document: TValue; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; +function TTelegramBot.SendDocument(const ChatId: TValue; const Document: TtgFileToSend; const Caption: string; const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: IReplyMarkup): ITgMessage; begin Result := TTgMessage.Create(RequestAPI('sendDocument', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // diff --git a/Source/TelegAPI.Bot.pas b/Source/TelegAPI.Bot.pas index 2063562..1e55901 100644 --- a/Source/TelegAPI.Bot.pas +++ b/Source/TelegAPI.Bot.pas @@ -342,7 +342,8 @@ interface /// sendVoice method instead. /// function SendAudio(// - const ChatId, Audio: TValue; // + const ChatId: TValue; // + const Audio: TtgFileToSend; // const Caption: string = ''; // const Duration: Int64 = 0; // const Performer: string = ''; // @@ -387,7 +388,8 @@ interface /// this limit may be changed in the future. /// function SendDocument(// - const ChatId, Document: TValue; // + const ChatId: TValue; // + const Document: TtgFileToSend; // const Caption: string = ''; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // @@ -439,7 +441,8 @@ interface /// limit may be changed in the future. /// function SendVideo(// - const ChatId, Video: TValue; // + const ChatId: TValue; // + const Video: TtgFileToSend; // const Caption: string = ''; // const Duration: Int64 = 0; // const Width: Int64 = 0; // @@ -488,7 +491,8 @@ interface /// limit may be changed in the future. /// function SendVoice(// - const ChatId, Voice: TValue; // + const ChatId: TValue; // + const Voice: TtgFileToSend; // const Caption: string = ''; // const Duration: Int64 = 0; // const DisableNotification: Boolean = False; // @@ -537,7 +541,7 @@ interface /// function SendVideoNote(// const ChatId: TValue; // - const VideoNote: TValue; // + const VideoNote: TtgFileToSend; // const Duration: Int64 = 0; // const Length: Int64 = 0; // const DisableNotification: Boolean = False; // diff --git a/Source/TelegAPI.CoreAPI.ParameterConverter.pas b/Source/TelegAPI.CoreAPI.ParameterConverter.pas index 23913a5..aeeedd2 100644 --- a/Source/TelegAPI.CoreAPI.ParameterConverter.pas +++ b/Source/TelegAPI.CoreAPI.ParameterConverter.pas @@ -98,14 +98,14 @@ procedure TtgParamConverter.AddClass_TtgFileToSend(var AFormData: TMultipartForm begin LFileToSent := AParam.Value.AsType; try - if LFileToSent.Tag = TtgFileToSend.FILE_TO_SEND_STREAM then - AFormData.AddStream(AParam.Key, LFileToSent.Content, LFileToSent.Data) - else if LFileToSent.Tag = TtgFileToSend.FILE_TO_SEND_FILE then - AFormData.AddFile(AParam.Key, LFileToSent.Data) - else if (LFileToSent.Tag = TtgFileToSend.FILE_TO_SEND_ID) or (LFileToSent.Tag = TtgFileToSend.FILE_TO_SEND_URL) then - AFormData.AddField(AParam.Key, LFileToSent.Data) + case LFileToSent.Tag of + TtgFileToSend.FILE_TO_SEND_STREAM: AFormData.AddStream(AParam.Key, LFileToSent.Content, LFileToSent.Data); + TtgFileToSend.FILE_TO_SEND_FILE: AFormData.AddFile(AParam.Key, LFileToSent.Data); + TtgFileToSend.FILE_TO_SEND_ID, + TtgFileToSend.FILE_TO_SEND_URL: AFormData.AddField(AParam.Key, LFileToSent.Data); else raise Exception.Create('Cant convert TTgFileToSend: Unknown prototype tag'); + end; finally LFileToSent.Free; end; From f2b32e43356a84b1fb4b0d8273fe09f9d2c84765 Mon Sep 17 00:00:00 2001 From: Sysoev Maxim Date: Thu, 7 Dec 2017 14:01:18 +0200 Subject: [PATCH 07/14] =?UTF-8?q?inline=20-=20=D0=BA=D0=BE=D0=BC=D0=B0?= =?UTF-8?q?=D0=BD=D0=B4=D1=8B=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D1=8E=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/EchoBot/EchoBot.Main.pas | 9 +-------- Source/TelegAPI.Utils.Json.pas | 3 ++- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Demo/EchoBot/EchoBot.Main.pas b/Demo/EchoBot/EchoBot.Main.pas index 521363e..4f6feff 100644 --- a/Demo/EchoBot/EchoBot.Main.pas +++ b/Demo/EchoBot/EchoBot.Main.pas @@ -150,9 +150,7 @@ procedure TMain.swtchTokenSwitch(Sender: TObject); procedure TMain.SendPhoto(Msg: ITgMessage); const - PATH_PHOTO = 'D:\git\Мои проекты\ms301-TelegAPI\Install\pJNqeRflXYU.png'; -//var -// LFile: TtgFileToSend; + PATH_PHOTO = 'Photo.png'; begin tgBot.SendChatAction(Msg.Chat.Id, TtgSendChatAction.UploadPhoto); if not TFile.Exists(PATH_PHOTO) then @@ -160,12 +158,7 @@ procedure TMain.SendPhoto(Msg: ITgMessage); WriteLine('Change path to photo in metod: TMain.SendPhoto'); Exit; end; -// LFile := TtgFileToSend.Create(PATH_PHOTO); -// try tgBot.SendPhoto(Msg.Chat.Id, TtgFileToSend.FromFile(PATH_PHOTO), 'Nice Picture'); -// finally -// LFile.Free; -// end; end; procedure TMain.SendInline; diff --git a/Source/TelegAPI.Utils.Json.pas b/Source/TelegAPI.Utils.Json.pas index 2ce190c..b3b3e7b 100644 --- a/Source/TelegAPI.Utils.Json.pas +++ b/Source/TelegAPI.Utils.Json.pas @@ -1,4 +1,4 @@ -unit TelegAPI.Utils.Json; +unit TelegAPI.Utils.Json; interface @@ -51,6 +51,7 @@ class function TJsonUtils.ArrayToJString(LArray: TArray): string; Result := Result + ','; end; Result := Result + ']'; + Result := Result.Replace('"inline_keyboard":null', '', [rfReplaceAll]);// какашечка end; { TBaseJson } From 125efe2158c682e1ec6dcc608e68596fb26dbbf3 Mon Sep 17 00:00:00 2001 From: Sysoev Maxim Date: Thu, 7 Dec 2017 15:38:20 +0200 Subject: [PATCH 08/14] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D0=B4?= =?UTF-8?q?=D1=83=D0=B1=D0=BB=D0=B8=D1=80=D1=83=D1=8E=D1=89=D0=B8=D0=B5=20?= =?UTF-8?q?xml-doc.=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20?= =?UTF-8?q?=D0=B2=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20=D0=BC=D0=B5?= =?UTF-8?q?=D1=82=D0=BE=D0=B4=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=D0=BD=D1=84=D0=BE?= =?UTF-8?q?=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8=20=D0=BE=20=D0=9A=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D0=BA=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/EchoBot/EchoBot.Main.pas | 8 + Source/TelegAPI.Bot.Impl.pas | 1590 +-------------------------------- 2 files changed, 27 insertions(+), 1571 deletions(-) diff --git a/Demo/EchoBot/EchoBot.Main.pas b/Demo/EchoBot/EchoBot.Main.pas index 4f6feff..2652ed9 100644 --- a/Demo/EchoBot/EchoBot.Main.pas +++ b/Demo/EchoBot/EchoBot.Main.pas @@ -56,6 +56,7 @@ TMain = class(TForm) procedure ParseTextMessage(Msg: ITgMessage); procedure ParsePhotoMessage(Msg: ITgMessage); procedure ParseLocationMessage(Msg: ITgMessage); + procedure ParseContactMessage(Msg: ITgMessage); public { Public declarations } end; @@ -79,6 +80,11 @@ procedure TMain.FormClose(Sender: TObject; var Action: TCloseAction); tgReceiverUI1.IsActive := False; end; +procedure TMain.ParseContactMessage(Msg: ITgMessage); +begin + WriteLine('Contact: ' + Msg.Contact.LastName + ' ' + Msg.Contact.FirstName + ' ' + Msg.Contact.PhoneNumber); +end; + procedure TMain.ParseLocationMessage(Msg: ITgMessage); begin WriteLine('Location: ' + Msg.Location.Longitude.ToString + ' ' + Msg.Location.Latitude.ToString); @@ -257,6 +263,8 @@ procedure TMain.tgReceiverUI1Message(ASender: TObject; AMessage: ITgMessage); ParsePhotoMessage(AMessage); TtgMessageType.LocationMessage: ParseLocationMessage(AMessage); + TtgMessageType.ContactMessage: + ParseContactMessage(AMessage); end; end; diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index 933d8b7..7df471b 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -46,201 +46,26 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) function GetExceptionManager: ItgExceptionHandler; procedure SetExceptionManager(const Value: ItgExceptionHandler); protected - /// - /// Мастер-функция для запросов на сервак - /// function RequestAPI(const Method: string; const Parameters: TArray): string; - public function ApiTest(const ARequest: string; const Parameters: TArray = nil): string; - {$REGION 'Getting updates'} - /// - /// - /// Используйте этот метод для получения обновлений используя long - /// polling. - /// - /// - /// Use this method to receive incoming updates using long polling. - /// - /// - /// - /// Identifier of the first update to be returned. Must be greater by one - /// than the highest among the identifiers of previously received - /// updates. By default, updates starting with the earliest unconfirmed - /// update are returned. An update is considered confirmed as soon as - /// getUpdates is called with an offset higher than its update_id. - /// The negative offset can be specified to retrieve updates starting - /// from -offset update from the end of the updates queue. All previous - /// updates will forgotten. - /// - /// - /// Количество обновлений которые могут прийти в одном запросе. - /// Допустимое значение от 1 до 100. По умолчанию - 100.Limits the number - /// of updates to be retrieved. Values between 1—100 are accepted. - /// Defaults to 100. - /// - /// - /// Timeout in seconds for long polling. Defaults to 0, i.e. usual short - /// polling - /// - /// - /// List the types of updates you want your bot to receive. For example, - /// specify [“message”, “edited_channel_post”, “callback_query”] to only - /// receive updates of these types. See Update for a complete list of - /// available update types. Specify an empty list to receive all updates - /// regardless of type (default). If not specified, the previous setting - /// will be used.

Please note that this parameter doesn't - /// affect updates created before the call to the getUpdates, so unwanted - /// updates may be received for a short period of time. - /// - /// - /// An Array of Update objects is returned. - /// - /// - /// 1. This method will not work if an outgoing webhook is set up. 2. In - /// order to avoid getting duplicate updates, recalculate offset after - /// each server response. - /// + public +{$REGION 'Getting updates'} function GetUpdates(// const Offset: Int64 = 0; // const Limit: Int64 = 100; // const Timeout: Int64 = 0; // const AllowedUpdates: TAllowedUpdates = UPDATES_ALLOWED_ALL): TArray; - /// - /// Use this method to specify a url and receive incoming updates via an - /// outgoing webhook. Whenever there is an update for the bot, we will - /// send an HTTPS POST request to the specified url, containing a - /// JSON-serialized Update. In case of an unsuccessful request, we will - /// give up after a reasonable amount of attempts. - /// - /// - /// HTTPS url to send updates to. Use an empty string to remove webhook - /// integration - /// - /// - /// Upload your public key certificate so that the root certificate in - /// use can be checked. See our self-signed guide for details. - /// - /// - /// Maximum allowed number of simultaneous HTTPS connections to the - /// webhook for update delivery, 1-100. Defaults to 40. Use lower values - /// to limit the load on your bot‘s server, and higher values to increase - /// your bot’s throughput. - /// - /// - /// List the types of updates you want your bot to receive. For example, - /// specify [“message”, “edited_channel_post”, “callback_query”] to only - /// receive updates of these types. See Update for a complete list of - /// available update types. Specify an empty list to receive all updates - /// regardless of type (default). If not specified, the previous setting - /// will be used.

Please note that this parameter doesn't - /// affect updates created before the call to the setWebhook, so unwanted - /// updates may be received for a short period of time. - /// - /// - /// - /// Notes - /// - /// - /// 1. You will not be able to receive updates using - /// getUpdates for as long as an outgoing webhook is set up. - /// - /// - /// 2. To use a self-signed certificate, you need to upload your - /// public key certificate using certificate parameter. - /// Please upload as InputFile, sending a String will not work. - /// - /// - /// 3. Ports currently supported for Webhooks: 443, 80, 88, 8443 - /// . - /// - /// - /// NEW! If you're having any trouble setting up webhooks, - /// please check out this - /// amazing guide to Webhooks. - /// - /// function SetWebhook(// const Url: string; // const Certificate: TtgFileToSend = nil; // const MaxConnections: Int64 = 40; // const AllowedUpdates: TAllowedUpdates = UPDATES_ALLOWED_ALL): Boolean; - /// - /// Use this method to remove webhook integration if you decide to switch - /// back to - /// getUpdates. - /// - /// - /// Returns True on success. - /// function DeleteWebhook: Boolean; - - /// - /// Use this method to get current webhook status. - /// - /// - /// On success, returns a - /// WebhookInfo object - /// - /// - /// If the bot is using - /// getUpdates, will return an object with the url field empty - /// function GetWebhookInfo: ItgWebhookInfo; {$ENDREGION} + {$REGION 'Basic methods'} - /// - /// - /// Простой метод для проверки токена вашего бота - /// - /// - /// A simple method for testing your bot's auth token. - /// - /// - /// - /// - /// Возвращает основную информацию о боте - /// - /// - /// Returns basic information about the bot in form of a - /// User object. - /// - /// function GetMe: ItgUser; - /// - /// Use this method to send text messages. - /// - /// - /// Int64 or String. Unique identifier for the target chat or username of - /// the target channel (in the format @channelusername ). - /// - /// - /// Text of the message to be sent - /// - /// - /// Send Markdown or HTML, if you want Telegram apps to show bold, - /// italic, fixed-width text or inline URLs in your bot's message. - /// - /// - /// Disables link previews for links in this message - /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound. - /// - /// - /// If the message is a reply, ID of the original message - /// - /// - /// InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or - /// ForceReply. Additional interface options. A JSON-serialized object - /// for an inline keyboard, custom reply keyboard, instructions to hide - /// reply keyboard or to force a reply from the user. - /// - /// - /// On success, the sent Message - /// is returned. - /// function SendMessage(// const ChatId: TValue; // const Text: string; // @@ -249,77 +74,10 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method to forward messages of any kind. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Unique identifier for the chat where the original message was sent - /// (or channel username in the format @channelusername)
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// Unique message identifier
- /// - /// - /// On success, the sent Message is returned. - /// function ForwardMessage(// const ChatId, FromChatId: TValue; // const MessageId: Int64; // const DisableNotification: Boolean = False): ITgMessage; - /// - /// Use this method to send photos. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Photo to send. You can either pass a file_id as String to resend a - /// photo that is already on the Telegram servers, or upload a new photo - /// using multipart/form-data.
- /// - /// - /// Photo caption (may also be used when resending photos by file_id), - /// 0-200 characters
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to remove reply - /// keyboard or to force a reply from the user.
- /// - /// - /// On success, the sent Message - /// is returned. - /// - /// - /// var - /// LMessage: TtgMessage; - /// Begin - /// //Если не известен ИД файла - /// LMessage := sendPhoto(chatId, TtgFileToSend.Create('Путь к файлу'), nil); - /// //Если известен ИД файла - /// LMessage := sendPhoto(chatId, 'ИД Файла'); - /// ... - /// LMessage.Free; - /// End; - /// function SendPhoto(// const ChatId: TValue; // const Photo: TtgFileToSend; // @@ -327,52 +85,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method to send audio files, if you want Telegram clients to - /// display them in the music player. Your audio must be in the .mp3 - /// format. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Audio file to send. You can either pass a file_id as String to resend - /// an audio that is already on the Telegram servers, or upload a new - /// audio file using multipart/form-data.
- /// - /// - /// Duration of the audio in seconds
- /// - /// - /// Performer
- /// - /// - /// Track name
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to hide reply keyboard - /// or to force a reply from the user.
- /// - /// - /// On success, the sent Message - /// is returned. - /// - /// - /// Bots can currently send audio files of up to 50 MB in size, this - /// limit may be changed in the future. For sending voice messages, use - /// the - /// sendVoice method instead. - /// function SendAudio(// const ChatId: TValue; // const Audio: TtgFileToSend; // @@ -382,43 +94,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method to send general files. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// File to send. You can either pass a file_id as String to resend a - /// file that is already on the Telegram servers, or upload a new file - /// using multipart/form-data.
- /// - /// - /// Document caption (may also be used when resending documents by - /// file_id), 0-200 characters
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to hide reply keyboard - /// or to force a reply from the user.
- /// - /// - /// On success, the sent Message - /// is returned. - /// - /// - /// Bots can currently send files of any type of up to 50 MB in size, - /// this limit may be changed in the future. - /// function SendDocument(// const ChatId: TValue; // const Document: TtgFileToSend; // @@ -426,52 +101,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method to send video files, Telegram clients support mp4 - /// videos (other formats may be sent as Document). - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Video to send. You can either pass a file_id as String to resend a - /// video that is already on the Telegram servers, or upload a new video - /// file using multipart/form-data.
- /// - /// - /// Duration of sent video in seconds
- /// - /// - /// Video width
- /// - /// - /// Video height
- /// - /// - /// Video caption (may also be used when resending videos by file_id), - /// 0-200 characters
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to hide reply keyboard - /// or to force a reply from the user.
- /// - /// - /// On success, the sent Message is returned. - /// - /// - /// Bots can currently send video files of up to 50 MB in size, this - /// limit may be changed in the future. - /// function SendVideo(// const ChatId: TValue; // const Video: TtgFileToSend; // @@ -482,46 +111,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - - /// - /// Use this method to send audio files, if you want Telegram clients to - /// display the file as a playable voice message. For this to work, your - /// audio must be in an .ogg file encoded with OPUS (other formats may be - /// sent as Audio or Document). - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Audio file to send. You can either pass a file_id as String to resend - /// an audio that is already on the Telegram servers, or upload a new - /// audio file using multipart/form-data.
- /// - /// - /// Duration of sent audio in seconds
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to hide reply keyboard - /// or to force a reply from the user.
- /// - /// - /// On success, the sent Message - /// is returned - /// - /// - /// Bots can currently send voice messages of up to 50 MB in size, this - /// limit may be changed in the future. - /// function SendVoice(// const ChatId: TValue; // const Voice: TtgFileToSend; // @@ -530,47 +119,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// As of - /// v.4.0, Telegram clients support rounded square mp4 videos of up - /// to 1 minute long. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Video note to send. Pass a file_id as String to send a video note - /// that exists on the Telegram servers (recommended) or upload a new - /// video using multipart/form-data. More info on Sending Files ». - /// Sending video notes by a URL is currently unsupported
- /// - /// - /// Duration of sent video in seconds
- /// - /// - /// Video width and height
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to remove reply - /// keyboard or to force a reply from the user.
- /// - /// - /// On success, the sent Message - /// is returned. - /// - /// - /// Use this method to send video messages. - /// function SendVideoNote(// const ChatId: TValue; // const VideoNote: TtgFileToSend; // @@ -579,34 +127,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - - /// - /// Use this method to send point on the map. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Latitude and Longitude of location - /// - /// - /// Sends the message - /// silently. iOS users will not receive a notification, Android - /// users will receive a notification with no sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to hide reply keyboard - /// or to force a reply from the user.
- /// - /// - /// On success, the sent Message - /// is returned. - /// function SendLocation(// const ChatId: TValue; // const Location: TtgLocation; // @@ -614,291 +134,40 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method to send information about a venue. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Latitude and Longitude of the venue
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.

- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to hide reply keyboard - /// or to force a reply from the user.
- /// - /// - /// Name of the venue - /// - /// - /// Address of the venue - /// - /// - /// Foursquare identifier of the venue - /// - /// - /// On success, the sent Message is returned. - /// function SendVenue(// const ChatId: TValue; // const Venue: TtgVenue; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method to send phone contacts. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Contact's phone number, first name, last name - /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound. - /// - /// - /// If the message is a reply, ID of the original message - /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to hide keyboard or to - /// force a reply from the user.
- /// - /// - /// On success, the sent Message - /// is returned. - /// - /// function SendContact(// const ChatId: TValue; // const Contact: TtgContact; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method when you need to tell the user that something is - /// happening on the bot's side. The status is set for 5 seconds or less - /// (when a message arrives from your bot, Telegram clients clear its - /// typing status). - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Type of action to broadcast. Choose one, depending on what the user - /// is about to receive: typing for text messages, upload_photo for - /// photos, record_video or upload_video for videos, record_audio or - /// upload_audio for audio files, upload_document for general files, - /// find_location for location data
- /// - /// - /// We only recommend using this method when a response from the bot will - /// take a noticeable amount of time to arrive. - /// - /// function SendChatAction(// const ChatId: TValue; // const Action: TtgSendChatAction): Boolean; - /// - /// Use this method to get a list of profile pictures for a user. - /// - /// - /// Unique identifier of the target user
- /// - /// - /// Sequential number of the first photo to be returned. By default, all - /// photos are returned.
- /// - /// - /// Limits the number of photos to be retrieved. Values between 1—100 are - /// accepted. Defaults to 100.
- /// - /// - /// Returns a - /// UserProfilePhotos object. - /// - /// function GetUserProfilePhotos(// const ChatId: TValue; // const Offset: Int64; // const Limit: Int64 = 100): ItgUserProfilePhotos; - /// - /// Use this method to get basic info about a file and prepare it for - /// downloading. For the moment, bots can download files of up to 20MB in - /// size. - /// - /// - /// File identifier to get info about
- /// - /// - /// On success, a File object is - /// returned. - /// - /// function GetFile(const FileId: string): ItgFile; - /// - /// Use this method to kick a user from a group, a supergroup or a - /// channel. In the case of supergroups and channels, the user will not - /// be able to return to the group on their own using invite links, etc., - /// unless unbanned first. The bot must be an administrator in the chat - /// for this to work and must have the appropriate admin rights. - /// - /// - /// Unique identifier for the target group or username of the target - /// supergroup (in the format @supergroupusername)
- /// - /// - /// Unique identifier of the target user
- /// - /// - /// Date when the user will be unbanned, unix time. If user is banned for - /// more than 366 days or less than 30 seconds from the current time they - /// are considered to be banned forever
unbanChatMember - /// - /// - /// Returns True on success. - /// - /// - /// Note: In regular groups (non-supergroups), this method will only work - /// if the ‘All Members Are Admins’ setting is off in the target group. - /// Otherwise members may only be removed by the group's creator or by - /// the member that added them. - /// - /// function KickChatMember(// const ChatId: TValue; // const UserId: Int64; // const UntilDate: Int64 = 0): Boolean; - /// - /// Use this method to unban a previously kicked user in a supergroup. - /// The user will not return to the group automatically, but will be able - /// to join via link, etc. - /// - /// - /// Unique identifier for the target group or username of the target - /// supergroup (in the format @supergroupusername)
- /// - /// - /// Unique identifier of the target user
- /// - /// - /// Returns True on success. - /// - /// - /// The bot must be an administrator in the group for this to work. - /// - /// function UnbanChatMember(// const ChatId: TValue; // const UserId: Int64): Boolean; - /// - /// Use this method for your bot to leave a group, supergroup or channel. - /// - /// - /// Unique identifier for the target group or username of the target - /// supergroup (in the format @supergroupusername)
- /// - /// - /// Returns True on success. - /// - /// function LeaveChat(const ChatId: TValue): Boolean; - /// - /// Use this method to get up to date information about the chat (current - /// name of the user for one-on-one conversations, current username of a - /// user, group or channel, etc.) - /// - /// - /// Unique identifier for the target chat or username of the target - /// supergroup or channel (in the format @channelusername)
- /// - /// - /// Returns a Chat object on - /// success. - /// - /// function GetChat(const ChatId: TValue): ItgChat; - /// - /// Use this method to get a list of administrators in a chat - /// - /// - /// Unique identifier for the target chat or username of the target - /// supergroup or channel (in the format @channelusername)
- /// - /// - /// On success, returns an Array of - /// ChatMember objects that contains information about all chat - /// administrators except other bots. If the chat is a group or a - /// supergroup and no administrators were appointed, only the creator - /// will be returned. - /// - /// function GetChatAdministrators(const ChatId: TValue): TArray; - /// - /// Use this method to get the number of members in a chat. - /// - /// - /// Unique identifier for the target chat or username of the target - /// supergroup or channel (in the format @channelusername)
- /// - /// - /// Returns Int64 on success. - /// - /// function GetChatMembersCount(const ChatId: TValue): Int64; - /// - /// Use this method to get information about a member of a chat. - /// - /// - /// Unique identifier for the target group or username of the target - /// supergroup (in the format @supergroupusername)
- /// - /// - /// Unique identifier of the target user
- /// - /// - /// Returns a ChatMember - /// object on success. - /// - /// function GetChatMember(// const ChatId: TValue; // const UserId: Int64): ItgChatMember; - /// - /// Use this method to send answers to callback queries sent from inline - /// keyboards. The answer will be displayed to the user as a notification - /// at the top of the chat screen or as an alert. - /// - /// - /// Unique identifier for the query to be answered
- /// - /// - /// Text of the notification. If not specified, nothing will be shown to - /// the user
- /// - /// - /// If true, an alert will be shown by the client instead of a - /// notification at the top of the chat screen. Defaults to false.
- /// - /// - /// On success, True is returned. - /// - /// function AnswerCallbackQuery(// const CallbackQueryId: string; // const Text: string = ''; // @@ -906,42 +175,8 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Url: string = ''; // const CacheTime: Int64 = 0): Boolean; {$ENDREGION} + {$REGION 'Updating messages'} - /// - /// Use this method to edit text messages sent by the bot or via the bot - /// (for inline bots). - /// - /// - /// Required if inline_message_id is not specified. Unique identifier for - /// the target chat or username of the target channel (in the format - /// @channelusername)
- /// - /// - /// Required if inline_message_id is not specified. Unique identifier of - /// the sent message
- /// - /// - /// Required if chat_id and message_id are not specified. Identifier of - /// the inline message
- /// - /// - /// New text of the message
- /// - /// - /// Send Markdown or HTML, if you want Telegram apps to show bold, - /// italic, fixed-width text or inline URLs in your bot's message.
- /// - /// - /// Disables link previews for links in this message
- /// - /// - /// A JSON-serialized object for an inline keyboard.
- /// - /// - /// On success, if edited message is sent by the bot, the edited Message - /// is returned, otherwise True is returned. - /// - /// function EditMessageText(// const ChatId: TValue; // const MessageId: Int64; // @@ -955,262 +190,44 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const ParseMode: TtgParseMode = TtgParseMode.Default; // const DisableWebPagePreview: Boolean = False; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; - /// - /// Use this method to edit captions of messages sent by the bot or via - /// the bot (for inline bots). - /// - /// - /// Required if InlineMessageId is not specified. Unique identifier for - /// the target chat or username of the target channel (in the format - /// @channelusername)
- /// - /// - /// Required if InlineMessageId is not specified. Unique identifier of
- /// the sent message
- /// - /// - /// Required if ChatId and MessageId are not specified. Identifier of the - /// inline message
- /// - /// - /// New caption of the message
- /// - /// - /// A JSON-serialized object for an inline keyboard.
- /// - /// - /// On success, if edited message is sent by the bot, the edited Message - /// is returned, otherwise True is returned. - /// - /// function EditMessageCaption(// const ChatId: TValue; // const MessageId: Int64; // const Caption: string; // ReplyMarkup: IReplyMarkup = nil): Boolean; overload; - { TODO -oM.E.Sysoev -cGeneral : Create Documentatiom } function EditMessageCaption(// const InlineMessageId: string; // const Caption: string; // ReplyMarkup: IReplyMarkup = nil): Boolean; overload; - - /// - /// Use this method to edit live location messages sent by the bot or via - /// the bot (for inline bots). A location can be edited until its - /// live_period expires or editing is explicitly disabled by a call to - /// stopMessageLiveLocation. - /// - /// - /// Required if inline_message_id is not specified. Unique identifier for - /// the target chat or username of the target channel (in the format - /// @channelusername) - /// - /// - /// Required if inline_message_id is not specified. Identifier of the - /// sent message - /// - /// - /// new location - /// - /// - /// A JSON-serialized object for a new inline keyboard. - /// - /// - /// On success, if the edited message was sent by the bot, the edited - /// Message is returned, otherwise True is returned. - /// function editMessageLiveLocation(// const ChatId: TValue; // const MessageId: Int64; // const Location: TtgLocation; // ReplyMarkup: IReplyMarkup = nil): Boolean; overload; - /// - /// Use this method to edit live location messages sent by the bot or via - /// the bot (for inline bots). A location can be edited until its - /// live_period expires or editing is explicitly disabled by a call to - /// stopMessageLiveLocation. - /// - /// - /// Required if chat_id and message_id are not specified. Identifier of - /// the inline message - /// - /// - /// new location - /// - /// - /// A JSON-serialized object for a new inline keyboard. - /// - /// - /// Required if inline_message_id is not specified. Unique identifier for - /// the target chat or username of the target channel (in the format - /// @channelusername) - /// - /// - /// Required if inline_message_id is not specified. Identifier of the - /// sent message - /// - /// - /// On success, if the edited message was sent by the bot, the edited - /// Message is returned, otherwise True is returned. - /// - function EditMessageLiveLocation(// + function editMessageLiveLocation(// const InlineMessageId: string; // const Location: TtgLocation; // ReplyMarkup: IReplyMarkup = nil): Boolean; overload; - - /// - /// Use this method to stop updating a live location message sent by the - /// bot or via the bot (for inline bots) before live_period expires. - /// - /// - /// equired if inline_message_id is not specified. Unique identifier for - /// the target chat or username of the target channel (in the format - /// @channelusername) - /// - /// - /// Required if inline_message_id is not specified. Identifier of the - /// sent message - /// - /// - /// A JSON-serialized object for a new inline keyboard. - /// - /// - /// On success, if the message was sent by the bot, the sent Message is - /// returned, otherwise True is returned. - /// function stopMessageLiveLocation(// const ChatId: TValue; // const MessageId: Int64; // ReplyMarkup: IReplyMarkup = nil): Boolean; overload; - /// - /// Use this method to stop updating a live location message sent by the - /// bot or via the bot (for inline bots) before live_period expires. - /// - /// - /// Required if chat_id and message_id are not specified. Identifier of - /// the inline message - /// - /// - /// A JSON-serialized object for a new inline keyboard. - /// - /// - /// On success, if the message was sent by the bot, the sent Message is - /// returned, otherwise True is returned. - /// function stopMessageLiveLocation(// const InlineMessageId: string; // ReplyMarkup: IReplyMarkup = nil): Boolean; overload; - /// - /// Use this method to edit only the reply markup of messages sent by the - /// bot or via the bot (for inline bots). - /// - /// - /// Required if InlineMessageId is not specified. Unique identifier for
- /// the target chat or username of the target channel (in the format
- /// @channelusername)
- /// - /// - /// Required if InlineMessageId is not specified. Unique identifier of
- /// the sent message
- /// - /// - /// A JSON-serialized object for an inline keyboard.
- /// - /// - /// On success, if edited message is sent by the bot, the edited Message - /// is returned, otherwise True is returned. - /// function EditMessageReplyMarkup(// const ChatId: TValue; // const MessageId: Int64; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; - /// - /// Use this method to edit only the reply markup of messages sent by the - /// bot or via the bot (for inline bots). - /// - /// - /// Required if ChatId and MessageId are not specified. Identifier of
- /// the inline message
- /// - /// - /// A JSON-serialized object for an inline keyboard.
- /// - /// - /// On success, if edited message is sent by the bot, the edited Message - /// is returned, otherwise True is returned. - /// function EditMessageReplyMarkup(// const InlineMessageId: string; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; overload; - /// - /// Use this method to delete a message. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Identifier of the message to delete
- /// - /// - /// Returns True on success. - /// - /// - /// A message can only be deleted if it was sent less than 48 hours ago. - /// Any such recently sent outgoing message may be deleted. Additionally, - /// if the bot is an administrator in a group chat, it can delete any - /// message. If the bot is an administrator in a supergroup, it can - /// delete messages from any other user and service messages about people - /// joining or leaving the group (other types of service messages may - /// only be removed by the group creator). In channels, bots can only - /// remove their own messages. - /// - /// function DeleteMessage(// const ChatId: TValue; // const MessageId: Int64): Boolean; - {$ENDREGION} +{$ENDREGION} + {$REGION 'Inline mode'} - /// - /// Use this method to send answers to an inline query. - /// - /// - /// Unique identifier for the answered query
- /// - /// - /// A JSON-serialized array of results for the inline query
- /// - /// - /// The maximum amount of time in seconds that the result of the inline - /// query may be cached on the server. Defaults to 300.
- /// - /// - /// Pass True, if results may be cached on the server side only for the - /// user that sent the query. By default, results may be returned to any - /// user who sends the same query
- /// - /// - /// Pass the offset that a client should send in the next query with the - /// same text to receive more results. Pass an empty string if there are - /// no more results or if you don‘t support pagination. Offset length - /// can’t exceed 64 bytes.
- /// - /// - /// If passed, clients will display a button with specified text that - /// switches the user to a private chat with the bot and sends the bot a - /// start message with the parameter switch_pm_parameter
- /// - /// - /// Parameter for the start message sent to the bot when user presses the - /// switch button
- /// - /// - /// On success, True is returned. - /// - /// - /// No more than 50 results per query are allowed. - /// - /// function AnswerInlineQuery(// const InlineQueryId: string; // const Results: TArray; // @@ -1220,85 +237,8 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const SwitchPmText: string = ''; // const SwitchPmParameter: string = ''): Boolean; {$ENDREGION} + {$REGION 'Payments'} - /// - /// Use this method to send invoices. - /// - /// - /// Unique identifier for the target private chat
- /// - /// - /// Product name - /// - /// - /// Product description - /// - /// - /// Bot-defined invoice payload, 1-128 bytes. This will not be displayed - /// to the user, use for your internal processes. - /// - /// - /// Payments provider token, obtained via Botfather - /// - /// - /// Unique deep-linking parameter that can be used to generate this - /// invoice when used as a start parameter - /// - /// - /// Three-letter ISO 4217 currency code, see more on currencies - /// - /// - /// Price breakdown, a list of components (e.g. product price, tax, - /// discount, delivery cost, delivery tax, bonus, etc.) - /// - /// - /// URL of the product photo for the invoice. Can be a photo of the goods - /// or a marketing image for a service. - /// - /// - /// Photo size - /// - /// - /// Photo width - /// - /// - /// Photo height - /// - /// - /// Pass True, if you require the user's full name to complete the order - /// - /// - /// Pass True, if you require the user's phone number to complete the - /// order - /// - /// - /// Pass True, if you require the user's email to complete the order - /// - /// - /// Pass True, if you require the user's shipping address to complete the - /// order - /// - /// - /// Pass True, if the final price depends on the shipping method - /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound. - /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for a custom - /// reply keyboard, instructions to hide keyboard or to force a reply - /// from the user.
- /// - /// - /// On success, the sent is - /// returned. - /// - /// function SendInvoice(// const ChatId: Int64; // const Title: string; // @@ -1321,143 +261,26 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// If you sent an invoice requesting a shipping address and the - /// parameter is_flexible was specified, the Bot API will send an Update - /// with a shipping_query field to the bot. Use this method to reply to - /// shipping queries. On success, True is returned. - /// - /// - /// Unique identifier for the query to be answered - /// - /// - /// Specify True if delivery to the specified address is possible and - /// False if there are any problems (for example, if delivery to the - /// specified address is not possible) - /// - /// - /// Required if ok is True. A JSON-serialized array of - /// available shipping options. - /// - /// - /// Required if ok is False. Error message in human - /// readable form that explains why it is impossible to complete the - /// order (e.g. "Sorry, delivery to your desired address is - /// unavailable'). Telegram will display this message to the user. - /// - /// function AnswerShippingQueryGood(// const ShippingQueryId: string; // const ShippingOptions: TArray): Boolean; function AnswerShippingQueryBad(// const ShippingQueryId: string; // const ErrorMessage: string): Boolean; - /// - /// Once the user has confirmed their payment and shipping details, the - /// Bot API sends the final confirmation in the form of an - /// Update with the field PreCheckoutQueryId. Use this method to - /// respond to such pre-checkout queries. - /// - /// - /// Unique identifier for the query to be answered - /// - /// - /// Specify True if everything is alright (goods are available, - /// etc.) and the bot is ready to proceed with the order. Use False if - /// there are any problems. - /// - /// - /// Required if ok is False. Error message in human - /// readable form that explains the reason for failure to proceed with - /// the checkout (e.g. "Sorry, somebody just bought the last of our - /// amazing black T-shirts while you were busy filling out your payment - /// details. Please choose a different color or garment!"). Telegram will - /// display this message to the user. - /// - /// - /// On success, True is returned. - /// - /// - /// Note: The Bot API must receive an answer within 10 seconds - /// after the pre-checkout query was sent. - /// - /// function AnswerPreCheckoutQueryGood(// const PreCheckoutQueryId: string): Boolean; function AnswerPreCheckoutQueryBad(// const PreCheckoutQueryId: string; // const ErrorMessage: string): Boolean; {$ENDREGION} + {$REGION 'Games'} - /// - /// Use this method to send a game. - /// - /// - /// Unique identifier for the target chat
- /// - /// - /// Short name of the game, serves as the unique identifier for the game. - /// Set up your games via Botfather.
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// A JSON-serialized object for an inline keyboard. If empty, one ‘Play - /// game_title’ button will be shown. If not empty, the first button must - /// launch the game.
- /// - /// - /// On success, the sent Message is returned. - /// - /// function SendGame(// const ChatId: Int64; // const GameShortName: string; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method to set the score of the specified user in a game. - /// - /// - /// User identifier
- /// - /// - /// New score, must be non-negative
- /// - /// - /// Pass True, if the high score is allowed to decrease. This can be - /// useful when fixing mistakes or banning cheaters
- /// - /// - /// Pass True, if the game message should not be automatically edited to - /// include the current scoreboard
- /// - /// - /// Required if InlineMessageId is not specified. Unique identifier for
- /// the target chat
- /// - /// - /// Required if InlineMessageId is not specified. Identifier of the
- /// sent message
- /// - /// - /// Required if ChatId and MessageId are not specified. Identifier of the - /// inline message
- /// - /// - /// On success, if the message was sent by the bot, returns the edited - /// Message, otherwise returns True. Returns an error, if the new score - /// is not greater than the user's current score in the chat and force is - /// False. - /// - /// function SetGameScore(// const UserId: Int64; // const Score: Int64; // @@ -1471,38 +294,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const MessageId: Int64; // const Force: Boolean = False; // const DisableEditMessage: Boolean = False): ITgMessage; overload; - /// - /// Use this method to get data for high score tables. Will return the - /// score of the specified user and several of his neighbors in a game. - /// - /// - /// Target user id
- /// - /// - /// Required if InlineMessageId is not specified. Unique identifier for
- /// the target chat
- /// - /// - /// Required if InlineMessageId is not specified. Identifier of the
- /// sent message
- /// - /// - /// Required if ChatId and MessageId are not specified. Identifier of
- /// the inline message
- /// - /// - /// On success, returns an Array of - /// GameHighScore objects. - /// - /// - /// This method will currently return scores for the target user, plus - /// two of his closest neighbors on each side. Will also return the top - /// three users if the user and his neighbors are not among them. Please - /// note that this behavior is subject to change. - /// - /// - /// Official API - /// function GetGameHighScores(// const UserId: Int64; // const InlineMessageId: string = ''): TArray; overload; @@ -1511,169 +302,21 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const ChatId: Int64 = 0; // const MessageId: Int64 = 0): TArray; overload; {$ENDREGION} + {$REGION 'Manage groups and channels'} - /// - /// Use this method to delete a chat photo. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername) - /// - /// - /// Returns True on success. - /// - /// - /// Photos can't be changed for private chats. The bot must be an - /// administrator in the chat for this to work and must have the - /// appropriate admin rights. - /// function DeleteChatPhoto(const ChatId: TValue): Boolean; - /// - /// Use this method to export an invite link to a supergroup or a - /// channel. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername) - /// - /// - /// Returns exported invite link as String on success. - /// - /// - /// The bot must be an administrator in the chat for this to work and - /// must have the appropriate admin rights. - /// function ExportChatInviteLink(const ChatId: TValue): string; - /// - /// Use this method to pin a message in a supergroup. The bot must be an - /// administrator in the chat for this to work and must have the - /// appropriate admin rights. - /// - /// - /// Unique identifier for the target chat or username of the target - /// supergroup (in the format @supergroupusername) - /// - /// - /// Identifier of a message to pin
- /// - /// - /// Pass True, if it is not necessary to send a notification to all group - /// members about the new pinned message - /// - /// - /// Returns True on success. - /// function PinChatMessage(// const ChatId: TValue; // const MessageId: Int64; // const DisableNotification: Boolean = False): Boolean; - /// - /// Use this method to change the description of a supergroup or a - /// channel. The bot must be an administrator in the chat for this to - /// work and must have the appropriate admin rights. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername) - /// - /// - /// New chat description, 0-255 characters - /// - /// - /// Returns True on success. - /// function SetChatDescription(const ChatId: TValue; const Description: string): Boolean; - /// - /// Use this method to set a new profile photo for the chat. Photos can't - /// be changed for private chats. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername) - /// - /// - /// New chat photo, uploaded using multipart/form-data - /// - /// - /// Returns True on success. - /// - /// - /// The bot must be an administrator in the chat for this to work and - /// must have the appropriate admin rights. - /// function SetChatPhoto(const ChatId: TValue; const Photo: TtgFileToSend): Boolean; - /// - /// Use this method to change the title of a chat. Titles can't be - /// changed for private chats. The bot must be an administrator in the - /// chat for this to work and must have the appropriate admin rights. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername) - /// - /// - /// New chat title, 1-255 characters - /// - /// - /// Returns True on success. - /// - /// - /// Note: In regular groups (non-supergroups), this method will only work - /// if the ‘All Members Are Admins’ setting is off in the target group. - /// function SetChatTitle(const ChatId: TValue; const Title: string): Boolean; - /// - /// Use this method to unpin a message in a supergroup chat. The bot must - /// be an administrator in the chat for this to work and must have the - /// appropriate admin rights. - /// - /// - /// Unique identifier for the target chat or username of the target - /// supergroup (in the format @supergroupusername) - /// - /// - /// Returns True on success. - /// function UnpinChatMessage(const ChatId: TValue): Boolean; {$ENDREGION} + {$REGION 'Manage users and admins'} - /// - /// Use this method to restrict a user in a supergroup. The bot must be - /// an administrator in the supergroup for this to work and must have the - /// appropriate admin rights. Pass True for all boolean parameters to - /// lift restrictions from a user. - /// - /// - /// Unique identifier for the target chat or username of the target - /// supergroup (in the format @supergroupusername) - /// - /// - /// Unique identifier of the target user - /// - /// - /// Date when restrictions will be lifted for the user, unix time. If - /// user is restricted for more than 366 days or less than 30 seconds - /// from the current time, they are considered to be restricted forever - /// - /// - /// Pass True, if the user can send text messages, contacts, locations - /// and venues - /// - /// - /// Pass True, if the user can send audios, documents, photos, videos, - /// video notes and voice notes, implies CanSendMessages
- /// - /// - /// Pass True, if the user can send animations, games, stickers and use - /// inline bots, implies CanSendMediaMessages
- /// - /// - /// Pass True, if the user may add web page previews to their messages, - /// implies CanSendMediaMessages
- /// - /// - /// Returns True on success. - /// function RestrictChatMember(// const ChatId: TValue; // const UserId: Int64; // @@ -1682,53 +325,6 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const CanSendMediaMessages: Boolean = False; // const CanSendOtherMessages: Boolean = False; // const CanAddWebPagePreviews: Boolean = False): Boolean; - /// - /// Use this method to restrict a user in a supergroup. The bot must be - /// an administrator in the supergroup for this to work and must have the - /// appropriate admin rights. Pass True for all boolean parameters to - /// lift restrictions from a user. - /// - /// - /// Unique identifier for the target chat or username of the target - /// supergroup (in the format @supergroupusername) - /// - /// - /// Unique identifier of the target user - /// - /// - /// Pass True, if the administrator can change chat title, photo and - /// other settings - /// - /// - /// Pass True, if the administrator can create channel posts, channels - /// only - /// - /// - /// Pass True, if the administrator can edit messages of other users, - /// channels only - /// - /// - /// Pass True, if the administrator can delete messages of other users - /// - /// - /// Pass True, if the administrator can invite new users to the chat - /// - /// - /// Pass True, if the administrator can restrict, ban or unban chat - /// members - /// - /// - /// Pass True, if the administrator can pin messages, supergroups only - /// - /// - /// Pass True, if the administrator can add new administrators with a - /// subset of his own privileges or demote administrators that he has - /// promoted, directly or indirectly (promoted by administrators that - /// were appointed by him) - /// - /// - /// Returns True on success. - /// function PromoteChatMember(// const ChatId: TValue; // const UserId: Int64; // @@ -1741,109 +337,16 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const CanPinMessages: Boolean = False; // const CanPromoteMembers: Boolean = False): Boolean; {$ENDREGION} + {$REGION 'Strickers'} - /// - /// Use this method to send .webp stickers. - /// - /// - /// Unique identifier for the target chat or username of the target - /// channel (in the format @channelusername)
- /// - /// - /// Sticker to send. You can either pass a file_id as String to resend a - /// sticker that is already on the Telegram servers, or upload a new - /// sticker using multipart/form-data.
- /// - /// - /// Sends the message silently. iOS users will not receive a - /// notification, Android users will receive a notification with no - /// sound.
- /// - /// - /// If the message is a reply, ID of the original message
- /// - /// - /// Additional interface options. A JSON-serialized object for an inline - /// keyboard, custom reply keyboard, instructions to hide reply keyboard - /// or to force a reply from the user.
- /// - /// - /// On success, the sent Message is returned. - /// function SendSticker(// const ChatId: TValue; // const Sticker: TValue; // const DisableNotification: Boolean = False; // const ReplyToMessageId: Int64 = 0; // ReplyMarkup: IReplyMarkup = nil): ITgMessage; - /// - /// Use this method to get a sticker set. - /// - /// - /// Name of the sticker set - /// - /// - /// On success, a StickerSet - /// object is returned. - /// function getStickerSet(const Name: string): TtgStickerSet; - /// - /// Use this method to upload a .png file with a sticker for later use in - /// - /// createNewStickerSet and - /// addStickerToSet methods (can be used multiple times).
- ///
- /// - /// User identifier of sticker file owner
- /// - /// - /// Png image with the sticker, must be up to 512 kilobytes in size, - /// dimensions must not exceed 512px, and either width or height must be - /// exactly 512px.
- /// - /// - /// Returns the uploaded File on - /// success. - /// function uploadStickerFile(const UserId: Int64; const PngSticker: TtgFileToSend): ItgFile; - /// - /// Use this method to create new sticker set owned by a user. The bot - /// will be able to edit the created sticker set. - /// - /// - /// User identifier of created sticker set owner
- /// - /// - /// Short name of sticker set, to be used in t.me/addstickers/ URLs - /// (e.g., animals). Can contain only english letters, digits and - /// underscores. Must begin with a letter, can't contain consecutive - /// underscores and must end in by “__<bot username>”. - /// <bot_username> is case insensitive. 1-64 characters.
- /// - /// - /// Sticker set title, 1-64 characters
- /// - /// - /// Png image with the sticker, must be up to 512 kilobytes in size, - /// dimensions must not exceed 512px, and either width or height must be - /// exactly 512px. Pass a file_id as a String to send a file that already - /// exists on the Telegram servers, pass an HTTP URL as a String for - /// Telegram to get a file from the Internet, or upload a new one using - /// multipart/form-data. More info on Sending Files »
- /// - /// - /// One or more emoji corresponding to the sticker
- /// - /// - /// Pass True, if a set of mask stickers should be created
- /// - /// - /// A JSON-serialized object for position where the mask should be placed - /// on faces
- /// - /// - /// Returns True on success. - /// function createNewStickerSet(// const UserId: Int64; // const Name, Title: string; // @@ -1851,67 +354,15 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) const Emojis: string; // const ContainsMasks: Boolean = False; // const MaskPosition: TtgMaskPosition = nil): Boolean; - /// - /// Use this method to add a new sticker to a set created by the bot. - /// - /// - /// Returns True on success. - /// function addStickerToSet(// const UserId: Int64; // const Name: string; // const PngSticker: TValue; // const Emojis: string; // const MaskPosition: TtgMaskPosition = nil): Boolean; - /// - /// Use this method to move a sticker in a set created by the bot to a - /// specific position. - /// - /// - /// File identifier of the sticker - /// - /// - /// New sticker position in the set, zero-based - /// - /// - /// Returns True on success. - /// function setStickerPositionInSet(const Sticker: string; const Position: Int64): Boolean; - /// - /// Use this method to delete a sticker from a set created by the bot. - /// - /// - /// File identifier of the sticker - /// - /// - /// Returns True on success. - /// function deleteStickerFromSet(const Sticker: string): Boolean; - /// - /// Use this method to set a new group sticker set for a supergroup. - /// - /// - /// Returns True on success. - /// - /// - /// The bot must be an administrator in the chat for this to work and - /// must have the appropriate admin rights. Use the field - /// CanSetStickerSet optionally returned in - /// getChat requests to check if the bot can use this method. - /// function setChatStickerSet(const ChatId: TValue; const StickerSetName: string): Boolean; - /// - /// Use this method to delete a group sticker set from a supergroup. - /// - /// - /// Returns True on success. - /// - /// - /// The bot must be an administrator in the chat for this to work and - /// must have the appropriate admin rights. Use the field - /// CanSetStickerSet optionally returned in - /// getChat requests to check if the bot can use this method. - /// function deleteChatStickerSet(const ChatId: TValue): Boolean; function sendMediaGroup(// const ChatId: TValue; // @@ -1979,12 +430,9 @@ function TTelegramBot.ApiTest(const ARequest: string; const Parameters: TArray nil then - begin - ExceptionManager.HaveApiExeption('TTelegramBot.ApiTest', EApiRequestException.Create(ARequest, 0)); - Exit; - end; - Result := FJSON.GetValue('result').ToJSON; + ExceptionManager.HaveApiExeption('TTelegramBot.ApiTest', EApiRequestException.Create(ARequest, 0)) + else + Result := FJSON.GetValue('result').ToJSON; finally FJSON.Free; end; @@ -2331,7 +779,7 @@ function TTelegramBot.GetChatAdministrators(const ChatId: TValue): TArray(TtgChatMember, // RequestAPI('getChatAdministrators', // - [TtgApiParameter.Create('chat_id', ChatId, 0, true)])); + [TtgApiParameter.Create('chat_id', ChatId, 0, True)])); end; function TTelegramBot.GetChatMember(const ChatId: TValue; const UserId: Int64): ItgChatMember; @@ -2358,7 +806,7 @@ function TTelegramBot.GetChatMembersCount(const ChatId: TValue): Int64; function TTelegramBot.GetFile(const FileId: string): ItgFile; begin Result := TtgFile.Create(RequestAPI('getFile', [// - TtgApiParameter.Create('file_id', FileId, 0, True)])); + TtgApiParameter.Create('file_id', FileId, '', True)])); end; function TTelegramBot.AnswerCallbackQuery(const CallbackQueryId, Text: string; const ShowAlert: Boolean; const Url: string; const CacheTime: Int64): Boolean; @@ -2426,14 +874,14 @@ function TTelegramBot.editMessageLiveLocation(const ChatId: TValue; const Messag begin Result := ExtractBool(RequestAPI('editMessageLiveLocation', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // - TtgApiParameter.Create('message_id', MessageId, nil, True), // + TtgApiParameter.Create('message_id', MessageId, 0, True), // TtgApiParameter.Create('latitude', Location.Latitude, '', False), // TtgApiParameter.Create('longitude', Location.Longitude, False, False), // TtgApiParameter.Create('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // ])); end; -function TTelegramBot.EditMessageLiveLocation(const InlineMessageId: string; const Location: TtgLocation; ReplyMarkup: IReplyMarkup): Boolean; +function TTelegramBot.editMessageLiveLocation(const InlineMessageId: string; const Location: TtgLocation; ReplyMarkup: IReplyMarkup): Boolean; begin Result := ExtractBool(RequestAPI('editMessageLiveLocation', [// TtgApiParameter.Create('inline_message_id', InlineMessageId, 0, True), // From f9d2e9cdf16b512b85638768d6e6b6117d074975 Mon Sep 17 00:00:00 2001 From: Antonina Soroka Date: Sun, 10 Dec 2017 13:43:29 +0200 Subject: [PATCH 09/14] =?UTF-8?q?=D0=A4=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D1=8F=20TtgChatMember.Status=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D1=8C=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=89=D0=B0=D0=B5?= =?UTF-8?q?=D1=82=20=D0=BF=D0=B5=D1=80=D0=B5=D1=87=D0=B8=D1=81=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B8=D0=BF=D0=B0=20TtgChatMemberSt?= =?UTF-8?q?atus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/TelegAPi.Types.Impl.pas | 23 +++++++++++++++++++---- Source/TelegAPi.Types.pas | 2 +- Source/TelegaPi.Types.Enums.pas | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Source/TelegAPi.Types.Impl.pas b/Source/TelegAPi.Types.Impl.pas index 93b66f8..f0621c8 100644 --- a/Source/TelegAPi.Types.Impl.pas +++ b/Source/TelegAPi.Types.Impl.pas @@ -23,7 +23,7 @@ TtgUser = class(TBaseJson, ItgUser) TtgChatMember = class(TBaseJson, ItgChatMember) public function User: ItgUser; - function Status: string; + function Status: TtgChatMemberStatus; function UntilDate: TDateTime; function CanBeEdited: Boolean; function CanChangeInfo: Boolean; @@ -1195,9 +1195,24 @@ function TtgChatMember.CanSendOtherMessages: Boolean; Result := ReadToSimpleType('can_send_other_messages'); end; -function TtgChatMember.Status: string; -begin - Result := ReadToSimpleType('status'); +function TtgChatMember.Status: TtgChatMemberStatus; +var + LStatus:string; +begin + LStatus := ReadToSimpleType('status'); + if LStatus = 'creator' then + Result := TtgChatMemberStatus.Creator + else if LStatus = 'administrator' then + Result := TtgChatMemberStatus.Administrator + else if LStatus = 'member' then + Result := TtgChatMemberStatus.Member + else if LStatus = 'restricted' then + Result := TtgChatMemberStatus.Restricted + else if LStatus = 'left' then + Result := TtgChatMemberStatus.Left + else if LStatus = 'kicked' then + Result := TtgChatMemberStatus.Kicked + else TBaseJson.UnSupported; end; function TtgChatMember.UntilDate: TDateTime; diff --git a/Source/TelegAPi.Types.pas b/Source/TelegAPi.Types.pas index 9d753fd..3690a72 100644 --- a/Source/TelegAPi.Types.pas +++ b/Source/TelegAPi.Types.pas @@ -21,7 +21,7 @@ interface ItgChatMember = interface ['{BE073F97-DA34-43E6-A15E-14A2B90CAB7E}'] function User: ItgUser; - function Status: string; + function Status: TtgChatMemberStatus; function UntilDate: TDateTime; function CanBeEdited: Boolean; function CanChangeInfo: Boolean; diff --git a/Source/TelegaPi.Types.Enums.pas b/Source/TelegaPi.Types.Enums.pas index ce91305..4670a59 100644 --- a/Source/TelegaPi.Types.Enums.pas +++ b/Source/TelegaPi.Types.Enums.pas @@ -79,6 +79,7 @@ interface /// Normal member of the ///
Member, + Restricted, /// /// A who left the From 63565390ef39b112f5f9bf1cfe134041a656b306 Mon Sep 17 00:00:00 2001 From: Antonina Soroka Date: Sun, 10 Dec 2017 13:44:26 +0200 Subject: [PATCH 10/14] =?UTF-8?q?=D0=9F=D0=B0=D1=80=D0=B0=D0=BC=D0=B5?= =?UTF-8?q?=D1=82=D1=80=20UntilDate=20=D0=B4=D0=BB=D1=8F=20=D1=83=D0=B4?= =?UTF-8?q?=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D0=B0=20=D1=82=D0=B5=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D1=8C=20=D0=B2=20=D0=B2=D0=B8=D0=B4=D0=B5=20=D1=82=D0=B8?= =?UTF-8?q?=D0=BF=D0=B0=20TDateTime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/TelegAPI.Bot.Impl.pas | 10 +++++----- Source/TelegAPI.Bot.pas | 4 ++-- Source/TelegAPI.CoreAPI.ParameterConverter.pas | 11 ++++++++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index 7df471b..df18d92 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -157,7 +157,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) function KickChatMember(// const ChatId: TValue; // const UserId: Int64; // - const UntilDate: Int64 = 0): Boolean; + const UntilDate: TDateTime = 0): Boolean; function UnbanChatMember(// const ChatId: TValue; // const UserId: Int64): Boolean; @@ -320,7 +320,7 @@ TTelegramBot = class(TtgAbstractComponent, ITelegramBot) function RestrictChatMember(// const ChatId: TValue; // const UserId: Int64; // - const UntilDate: Int64 = 0; // + const UntilDate: TDateTime = 0; // const CanSendMessages: Boolean = False; // const CanSendMediaMessages: Boolean = False; // const CanSendOtherMessages: Boolean = False; // @@ -731,12 +731,12 @@ function TTelegramBot.SendDocument(const ChatId: TValue; const Document: TtgFile ])); end; -function TTelegramBot.KickChatMember(const ChatId: TValue; const UserId, UntilDate: Int64): Boolean; +function TTelegramBot.KickChatMember(const ChatId: TValue; const UserId: Int64; const UntilDate: TDateTime): Boolean; begin Result := ExtractBool(RequestAPI('kickChatMember', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // TtgApiParameter.Create('user_id', UserId, 0, True), // - TtgApiParameter.Create('until_date', UntilDate, '', False)// + TtgApiParameter.Create('until_date', UntilDate, 0, False)// ])); end; @@ -992,7 +992,7 @@ function TTelegramBot.PromoteChatMember(const ChatId: TValue; const UserId: Int6 TtgApiParameter.Create('can_promote_members', CanPromoteMembers, False, False)])); end; -function TTelegramBot.RestrictChatMember(const ChatId: TValue; const UserId, UntilDate: Int64; const CanSendMessages, CanSendMediaMessages, CanSendOtherMessages, CanAddWebPagePreviews: Boolean): Boolean; +function TTelegramBot.RestrictChatMember(const ChatId: TValue; const UserId: Int64;const UntilDate: TDateTime; const CanSendMessages, CanSendMediaMessages, CanSendOtherMessages, CanAddWebPagePreviews: Boolean): Boolean; begin Result := ExtractBool(RequestAPI('restrictChatMember', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // diff --git a/Source/TelegAPI.Bot.pas b/Source/TelegAPI.Bot.pas index 1e55901..e0c246e 100644 --- a/Source/TelegAPI.Bot.pas +++ b/Source/TelegAPI.Bot.pas @@ -751,7 +751,7 @@ interface function KickChatMember(// const ChatId: TValue; // const UserId: Int64; // - const UntilDate: Int64 = 0): Boolean; + const UntilDate: TDateTime = 0): Boolean; /// /// Use this method to unban a previously kicked user in a supergroup. /// The user will not return to the group automatically, but will be able @@ -1645,7 +1645,7 @@ interface function RestrictChatMember(// const ChatId: TValue; // const UserId: Int64; // - const UntilDate: Int64 = 0; // + const UntilDate: TDateTime = 0; // const CanSendMessages: Boolean = False; // const CanSendMediaMessages: Boolean = False; // const CanSendOtherMessages: Boolean = False; // diff --git a/Source/TelegAPI.CoreAPI.ParameterConverter.pas b/Source/TelegAPI.CoreAPI.ParameterConverter.pas index aeeedd2..a80c4bf 100644 --- a/Source/TelegAPI.CoreAPI.ParameterConverter.pas +++ b/Source/TelegAPI.CoreAPI.ParameterConverter.pas @@ -5,7 +5,7 @@ interface uses System.Generics.Collections, System.Net.Mime, - System.rtti, + System.Rtti, System.SysUtils, System.TypInfo, TelegAPI.Types, @@ -23,6 +23,7 @@ TtgParamConverter = class TLoader = procedure(var AFormData: TMultipartFormData; AParam: TtgApiParameter) of object; protected procedure AddInteger(var AFormData: TMultipartFormData; AParam: TtgApiParameter); + procedure AddTDateTime(var AFormData: TMultipartFormData; AParam: TtgApiParameter); procedure AddString(var AFormData: TMultipartFormData; AParam: TtgApiParameter); procedure AddInt64(var AFormData: TMultipartFormData; AParam: TtgApiParameter); procedure AddBoolean(var AFormData: TMultipartFormData; AParam: TtgApiParameter); @@ -38,6 +39,7 @@ TtgParamConverter = class implementation uses + System.DateUtils, TelegAPI.Helpers; procedure TtgParamConverter.AddInteger(var AFormData: TMultipartFormData; AParam: TtgApiParameter); @@ -50,6 +52,12 @@ procedure TtgParamConverter.AddString(var AFormData: TMultipartFormData; AParam: AFormData.AddField(AParam.Key, AParam.Value.AsString); end; +procedure TtgParamConverter.AddTDateTime(var AFormData: TMultipartFormData; + AParam: TtgApiParameter); +begin + AFormData.AddField(AParam.Key, DateTimeToUnix(AParam.Value.AsType, False).ToString); +end; + function TtgParamConverter.ApplyParamToFormData(const AParam: TtgApiParameter; var Form: TMultipartFormData): Boolean; begin Result := ParamLoaders.ContainsKey(AParam.Value.TypeInfo); @@ -67,6 +75,7 @@ constructor TtgParamConverter.Create; ParamLoaders.Add(PTypeInfo(TypeInfo(string)), AddString); ParamLoaders.Add(PTypeInfo(TypeInfo(Int64)), AddInt64); ParamLoaders.Add(PTypeInfo(TypeInfo(Boolean)), AddBoolean); + ParamLoaders.Add(PTypeInfo(TypeInfo(TDateTime)), AddTDateTime); //class types ParamLoaders.Add(PTypeInfo(TypeInfo(TtgFileToSend)), AddClass_TtgFileToSend); end; From bfc63ee171263679d3e08c713fb3bf97201a97a5 Mon Sep 17 00:00:00 2001 From: Maxim Sysoev Date: Tue, 12 Dec 2017 20:24:56 +0200 Subject: [PATCH 11/14] =?UTF-8?q?=D0=9E=D0=B1=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA=20?= =?UTF-8?q?=D1=81=D0=B5=D1=82=D0=B8=20=D0=B2=20CoreAPI.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/TelegAPI.Bot.Impl.pas | 25 +++++++++++++----- Source/TelegAPi.CoreAPI.Request.pas | 41 +++++++++++++++++++++-------- Source/TelegAPi.Types.Impl.pas | 6 +++-- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index df18d92..b6df3ac 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -406,15 +406,26 @@ function TTelegramBot.RequestAPI(const Method: string; const Parameters: TArray< procedure(Data: string) begin Log.d('%s', [Data]); + if Assigned(OnReceiveRawData) then + OnReceiveRawData(Self, Data); + end; + LTgRequest.OnError := + procedure(E: Exception) + begin + ExceptionManager.HaveGlobalExeption('RequestAPI', E) end; LTgRequest.Parameters.AddRange(Parameters); - Result := LTgRequest.Execute.ContentAsString(TEncoding.UTF8); - if Assigned(OnReceiveRawData) then - OnReceiveRawData(Self, Result); - if Result.IsEmpty then - ExceptionManager.HaveGlobalExeption('RequestAPI', ETelegramUnknownData.Create('Can''t parse response')) + if LTgRequest.Execute(Result) then + begin + if Result.IsEmpty then + ExceptionManager.HaveGlobalExeption('RequestAPI', ETelegramUnknownData.Create('Can''t parse response')) + else + Result := ApiTest(Result, Parameters); + end else - Result := ApiTest(Result, Parameters); + begin + ExceptionManager.HaveGlobalExeption('RequestAPI', ETelegramUnknownData.Create('Can''t send data')) + end; finally LTgRequest.Free; end; @@ -992,7 +1003,7 @@ function TTelegramBot.PromoteChatMember(const ChatId: TValue; const UserId: Int6 TtgApiParameter.Create('can_promote_members', CanPromoteMembers, False, False)])); end; -function TTelegramBot.RestrictChatMember(const ChatId: TValue; const UserId: Int64;const UntilDate: TDateTime; const CanSendMessages, CanSendMediaMessages, CanSendOtherMessages, CanAddWebPagePreviews: Boolean): Boolean; +function TTelegramBot.RestrictChatMember(const ChatId: TValue; const UserId: Int64; const UntilDate: TDateTime; const CanSendMessages, CanSendMediaMessages, CanSendOtherMessages, CanAddWebPagePreviews: Boolean): Boolean; begin Result := ExtractBool(RequestAPI('restrictChatMember', [// TtgApiParameter.Create('chat_id', ChatId, 0, True), // diff --git a/Source/TelegAPi.CoreAPI.Request.pas b/Source/TelegAPi.CoreAPI.Request.pas index f17c546..5515a08 100644 --- a/Source/TelegAPi.CoreAPI.Request.pas +++ b/Source/TelegAPi.CoreAPI.Request.pas @@ -25,6 +25,7 @@ TtgApiRequest = class FOnReceive: TProc; FTelega: TTelegramBot; FOnSend: TProc; + FOnError: TProc; protected function DoPost: IHTTPResponse; function DoGet: IHTTPResponse; @@ -32,13 +33,14 @@ TtgApiRequest = class function StreamToString(Stream: TMemoryStream): string; public constructor Create(Sender: TTelegramBot; const AMethod: string); - function Execute: IHTTPResponse; - function ExecuteAsString: string; + function Execute(out Return: IHTTPResponse): Boolean; overload; + function Execute(out Return: string): Boolean; overload; function GetUrl: string; destructor Destroy; override; property Parameters: TObjectList read FParams write FParams; property OnReceive: TProc read FOnReceive write FOnReceive; property OnSend: TProc read FOnSend write FOnSend; + property OnError: TProc read FOnError write FOnError; end; implementation @@ -89,20 +91,37 @@ function TtgApiRequest.DoPost: IHTTPResponse; end; end; -function TtgApiRequest.Execute: IHTTPResponse; +function TtgApiRequest.Execute(out Return: IHTTPResponse): Boolean; begin + Result := False; FHttp.ProxySettings := FTelega.ProxySettings; - if Parameters.Count > 0 then - Result := DoPost - else - Result := DoGet; - if Assigned(OnReceive) then - OnReceive(Result.ContentAsString); + try + if Parameters.Count > 0 then + Return := DoPost + else + Return := DoGet; + if Return = nil then + Exit; + Result := True; + if Assigned(OnReceive) then + OnReceive(Return.ContentAsString); + except + on E: Exception do + begin + Result := False; + if Assigned(OnError) then + OnError(E); + end; + end; end; -function TtgApiRequest.ExecuteAsString: string; +function TtgApiRequest.Execute(out Return: string): Boolean; +var + LResponse: IHTTPResponse; begin - Result := Execute.ContentAsString(TEncoding.UTF8); + Result := Execute(LResponse); + if Result then + Return := LResponse.ContentAsString(TEncoding.UTF8); end; procedure TtgApiRequest.FillFormData(var AForm: TMultipartFormData); diff --git a/Source/TelegAPi.Types.Impl.pas b/Source/TelegAPi.Types.Impl.pas index f0621c8..e206c5a 100644 --- a/Source/TelegAPi.Types.Impl.pas +++ b/Source/TelegAPi.Types.Impl.pas @@ -1197,8 +1197,9 @@ function TtgChatMember.CanSendOtherMessages: Boolean; function TtgChatMember.Status: TtgChatMemberStatus; var - LStatus:string; + LStatus: string; begin + Result := TtgChatMemberStatus.Member; LStatus := ReadToSimpleType('status'); if LStatus = 'creator' then Result := TtgChatMemberStatus.Creator @@ -1212,7 +1213,8 @@ function TtgChatMember.Status: TtgChatMemberStatus; Result := TtgChatMemberStatus.Left else if LStatus = 'kicked' then Result := TtgChatMemberStatus.Kicked - else TBaseJson.UnSupported; + else + TBaseJson.UnSupported; end; function TtgChatMember.UntilDate: TDateTime; From c0498d3c4b0f57ce2f9ede85811f846f01b59dc4 Mon Sep 17 00:00:00 2001 From: Maxim Sysoev Date: Tue, 12 Dec 2017 20:43:08 +0200 Subject: [PATCH 12/14] =?UTF-8?q?=D0=91=D0=B0=D0=B7=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BC=D0=B5?= =?UTF-8?q?=D1=85=D0=B0=D0=BD=D0=B8=D0=B7=D0=BC=D0=B0=20=D1=81=D0=B5=D1=81?= =?UTF-8?q?=D1=81=D0=B8=D0=B9=20=20(=D0=B7=D0=B0=20=D0=B8=D0=B4=D0=B5?= =?UTF-8?q?=D1=8E=20=D0=B2=D0=B7=D1=8F=D1=82=20memcached)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Install/TelegaPi.dpk | 3 +- Install/TelegaPi.dproj | 387 +++++++++++++++---------------- Source/TelegaPi.Ext.Sessions.pas | 144 ++++++++++++ 3 files changed, 339 insertions(+), 195 deletions(-) create mode 100644 Source/TelegaPi.Ext.Sessions.pas diff --git a/Install/TelegaPi.dpk b/Install/TelegaPi.dpk index 302f8ac..fa359db 100644 --- a/Install/TelegaPi.dpk +++ b/Install/TelegaPi.dpk @@ -55,6 +55,7 @@ contains TelegAPI.Receiver.UI in '..\Source\TelegAPI.Receiver.UI.pas', TelegaPi.Factory in '..\Source\TelegaPi.Factory.pas', TelegAPi.CoreAPI.Request in '..\Source\TelegAPi.CoreAPI.Request.pas', - TelegAPi.CoreAPI.Parameter in '..\Source\TelegAPi.CoreAPI.Parameter.pas'; + TelegAPi.CoreAPI.Parameter in '..\Source\TelegAPi.CoreAPI.Parameter.pas', + TelegaPi.Ext.Sessions in '..\Source\TelegaPi.Ext.Sessions.pas'; end. diff --git a/Install/TelegaPi.dproj b/Install/TelegaPi.dproj index c22f718..46fdedc 100644 --- a/Install/TelegaPi.dproj +++ b/Install/TelegaPi.dproj @@ -14,35 +14,35 @@ true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true - Base true + Base + true All @@ -57,10 +57,8 @@ false true true - - - + false TelegaPi @@ -135,6 +133,11 @@ $(PreBuildEvent)]]> + + + Cfg_2 + Base + Base @@ -142,10 +145,6 @@ $(PreBuildEvent)]]> Cfg_1 Base - - Cfg_2 - Base - Delphi.Personality.12 @@ -172,12 +171,12 @@ $(PreBuildEvent)]]> true - + true - + true @@ -188,12 +187,10 @@ $(PreBuildEvent)]]> true - - - Contents\MacOS - 0 - + + + Contents\Resources 1 @@ -203,15 +200,18 @@ $(PreBuildEvent)]]> 1 - - - library\lib\armeabi-v7a + + + Contents\MacOS + 0 + + 1 - + - library\lib\armeabi + res\drawable-xxhdpi 1 @@ -221,94 +221,40 @@ $(PreBuildEvent)]]> 1 - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - - - res\values - 1 - - - - - res\drawable - 1 - - - - - res\drawable-xxhdpi + + 1 - - - - res\drawable-ldpi + 1 - - - - res\drawable-mdpi + 1 - - - res\drawable-hdpi + + 1 - - - - res\drawable-xhdpi + 1 - - - - res\drawable-small - 1 + + 0 - - - - res\drawable-normal + 1 - - - - res\drawable-large + 1 - - - res\drawable-xlarge + library\lib\armeabi-v7a 1 - - - - 0 - 1 - - 1 - @@ -319,124 +265,101 @@ $(PreBuildEvent)]]> .framework - + - 0 - .dll;.bpl + 1 - + 1 - .dylib - - - 0 - .bpl - - + + 1 - .dylib - + 1 - .dylib 1 - .dylib + + 1 - .dylib - - - - - 0 - 0 - - - 0 + 1 - 0 + 1 - - 0 + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 - - 0 + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 - + + library\lib\armeabi 1 - - - - - Contents\Resources + + + 1 - - 1 1 + + 0 - + 1 1 - - library\lib\armeabi-v7a - 1 - - - 1 - - - - 1 - - + + 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - - - - - + + + res\drawable-normal 1 - + + + + res\drawable-large 1 - + + + + res\drawable-xhdpi 1 @@ -460,18 +383,22 @@ $(PreBuildEvent)]]> 1 - - - 1 - - + + + + library\lib\armeabi-v7a 1 - + + + + res\drawable-hdpi 1 - + + + 1 @@ -482,6 +409,12 @@ $(PreBuildEvent)]]> 1 + + + res\values + 1 + + 1 @@ -493,7 +426,19 @@ $(PreBuildEvent)]]> 1 - + + + res\drawable-small + 1 + + + + + res\drawable + 1 + + + 1 @@ -504,46 +449,100 @@ $(PreBuildEvent)]]> 1 - - + + 1 - + + + + res\drawable 1 + + + + 0 + + + 0 + + + 0 + + 0 + + + 0 + + + 0 + + + + + library\lib\armeabi-v7a 1 - - + + + res\drawable-mdpi 1 + + + + 0 + .bpl + 1 + .dylib + + + 1 + .dylib 1 + .dylib - - 1 + .dylib - + + + + res\drawable-xlarge 1 - + + + + res\drawable-ldpi 1 - - - - + + + 0 + .dll;.bpl + + + 1 + .dylib + + - + + + + + @@ -558,51 +557,51 @@ $(PreBuildEvent)]]> - - False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False + + False diff --git a/Source/TelegaPi.Ext.Sessions.pas b/Source/TelegaPi.Ext.Sessions.pas new file mode 100644 index 0000000..55c4024 --- /dev/null +++ b/Source/TelegaPi.Ext.Sessions.pas @@ -0,0 +1,144 @@ +unit TelegaPi.Ext.Sessions; + +interface + +uses + System.Rtti, + System.Generics.Collections; + +type + ItgSession = interface + ['{D581A266-7AC0-496A-8784-9DCEDC6849C9}'] + function GetItem(const AKey: string): TValue; + procedure SetItem(const AKey: string; const Value: TValue); + function GetCreatedAt: TDateTime; + procedure SetCreatedAt(const Value: TDateTime); + // + procedure Clear; + property Items[const AKey: string]: TValue read GetItem write SetItem; Default; + property CreatedAt: TDateTime read GetCreatedAt write SetCreatedAt; + end; + + TtgSession = class(TInterfacedObject, ItgSession) + private + FItems: TDictionary; + FCreatedAt: TDateTime; + function GetItem(const AKey: string): TValue; + procedure SetItem(const AKey: string; const Value: TValue); + function GetCreatedAt: TDateTime; + procedure SetCreatedAt(const Value: TDateTime); + public + constructor Create; + destructor Destroy; override; + procedure Clear; + property CreatedAt: TDateTime read GetCreatedAt write SetCreatedAt; + property Items[const AKey: string]: TValue read GetItem write SetItem; Default; + end; + + ItgSessionManager = interface + ['{52E3CD5C-C096-4C3D-BC70-D284233C0250}'] + function GetItem(const AID: Int64): ItgSession; + procedure SetItem(const AID: Int64; const Value: ItgSession); + procedure Clear; + property Items[const AID: Int64]: ItgSession read GetItem write SetItem; Default; + end; + + TtgSessionManager = class(TInterfacedObject, ItgSessionManager) + private + class var + Instance: TtgSessionManager; + private + FItems: TDictionary; + function GetItem(const AID: Int64): ItgSession; + procedure SetItem(const AID: Int64; const Value: ItgSession); + public + class function NewInstance: TObject; override; + constructor Create; + destructor Destroy; override; + procedure Clear; + property Items[const AID: Int64]: ItgSession read GetItem write SetItem; Default; + end; + +implementation + +uses + System.SysUtils; + +procedure TtgSession.Clear; +begin + FItems.Clear; +end; + +constructor TtgSession.Create; +begin + FItems := TDictionary.Create; +end; + +destructor TtgSession.Destroy; +begin + FItems.Free; + inherited; +end; + +function TtgSession.GetCreatedAt: TDateTime; +begin + Result := FCreatedAt; +end; + +function TtgSession.GetItem(const AKey: string): TValue; +begin + if not FItems.ContainsKey(AKey) then + FItems.Add(AKey, TValue.Empty); + Result := FItems.Items[AKey] +end; + +procedure TtgSession.SetCreatedAt(const Value: TDateTime); +begin + FCreatedAt := Value; +end; + +procedure TtgSession.SetItem(const AKey: string; const Value: TValue); +begin + FItems.AddOrSetValue(AKey, Value); +end; + +{ TtgSesionManager } + +procedure TtgSessionManager.Clear; +begin + FItems.Clear; +end; + +constructor TtgSessionManager.Create; +begin + FItems := TDictionary.Create; +end; + +destructor TtgSessionManager.Destroy; +begin + FItems.Free; + inherited; +end; + +function TtgSessionManager.GetItem(const AID: Int64): ItgSession; +begin + if not FItems.ContainsKey(AID) then + FItems.Add(AID, TtgSession.Create); + Result := FItems.Items[AID] +end; + +class function TtgSessionManager.NewInstance: TObject; +begin + if Instance = nil then + Instance := TtgSessionManager(inherited NewInstance); + Result := Instance; +end; + +procedure TtgSessionManager.SetItem(const AID: Int64; const Value: ItgSession); +begin + FItems.AddOrSetValue(AID, Value); + FItems.Items[AID].CreatedAt := Now; +end; + +end. + From 650ddf2bdf38d1659b81ba66fdf666f403885e25 Mon Sep 17 00:00:00 2001 From: Sysoev Maxim Date: Tue, 19 Dec 2017 08:27:52 +0200 Subject: [PATCH 13/14] =?UTF-8?q?=D0=98=D0=B7=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D0=B1=D0=B0=D0=B3=20=D0=B2=20=D0=BA=D0=BB?= =?UTF-8?q?=D0=B0=D1=81=D1=81=D0=B5=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2.=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BD=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D1=8E?= =?UTF-8?q?=D1=89=D0=B8=D0=B5=20GUID"=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Install/TelegaPi.dproj | 386 ++++++++++++++++--------------- Source/TelegAPI.Bot.Impl.pas | 4 - Source/TelegAPi.Types.Impl.pas | 2 + Source/TelegAPi.Types.pas | 8 +- Source/TelegaPi.Ext.Sessions.pas | 8 +- 5 files changed, 205 insertions(+), 203 deletions(-) diff --git a/Install/TelegaPi.dproj b/Install/TelegaPi.dproj index 46fdedc..13dbba5 100644 --- a/Install/TelegaPi.dproj +++ b/Install/TelegaPi.dproj @@ -14,35 +14,35 @@ true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true - Base true + Base + true - true + true Cfg_1 true - true + true - true - Base true + Base + true All @@ -57,8 +57,10 @@ false true true - + + + false TelegaPi @@ -134,10 +136,6 @@ $(PreBuildEvent)]]> - - Cfg_2 - Base - Base @@ -145,6 +143,10 @@ $(PreBuildEvent)]]> Cfg_1 Base + + Cfg_2 + Base + Delphi.Personality.12 @@ -171,12 +173,12 @@ $(PreBuildEvent)]]> true - + true - + true @@ -187,10 +189,12 @@ $(PreBuildEvent)]]> true - - + + + Contents\MacOS + 0 + - Contents\Resources 1 @@ -200,18 +204,15 @@ $(PreBuildEvent)]]> 1 - - - Contents\MacOS - 0 - - + + + library\lib\armeabi-v7a 1 - + - res\drawable-xxhdpi + library\lib\armeabi 1 @@ -221,40 +222,94 @@ $(PreBuildEvent)]]> 1 - - + + + library\lib\armeabi-v7a 1 - + + + + res\drawable 1 - + + + + res\values 1 - - + + + res\drawable 1 - + + + + res\drawable-xxhdpi 1 - - 0 + + + + res\drawable-ldpi + 1 - + + + + res\drawable-mdpi 1 - + + + + res\drawable-hdpi 1 + + - library\lib\armeabi-v7a + res\drawable-xhdpi + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge 1 + + + + 0 + 1 + + 1 + @@ -265,101 +320,124 @@ $(PreBuildEvent)]]> .framework - + - 1 + 0 + .dll;.bpl - + 1 + .dylib - - - 1 + + + 0 + .bpl 1 + .dylib + + + 1 + .dylib 1 + .dylib - - 1 + .dylib + + + + + 0 - 1 + 0 + + + 0 - 1 + 0 - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 + + 0 - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 + + 0 - + - library\lib\armeabi 1 - - - + + + + + Contents\Resources 1 + + 1 1 - - 0 - + 1 1 - - + + library\lib\armeabi-v7a + 1 + 1 + + + + 1 + + + 1 + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 - - - res\drawable-normal + + + + + 1 - - - - res\drawable-large + 1 - - - - res\drawable-xhdpi + 1 @@ -383,22 +461,18 @@ $(PreBuildEvent)]]> 1 - - - - library\lib\armeabi-v7a + + 1 - - - - res\drawable-hdpi + + 1 + + 1 - - - + 1 @@ -409,12 +483,6 @@ $(PreBuildEvent)]]> 1 - - - res\values - 1 - - 1 @@ -426,19 +494,7 @@ $(PreBuildEvent)]]> 1 - - - res\drawable-small - 1 - - - - - res\drawable - 1 - - - + 1 @@ -449,100 +505,46 @@ $(PreBuildEvent)]]> 1 - - - 1 - - - - - res\drawable + + 1 - - - - 0 - - 0 - - - 0 + 1 - 0 - - - 0 - - - 0 - - - - - library\lib\armeabi-v7a 1 - - - res\drawable-mdpi + + 1 - - - - 0 - .bpl - 1 - .dylib - - - 1 - .dylib 1 - .dylib - - - 1 - .dylib - - - res\drawable-xlarge + + 1 - - - - res\drawable-ldpi + 1 - - - - 0 - .dll;.bpl - - + 1 - .dylib - - - + - - + + + + @@ -557,51 +559,51 @@ $(PreBuildEvent)]]> + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False + + False "$(BDS)\Bin\brcc32.exe" -fo "$(PROJECTDIR)\TTelegramBot.dcr" "$(PROJECTDIR)\TTelegramBot.rc" True False - - False diff --git a/Source/TelegAPI.Bot.Impl.pas b/Source/TelegAPI.Bot.Impl.pas index b6df3ac..4606a61 100644 --- a/Source/TelegAPI.Bot.Impl.pas +++ b/Source/TelegAPI.Bot.Impl.pas @@ -422,10 +422,6 @@ function TTelegramBot.RequestAPI(const Method: string; const Parameters: TArray< else Result := ApiTest(Result, Parameters); end - else - begin - ExceptionManager.HaveGlobalExeption('RequestAPI', ETelegramUnknownData.Create('Can''t send data')) - end; finally LTgRequest.Free; end; diff --git a/Source/TelegAPi.Types.Impl.pas b/Source/TelegAPi.Types.Impl.pas index e206c5a..42e8511 100644 --- a/Source/TelegAPi.Types.Impl.pas +++ b/Source/TelegAPi.Types.Impl.pas @@ -624,6 +624,7 @@ function TTgMessage.NewChatMembers: TArray; LJsonArray: TJSONArray; I: Integer; begin + Result := nil; if FJSON.TryGetValue('new_chat_members', LValue) then begin LJsonArray := TJSONObject.ParseJSONValue(LValue) as TJSONArray; @@ -643,6 +644,7 @@ function TTgMessage.NewChatPhoto: TArray; LJsonArray: TJSONArray; I: Integer; begin + Result := nil; if FJSON.TryGetValue('new_chat_photo', LValue) then begin LJsonArray := TJSONObject.ParseJSONValue(LValue) as TJSONArray; diff --git a/Source/TelegAPi.Types.pas b/Source/TelegAPi.Types.pas index 3690a72..f65ef6c 100644 --- a/Source/TelegAPi.Types.pas +++ b/Source/TelegAPi.Types.pas @@ -205,6 +205,7 @@ interface end; ItgInvoice = interface + ['{1D8923E1-068C-4747-84DE-A1B3B4674FD3}'] function Title: string; function Description: string; function StartParameter: string; @@ -213,6 +214,7 @@ interface end; ItgSuccessfulPayment = interface + ['{B2BE36C2-61F9-4D4B-AB9D-75BB524661AB}'] function Currency: string; function TotalAmount: Int64; end; @@ -413,7 +415,7 @@ TtgFileToSend = class Data: string; Content: TStream; Tag: Byte; - constructor Create(const ATag: Byte = FILE_TO_SEND_ERROR; AData: string = ''; AContent: TStream = nil); + constructor Create(const ATag: Byte = FILE_TO_SEND_ERROR; const AData: string = ''; AContent: TStream = nil); class function FromFile(const AFileName: string): TtgFileToSend; class function FromID(const AID: string): TtgFileToSend; class function FromURL(const AURL: string): TtgFileToSend; @@ -454,11 +456,11 @@ constructor TtgInputMediaVideo.Create(AMedia: TValue; const ACaption: string; AW { TtgFileToSend } -constructor TtgFileToSend.Create(const ATag: Byte; AData: string; AContent: TStream); +constructor TtgFileToSend.Create(const ATag: Byte; const AData: string; AContent: TStream); begin Tag := ATag; Data := AData; - Content := Content; + Content := AContent; end; class function TtgFileToSend.FromFile(const AFileName: string): TtgFileToSend; diff --git a/Source/TelegaPi.Ext.Sessions.pas b/Source/TelegaPi.Ext.Sessions.pas index 55c4024..d7b6f7e 100644 --- a/Source/TelegaPi.Ext.Sessions.pas +++ b/Source/TelegaPi.Ext.Sessions.pas @@ -46,7 +46,7 @@ TtgSession = class(TInterfacedObject, ItgSession) TtgSessionManager = class(TInterfacedObject, ItgSessionManager) private class var - Instance: TtgSessionManager; + FInstance: TtgSessionManager; private FItems: TDictionary; function GetItem(const AID: Int64): ItgSession; @@ -129,9 +129,9 @@ function TtgSessionManager.GetItem(const AID: Int64): ItgSession; class function TtgSessionManager.NewInstance: TObject; begin - if Instance = nil then - Instance := TtgSessionManager(inherited NewInstance); - Result := Instance; + if FInstance = nil then + FInstance := TtgSessionManager(inherited NewInstance); + Result := FInstance; end; procedure TtgSessionManager.SetItem(const AID: Int64; const Value: ItgSession); From 274189a6978a08aa5967e5892110a4d9fcda8210 Mon Sep 17 00:00:00 2001 From: Sysoev Maxim Date: Tue, 19 Dec 2017 12:13:55 +0200 Subject: [PATCH 14/14] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Delphinus.Info.json | 2 +- Install/TelegaPi.dproj | 15 ++++++++++++--- README.md | 4 ++-- Source/TelegAPI.Base.pas | 2 +- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Delphinus.Info.json b/Delphinus.Info.json index ae39c22..2a771f4 100644 --- a/Delphinus.Info.json +++ b/Delphinus.Info.json @@ -12,7 +12,7 @@ "dependencies": [], "author": "M.E.Sysoev", "description": "Telegram Bot API for Delphi", - "version": "3.5.0", + "version": "3.5.1", "first_version": "2.3.1", "project_url": "https://github.com/ms301/TelegAPI", "homepage_url": "https://t.me/telegaPiBotTest", diff --git a/Install/TelegaPi.dproj b/Install/TelegaPi.dproj index 13dbba5..d6edbff 100644 --- a/Install/TelegaPi.dproj +++ b/Install/TelegaPi.dproj @@ -69,23 +69,33 @@ $(PreBuildEvent)]]> None rtl;fmx;RESTComponents;$(DCC_UsePackage) android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + true + 1 package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= Debug Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) rtl;fmx;RESTComponents;$(DCC_UsePackage) + true true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + CompanyName=Maxim Sysoev;FileDescription=$(MSBuildProjectName);FileVersion=3.5.1.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 1033 + 3 + 5 + 1 Debug Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) rtl;fmx;RESTComponents;$(DCC_UsePackage) + true true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + CompanyName=Maxim Sysoev;FileDescription=$(MSBuildProjectName);FileVersion=3.5.1.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 1033 + 3 + 5 + 1 true @@ -159,7 +169,6 @@ $(PreBuildEvent)]]> Microsoft Office 2000 Sample Automation Server Wrapper Components Microsoft Office XP Sample Automation Server Wrapper Components - (untitled) diff --git a/README.md b/README.md index 7432466..b6ade14 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Telega π - Library for working with Telegram Bot API in Delphi -Version Bot API: *3.5.0* +Version Bot API: *3.5.1* ## Support project @@ -49,7 +49,7 @@ as well as many others who ask / suggest features / points bugs. Telega π - Библиотека для работы с Telegram Bot API в Delphi -Версия Bot API: *3.5.0* +Версия Bot API: *3.5.1* ## Помощь проекту diff --git a/Source/TelegAPI.Base.pas b/Source/TelegAPI.Base.pas index 81adddb..c24d44a 100644 --- a/Source/TelegAPI.Base.pas +++ b/Source/TelegAPI.Base.pas @@ -28,7 +28,7 @@ constructor TtgAbstractComponent.Create(AOwner: TComponent); begin inherited; FAutor := 'Maxim Sysoev'; - FVersion := '3.5.0'; + FVersion := '3.5.1'; end; end.