From 6e7acdbdbaa92a4b87ee0db0208a1cd8422afeed Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 10 Mar 2024 16:49:18 +0100 Subject: [PATCH 01/15] Bugfix in BBB --- TelegramBotBase/Builder/BotBaseBuilder.cs | 12 ++++++------ .../Builder/Interfaces/ILanguageSelectionStage.cs | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/TelegramBotBase/Builder/BotBaseBuilder.cs b/TelegramBotBase/Builder/BotBaseBuilder.cs index 64596b9..1baeba2 100644 --- a/TelegramBotBase/Builder/BotBaseBuilder.cs +++ b/TelegramBotBase/Builder/BotBaseBuilder.cs @@ -399,41 +399,41 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage, #region "Step 7 (Language)" /// - public IBuildingStage DefaultLanguage() + public IThreadingStage DefaultLanguage() { return this; } /// - public IBuildingStage UseEnglish() + public IThreadingStage UseEnglish() { Default.Language = new English(); return this; } /// - public IBuildingStage UseGerman() + public IThreadingStage UseGerman() { Default.Language = new German(); return this; } /// - public IBuildingStage UsePersian() + public IThreadingStage UsePersian() { Default.Language = new Persian(); return this; } /// - public IBuildingStage UseRussian() + public IThreadingStage UseRussian() { Default.Language = new Russian(); return this; } /// - public IBuildingStage Custom(Localization language) + public IThreadingStage Custom(Localization language) { Default.Language = language; return this; diff --git a/TelegramBotBase/Builder/Interfaces/ILanguageSelectionStage.cs b/TelegramBotBase/Builder/Interfaces/ILanguageSelectionStage.cs index b06addd..769e698 100644 --- a/TelegramBotBase/Builder/Interfaces/ILanguageSelectionStage.cs +++ b/TelegramBotBase/Builder/Interfaces/ILanguageSelectionStage.cs @@ -11,35 +11,35 @@ public interface ILanguageSelectionStage /// Selects the default language for control usage. (English) /// /// The next stage in the building process. - IBuildingStage DefaultLanguage(); + IThreadingStage DefaultLanguage(); /// /// Selects english as the default language for control labels. /// /// The next stage in the building process. - IBuildingStage UseEnglish(); + IThreadingStage UseEnglish(); /// /// Selects german as the default language for control labels. /// /// The next stage in the building process. - IBuildingStage UseGerman(); + IThreadingStage UseGerman(); /// /// Selects persian as the default language for control labels. /// /// The next stage in the building process. - IBuildingStage UsePersian(); + IThreadingStage UsePersian(); /// /// Selects russian as the default language for control labels. /// /// The next stage in the building process. - IBuildingStage UseRussian(); + IThreadingStage UseRussian(); /// /// Selects a custom language as the default language for control labels. /// /// The next stage in the building process. - IBuildingStage Custom(Localization language); + IThreadingStage Custom(Localization language); } \ No newline at end of file From b829f43c5d3f74e660d147b1ae8240af8178ebd6 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 10 Mar 2024 17:09:13 +0100 Subject: [PATCH 02/15] Adding a exception for invalid ServiceProviders #62 - adding an internal exception handler to catch InvalidOperationException and throw a new explicit one --- TelegramBotBase/BotBase.cs | 8 ++++++++ .../InvalidServiceProviderConfiguration.cs | 12 ++++++++++++ .../Factories/ServiceProviderStartFormFactory.cs | 12 +++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 TelegramBotBase/Exceptions/InvalidServiceProviderConfiguration.cs diff --git a/TelegramBotBase/BotBase.cs b/TelegramBotBase/BotBase.cs index a481d6d..8332aa2 100644 --- a/TelegramBotBase/BotBase.cs +++ b/TelegramBotBase/BotBase.cs @@ -8,6 +8,7 @@ using Telegram.Bot.Types; using TelegramBotBase.Args; using TelegramBotBase.Base; using TelegramBotBase.Enums; +using TelegramBotBase.Exceptions; using TelegramBotBase.Interfaces; using TelegramBotBase.Sessions; using Console = TelegramBotBase.Tools.Console; @@ -139,6 +140,13 @@ public sealed class BotBase mr.IsFirstHandler = false; } while (ds.FormSwitched && i < GetSetting(ESettings.NavigationMaximum, 10)); } + catch (InvalidServiceProviderConfiguration ex) + { + var ds = Sessions.GetSession(e.DeviceId); + OnException(new SystemExceptionEventArgs(e.Message.Text, e.DeviceId, ds, ex)); + + throw; + } catch (Exception ex) { var ds = Sessions.GetSession(e.DeviceId); diff --git a/TelegramBotBase/Exceptions/InvalidServiceProviderConfiguration.cs b/TelegramBotBase/Exceptions/InvalidServiceProviderConfiguration.cs new file mode 100644 index 0000000..03135ad --- /dev/null +++ b/TelegramBotBase/Exceptions/InvalidServiceProviderConfiguration.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TelegramBotBase.Exceptions +{ + public sealed class InvalidServiceProviderConfiguration : Exception + { + public InvalidServiceProviderConfiguration(string message, Exception innerException) : base(message, innerException) { } + + } +} diff --git a/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs b/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs index 8bac651..f143604 100644 --- a/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs +++ b/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Extensions.DependencyInjection; using TelegramBotBase.DependencyInjection; +using TelegramBotBase.Exceptions; using TelegramBotBase.Form; using TelegramBotBase.Interfaces; @@ -24,7 +25,16 @@ public class ServiceProviderStartFormFactory : IStartFormFactory public FormBase CreateForm() { - var fb = (FormBase)ActivatorUtilities.CreateInstance(_serviceProvider, _startFormClass); + FormBase fb = null; + + try + { + fb = (FormBase)ActivatorUtilities.CreateInstance(_serviceProvider, _startFormClass); + } + catch(InvalidOperationException ex) + { + throw new InvalidServiceProviderConfiguration(ex.Message, ex); + } //Sets an internal field for future ServiceProvider navigation fb.SetServiceProvider(_serviceProvider); From 652526ec59ed47cca48db8ed40716e8eb7cc0aa9 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 12 May 2024 18:40:55 +0300 Subject: [PATCH 03/15] Consolidate nuget references --- Examples/BotAndWebApplication/BotAndWebApplication.csproj | 2 +- Examples/EFCoreBot/EFCoreBot.csproj | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Examples/BotAndWebApplication/BotAndWebApplication.csproj b/Examples/BotAndWebApplication/BotAndWebApplication.csproj index 387f4c2..25fbd15 100644 --- a/Examples/BotAndWebApplication/BotAndWebApplication.csproj +++ b/Examples/BotAndWebApplication/BotAndWebApplication.csproj @@ -7,7 +7,7 @@ - + diff --git a/Examples/EFCoreBot/EFCoreBot.csproj b/Examples/EFCoreBot/EFCoreBot.csproj index 885fc87..1337c26 100644 --- a/Examples/EFCoreBot/EFCoreBot.csproj +++ b/Examples/EFCoreBot/EFCoreBot.csproj @@ -8,12 +8,12 @@ - - + + - + From e345fc29487309d597f3432863d7ab81877a8d89 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 12 May 2024 18:45:18 +0300 Subject: [PATCH 04/15] Fixing message loop handling of Action methods --- TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs | 2 +- TelegramBotBase/MessageLoops/FullMessageLoop.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs b/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs index 4bec2a0..5d719b1 100644 --- a/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs +++ b/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs @@ -79,7 +79,7 @@ public class FormBaseMessageLoop : IMessageLoopFactory } //Action Event - if (!session.FormSwitched && mr.IsAction) + if (!session.FormSwitched && mr.IsAction && !mr.Handled) { //Send Action event to controls await activeForm.ActionControls(mr); diff --git a/TelegramBotBase/MessageLoops/FullMessageLoop.cs b/TelegramBotBase/MessageLoops/FullMessageLoop.cs index 1affd19..061a2ab 100644 --- a/TelegramBotBase/MessageLoops/FullMessageLoop.cs +++ b/TelegramBotBase/MessageLoops/FullMessageLoop.cs @@ -72,7 +72,7 @@ public class FullMessageLoop : IMessageLoopFactory } //Action Event - if (!session.FormSwitched && mr.IsAction) + if (!session.FormSwitched && mr.IsAction && !mr.Handled) { //Send Action event to controls await activeForm.ActionControls(mr); From 5ce2360cc765aeacdc8c1d8ee64ce022cbdb7049 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 12 May 2024 19:01:50 +0300 Subject: [PATCH 05/15] Adding callbackdata too long exception and checks --- TelegramBotBase/Constants/Telegram.cs | 5 +++ .../CallbackDataTooLongException.cs | 31 ++++++++++++++++ TelegramBotBase/Form/CallbackData.cs | 35 ++++++++----------- 3 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 TelegramBotBase/Exceptions/CallbackDataTooLongException.cs diff --git a/TelegramBotBase/Constants/Telegram.cs b/TelegramBotBase/Constants/Telegram.cs index a2837d7..f91642d 100644 --- a/TelegramBotBase/Constants/Telegram.cs +++ b/TelegramBotBase/Constants/Telegram.cs @@ -16,4 +16,9 @@ public static class Telegram public const int MaxReplyKeyboardCols = 12; public const int MessageDeletionsPerSecond = 30; + + /// + /// The maximum length of callback data. Will raise an exception of it exceeds it. + /// + public const int MaxCallBackDataBytes = 64; } \ No newline at end of file diff --git a/TelegramBotBase/Exceptions/CallbackDataTooLongException.cs b/TelegramBotBase/Exceptions/CallbackDataTooLongException.cs new file mode 100644 index 0000000..a2ccd92 --- /dev/null +++ b/TelegramBotBase/Exceptions/CallbackDataTooLongException.cs @@ -0,0 +1,31 @@ +using System; +using Telegram.Bot.Exceptions; + +namespace TelegramBotBase.Exceptions; + +public sealed class CallbackDataTooLongException : Exception +{ + static ApiRequestException _innerException = new Telegram.Bot.Exceptions.ApiRequestException("Bad Request: BUTTON_DATA_INVALID", 400); + + static String _message = $"You have exceeded the maximum {Constants.Telegram.MaxCallBackDataBytes} bytes of callback data.\r\nThis is a pre-sending message from the TelegramBotBase framework.\r\nread more: https://core.telegram.org/bots/api#inlinekeyboardbutton"; + + static String _message_with_bytes = $"You have exceeded the maximum {Constants.Telegram.MaxCallBackDataBytes} bytes of callback data with @current_callback_bytes@ bytes.\r\nThis is a pre-sending message from the TelegramBotBase framework.\r\nread more: https://core.telegram.org/bots/api#inlinekeyboardbutton"; + + public CallbackDataTooLongException() : base(_message, _innerException) + { + + } + + public CallbackDataTooLongException(int current_callback_bytes) : base(getMessage(current_callback_bytes), _innerException) + { + + } + + static String getMessage(int current_callback_bytes = -1) + { + if (current_callback_bytes == -1) + return _message; + + return _message_with_bytes.Replace("@current_callback_bytes@", current_callback_bytes.ToString()); + } +} \ No newline at end of file diff --git a/TelegramBotBase/Form/CallbackData.cs b/TelegramBotBase/Form/CallbackData.cs index 8385551..13b701a 100644 --- a/TelegramBotBase/Form/CallbackData.cs +++ b/TelegramBotBase/Form/CallbackData.cs @@ -1,4 +1,6 @@ using Newtonsoft.Json; +using System.Text; +using TelegramBotBase.Exceptions; namespace TelegramBotBase.Form; @@ -23,22 +25,24 @@ public class CallbackData public static string Create(string method, string value) { - return new CallbackData(method, value).Serialize(); + return new CallbackData(method, value).Serialize(true); } /// /// Serializes data to json string /// /// - public string Serialize() + public string Serialize(bool throwExceptionOnOverflow = false) { - var s = ""; - try - { - s = JsonConvert.SerializeObject(this); - } - catch + var s = string.Empty; + + s = JsonConvert.SerializeObject(this); + + //Is data over 64 bytes ? + int byte_count = Encoding.UTF8.GetByteCount(s); + if (throwExceptionOnOverflow && byte_count > Constants.Telegram.MaxCallBackDataBytes) { + throw new CallbackDataTooLongException(byte_count); } return s; @@ -51,19 +55,8 @@ public class CallbackData /// public static CallbackData Deserialize(string data) { - CallbackData cd = null; - try - { - cd = JsonConvert.DeserializeObject(data); - - return cd; - } - catch - { - } - - return null; + return JsonConvert.DeserializeObject(data); } - public static implicit operator string(CallbackData callbackData) => callbackData.Serialize(); + public static implicit operator string(CallbackData callbackData) => callbackData.Serialize(true); } From 87d57c471a68e0fe4b4c29cb49ece4079caa91e1 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 12 May 2024 19:07:33 +0300 Subject: [PATCH 06/15] Update CallbackDataTooLongException.cs --- TelegramBotBase/Exceptions/CallbackDataTooLongException.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TelegramBotBase/Exceptions/CallbackDataTooLongException.cs b/TelegramBotBase/Exceptions/CallbackDataTooLongException.cs index a2ccd92..354a7f0 100644 --- a/TelegramBotBase/Exceptions/CallbackDataTooLongException.cs +++ b/TelegramBotBase/Exceptions/CallbackDataTooLongException.cs @@ -16,6 +16,10 @@ public sealed class CallbackDataTooLongException : Exception } + /// + /// + /// + /// The amount of callback bytes generated. public CallbackDataTooLongException(int current_callback_bytes) : base(getMessage(current_callback_bytes), _innerException) { From dc28bde382a03db51f5f8bb36b120a66a9445bb2 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 19 May 2024 14:06:01 +0200 Subject: [PATCH 07/15] Fix Action method handling, if handled by control already --- TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs | 7 +++++-- TelegramBotBase/MessageLoops/FullMessageLoop.cs | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs b/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs index 5d719b1..bdc6374 100644 --- a/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs +++ b/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs @@ -84,8 +84,11 @@ public class FormBaseMessageLoop : IMessageLoopFactory //Send Action event to controls await activeForm.ActionControls(mr); - //Send Action event to form itself - await activeForm.Action(mr); + if (!mr.Handled) + { + //Send Action event to form itself, if not already handled by a control + await activeForm.Action(mr); + } if (!mr.Handled) { diff --git a/TelegramBotBase/MessageLoops/FullMessageLoop.cs b/TelegramBotBase/MessageLoops/FullMessageLoop.cs index 061a2ab..a0c1c51 100644 --- a/TelegramBotBase/MessageLoops/FullMessageLoop.cs +++ b/TelegramBotBase/MessageLoops/FullMessageLoop.cs @@ -77,8 +77,11 @@ public class FullMessageLoop : IMessageLoopFactory //Send Action event to controls await activeForm.ActionControls(mr); - //Send Action event to form itself - await activeForm.Action(mr); + if (!mr.Handled) + { + //Send Action event to form itself, if not already handled by a control + await activeForm.Action(mr); + } if (!mr.Handled) { From 34e4429b384a1bc9987ea71684b6ba28d9c19c88 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 19 May 2024 14:15:56 +0200 Subject: [PATCH 08/15] Updating nuget dependencies --- .../TelegramBotBase.Extensions.Images.IronSoftware.csproj | 2 +- .../TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TelegramBotBase.Extensions.Images.IronSoftware/TelegramBotBase.Extensions.Images.IronSoftware.csproj b/TelegramBotBase.Extensions.Images.IronSoftware/TelegramBotBase.Extensions.Images.IronSoftware.csproj index df94a01..3f0707d 100644 --- a/TelegramBotBase.Extensions.Images.IronSoftware/TelegramBotBase.Extensions.Images.IronSoftware.csproj +++ b/TelegramBotBase.Extensions.Images.IronSoftware/TelegramBotBase.Extensions.Images.IronSoftware.csproj @@ -14,7 +14,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TelegramBotBase.Extensions.Serializer.Database.MSSQL/TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj index 7acb0e4..1243327 100644 --- a/TelegramBotBase.Extensions.Serializer.Database.MSSQL/TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj +++ b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj @@ -16,7 +16,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 175927fbab90f4d71d351c4a5dd163402e45b02d Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 19 May 2024 14:16:18 +0200 Subject: [PATCH 09/15] Updating nuget dependencies 2 --- ...gramBotBase.Extensions.Serializer.Database.PostgreSql.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TelegramBotBase.Extensions.Serializer.Database.PostgreSql/TelegramBotBase.Extensions.Serializer.Database.PostgreSql.csproj b/TelegramBotBase.Extensions.Serializer.Database.PostgreSql/TelegramBotBase.Extensions.Serializer.Database.PostgreSql.csproj index ce2b6ef..565075a 100644 --- a/TelegramBotBase.Extensions.Serializer.Database.PostgreSql/TelegramBotBase.Extensions.Serializer.Database.PostgreSql.csproj +++ b/TelegramBotBase.Extensions.Serializer.Database.PostgreSql/TelegramBotBase.Extensions.Serializer.Database.PostgreSql.csproj @@ -22,7 +22,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From 7a86ecdf32714f6e70139638a35dbc38ea696af2 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sat, 25 May 2024 17:24:24 +0200 Subject: [PATCH 10/15] Breakable change! Remove of most try/catch's in DeviceSession --- TelegramBotBase/Sessions/DeviceSession.cs | 305 +++++++--------------- 1 file changed, 97 insertions(+), 208 deletions(-) diff --git a/TelegramBotBase/Sessions/DeviceSession.cs b/TelegramBotBase/Sessions/DeviceSession.cs index 50ad65e..f2b49d2 100644 --- a/TelegramBotBase/Sessions/DeviceSession.cs +++ b/TelegramBotBase/Sessions/DeviceSession.cs @@ -131,13 +131,9 @@ public class DeviceSession : IDeviceSession public async Task ConfirmAction(string callbackQueryId, string message = "", bool showAlert = false, string urlToOpen = null) { - try - { - await Client.TelegramClient.AnswerCallbackQueryAsync(callbackQueryId, message, showAlert, urlToOpen); - } - catch - { - } + + await Client.TelegramClient.AnswerCallbackQueryAsync(callbackQueryId, message, showAlert, urlToOpen); + } /// @@ -157,17 +153,8 @@ public class DeviceSession : IDeviceSession throw new MessageTooLongException(text.Length); } - try - { - return await Api(a => - a.EditMessageTextAsync(DeviceId, messageId, text, parseMode, replyMarkup: markup)); - } - catch - { - } - - return null; + return await Api(a => a.EditMessageTextAsync(DeviceId, messageId, text, parseMode, replyMarkup: markup)); } /// @@ -185,17 +172,9 @@ public class DeviceSession : IDeviceSession throw new MessageTooLongException(text.Length); } - try - { - return await Api(a => - a.EditMessageTextAsync(DeviceId, messageId, text, parseMode, replyMarkup: markup)); - } - catch - { - } + return await Api(a => a.EditMessageTextAsync(DeviceId, messageId, text, parseMode, replyMarkup: markup)); - return null; } /// @@ -215,18 +194,8 @@ public class DeviceSession : IDeviceSession throw new MessageTooLongException(message.Text.Length); } - try - { - return await Api(a => - a.EditMessageTextAsync(DeviceId, message.MessageId, message.Text, parseMode, - replyMarkup: markup)); - } - catch - { - } - - - return null; + return await Api(a => a.EditMessageTextAsync(DeviceId, message.MessageId, message.Text, parseMode, + replyMarkup: markup)); } /// @@ -237,15 +206,8 @@ public class DeviceSession : IDeviceSession /// public async Task EditReplyMarkup(int messageId, ButtonForm bf) { - try - { - return await Api(a => a.EditMessageReplyMarkupAsync(DeviceId, messageId, bf)); - } - catch - { - } - return null; + return await Api(a => a.EditMessageReplyMarkupAsync(DeviceId, messageId, bf)); } /// @@ -277,21 +239,16 @@ public class DeviceSession : IDeviceSession text = text.MarkdownV2Escape(); } - try - { - var t = Api(a => a.SendTextMessageAsync(deviceId, text, null, parseMode, replyToMessageId: replyTo, - replyMarkup: markup, disableNotification: disableNotification)); - var o = GetOrigin(new StackTrace()); + var t = Api(a => a.SendTextMessageAsync(deviceId, text, null, parseMode, replyToMessageId: replyTo, + replyMarkup: markup, disableNotification: disableNotification)); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var o = GetOrigin(new StackTrace()); + + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -336,20 +293,15 @@ public class DeviceSession : IDeviceSession text = text.MarkdownV2Escape(); } - try - { - var t = Api(a => a.SendTextMessageAsync(DeviceId, text, null, parseMode, replyToMessageId: replyTo, - replyMarkup: markup, disableNotification: disableNotification)); - var o = GetOrigin(new StackTrace()); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var t = Api(a => a.SendTextMessageAsync(DeviceId, text, null, parseMode, replyToMessageId: replyTo, + replyMarkup: markup, disableNotification: disableNotification)); + + var o = GetOrigin(new StackTrace()); + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -379,20 +331,15 @@ public class DeviceSession : IDeviceSession text = text.MarkdownV2Escape(); } - try - { - var t = Api(a => a.SendTextMessageAsync(DeviceId, text, null, parseMode, replyToMessageId: replyTo, - replyMarkup: markup, disableNotification: disableNotification)); - var o = GetOrigin(new StackTrace()); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var t = Api(a => a.SendTextMessageAsync(DeviceId, text, null, parseMode, replyToMessageId: replyTo, + replyMarkup: markup, disableNotification: disableNotification)); + + var o = GetOrigin(new StackTrace()); + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -414,20 +361,15 @@ public class DeviceSession : IDeviceSession InlineKeyboardMarkup markup = buttons; - try - { - var t = Api(a => a.SendPhotoAsync(DeviceId, file, null, caption, parseMode, replyToMessageId: replyTo, - replyMarkup: markup, disableNotification: disableNotification)); - var o = GetOrigin(new StackTrace()); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var t = Api(a => a.SendPhotoAsync(DeviceId, file, null, caption, parseMode, replyToMessageId: replyTo, + replyMarkup: markup, disableNotification: disableNotification)); + + var o = GetOrigin(new StackTrace()); + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -449,21 +391,16 @@ public class DeviceSession : IDeviceSession InlineKeyboardMarkup markup = buttons; - try - { - var t = Api(a => a.SendVideoAsync(DeviceId, file, caption: caption, parseMode: parseMode, - replyToMessageId: replyTo, replyMarkup: markup, - disableNotification: disableNotification)); - var o = GetOrigin(new StackTrace()); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var t = Api(a => a.SendVideoAsync(DeviceId, file, caption: caption, parseMode: parseMode, + replyToMessageId: replyTo, replyMarkup: markup, + disableNotification: disableNotification)); + + var o = GetOrigin(new StackTrace()); + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -484,21 +421,16 @@ public class DeviceSession : IDeviceSession InlineKeyboardMarkup markup = buttons; - try - { - var t = Api(a => a.SendVideoAsync(DeviceId, InputFile.FromUri(url), parseMode: parseMode, - replyToMessageId: replyTo, replyMarkup: markup, - disableNotification: disableNotification)); - var o = GetOrigin(new StackTrace()); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var t = Api(a => a.SendVideoAsync(DeviceId, InputFile.FromUri(url), parseMode: parseMode, + replyToMessageId: replyTo, replyMarkup: markup, + disableNotification: disableNotification)); + + var o = GetOrigin(new StackTrace()); + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -520,24 +452,19 @@ public class DeviceSession : IDeviceSession InlineKeyboardMarkup markup = buttons; - try - { - var ms = new MemoryStream(video); - var fts = InputFile.FromStream(ms, filename); + var ms = new MemoryStream(video); - var t = Api(a => a.SendVideoAsync(DeviceId, fts, parseMode: parseMode, replyToMessageId: replyTo, - replyMarkup: markup, disableNotification: disableNotification)); + var fts = InputFile.FromStream(ms, filename); - var o = GetOrigin(new StackTrace()); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var t = Api(a => a.SendVideoAsync(DeviceId, fts, parseMode: parseMode, replyToMessageId: replyTo, + replyMarkup: markup, disableNotification: disableNotification)); + + var o = GetOrigin(new StackTrace()); + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -560,26 +487,21 @@ public class DeviceSession : IDeviceSession InlineKeyboardMarkup markup = buttons; - try - { - var fs = new FileStream(filepath, FileMode.Open); - var filename = Path.GetFileName(filepath); + var fs = new FileStream(filepath, FileMode.Open); - var fts = InputFile.FromStream(fs, filename); + var filename = Path.GetFileName(filepath); - var t = Api(a => a.SendVideoAsync(DeviceId, fts, parseMode: parseMode, replyToMessageId: replyTo, - replyMarkup: markup, disableNotification: disableNotification)); + var fts = InputFile.FromStream(fs, filename); - var o = GetOrigin(new StackTrace()); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var t = Api(a => a.SendVideoAsync(DeviceId, fts, parseMode: parseMode, replyToMessageId: replyTo, + replyMarkup: markup, disableNotification: disableNotification)); + + var o = GetOrigin(new StackTrace()); + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -650,20 +572,15 @@ public class DeviceSession : IDeviceSession markup = buttons; } - try - { - var t = Api(a => a.SendDocumentAsync(DeviceId, document, null, null, caption, replyMarkup: markup, - disableNotification: disableNotification, replyToMessageId: replyTo)); - var o = GetOrigin(new StackTrace()); - await OnMessageSent(new MessageSentEventArgs(await t, o)); + var t = Api(a => a.SendDocumentAsync(DeviceId, document, null, null, caption, replyMarkup: markup, + disableNotification: disableNotification, replyToMessageId: replyTo)); + + var o = GetOrigin(new StackTrace()); + await OnMessageSent(new MessageSentEventArgs(await t, o)); + + return await t; - return await t; - } - catch - { - return null; - } } /// @@ -714,22 +631,16 @@ public class DeviceSession : IDeviceSession public async Task HideReplyKeyboard(string closedMsg = "Closed", bool autoDeleteResponse = true) { - try - { - var m = await Send(closedMsg, new ReplyKeyboardRemove()); - if (autoDeleteResponse && m != null) - { - await DeleteMessage(m); - } + var m = await Send(closedMsg, new ReplyKeyboardRemove()); - return m; - } - catch + if (autoDeleteResponse && m != null) { + await DeleteMessage(m); } - return null; + return m; + } /// @@ -759,13 +670,9 @@ public class DeviceSession : IDeviceSession public virtual async Task ChangeChatPermissions(ChatPermissions permissions) { - try - { - await Api(a => a.SetChatPermissionsAsync(DeviceId, permissions)); - } - catch - { - } + + await Api(a => a.SetChatPermissionsAsync(DeviceId, permissions)); + } private Type GetOrigin(StackTrace stackTrace) @@ -878,49 +785,31 @@ public class DeviceSession : IDeviceSession public virtual async Task GetChatUser(long userId) { - try - { - return await Api(a => a.GetChatMemberAsync(DeviceId, userId)); - } - catch - { - } - return null; + return await Api(a => a.GetChatMemberAsync(DeviceId, userId)); + } [Obsolete("User BanUser instead.")] public virtual async Task KickUser(long userId, DateTime until = default) { - try - { - await Api(a => a.BanChatMemberAsync(DeviceId, userId, until)); - } - catch - { - } + + await Api(a => a.BanChatMemberAsync(DeviceId, userId, until)); + } public virtual async Task BanUser(long userId, DateTime until = default) { - try - { - await Api(a => a.BanChatMemberAsync(DeviceId, userId, until)); - } - catch - { - } + + await Api(a => a.BanChatMemberAsync(DeviceId, userId, until)); + } public virtual async Task UnbanUser(long userId) { - try - { - await Api(a => a.UnbanChatMemberAsync(DeviceId, userId)); - } - catch - { - } + + await Api(a => a.UnbanChatMemberAsync(DeviceId, userId)); + } #endregion From 801c0b77f814cdf96e16ad9f501d0872e14e5bf1 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Mon, 27 May 2024 21:39:36 +0200 Subject: [PATCH 11/15] Introducing BotGroupCommand property. --- TelegramBotBase/Base/MessageResult.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/TelegramBotBase/Base/MessageResult.cs b/TelegramBotBase/Base/MessageResult.cs index 11e33d7..20b2bc6 100644 --- a/TelegramBotBase/Base/MessageResult.cs +++ b/TelegramBotBase/Base/MessageResult.cs @@ -62,6 +62,11 @@ public class MessageResult : ResultBase /// public bool IsBotCommand => MessageText.StartsWith("/"); + /// + /// Is this a bot command sent from a group via @BotId ? + /// + public bool IsBotGroupCommand => IsBotCommand && MessageText.Contains("@"); + /// /// Returns a List of all parameters which has been sent with the command itself (i.e. /start 123 456 789 => /// 123,456,789) @@ -87,12 +92,17 @@ public class MessageResult : ResultBase { get { - if (!IsBotCommand) + if (IsBotGroupCommand) { - return null; + return MessageText.Substring(0, MessageText.LastIndexOf('@')).Split(' ')[0]; } - return MessageText.Split(' ')[0]; + if (IsBotCommand) + { + return MessageText.Split(' ')[0]; + } + + return null; } } From a7411176e6fa036fa389f6b0419e929b90c8d772 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Wed, 29 May 2024 21:29:14 +0200 Subject: [PATCH 12/15] Fixing the prototype solution of group commands detection --- TelegramBotBase/Base/MessageResult.cs | 56 ++++++++++++++------------- TelegramBotBase/BotBase.cs | 9 ++--- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/TelegramBotBase/Base/MessageResult.cs b/TelegramBotBase/Base/MessageResult.cs index 20b2bc6..c4eb955 100644 --- a/TelegramBotBase/Base/MessageResult.cs +++ b/TelegramBotBase/Base/MessageResult.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Newtonsoft.Json; @@ -9,16 +10,35 @@ namespace TelegramBotBase.Base; public class MessageResult : ResultBase { - internal MessageResult() - { - } - public MessageResult(Update update) { UpdateData = update; + + init(); } - public Update UpdateData { get; set; } + void init() + { + IsAction = UpdateData.CallbackQuery != null; + + IsBotCommand = UpdateData.Message.Entities.Any(a => a.Type == MessageEntityType.BotCommand); + + if (!IsBotCommand) + return; + + BotCommand = MessageText.Split(' ')[0]; + + IsBotGroupCommand = BotCommand.Contains("@"); + + if (IsBotGroupCommand) + { + BotCommand = BotCommand.Substring(0, BotCommand.LastIndexOf('@')); + } + + + } + + public Update UpdateData { get; private set; } /// /// Returns the Device/ChatId @@ -55,17 +75,17 @@ public class MessageResult : ResultBase /// /// Is this an action ? (i.e. button click) /// - public bool IsAction => UpdateData.CallbackQuery != null; + public bool IsAction { get; private set; } /// /// Is this a command ? Starts with a slash '/' and a command /// - public bool IsBotCommand => MessageText.StartsWith("/"); + public bool IsBotCommand { get; private set; } /// /// Is this a bot command sent from a group via @BotId ? /// - public bool IsBotGroupCommand => IsBotCommand && MessageText.Contains("@"); + public bool IsBotGroupCommand { get; private set; } /// /// Returns a List of all parameters which has been sent with the command itself (i.e. /start 123 456 789 => @@ -88,23 +108,7 @@ public class MessageResult : ResultBase /// /// Returns just the command (i.e. /start 1 2 3 => /start) /// - public string BotCommand - { - get - { - if (IsBotGroupCommand) - { - return MessageText.Substring(0, MessageText.LastIndexOf('@')).Split(' ')[0]; - } - - if (IsBotCommand) - { - return MessageText.Split(' ')[0]; - } - - return null; - } - } + public string BotCommand { get; private set; } /// /// Returns if this message will be used on the first form or not. diff --git a/TelegramBotBase/BotBase.cs b/TelegramBotBase/BotBase.cs index 8332aa2..c7d865a 100644 --- a/TelegramBotBase/BotBase.cs +++ b/TelegramBotBase/BotBase.cs @@ -197,13 +197,10 @@ public sealed class BotBase /// Contains the device/chat id of the device to update. public async Task InvokeMessageLoop(long deviceId) { - var mr = new MessageResult + var mr = new MessageResult(new Update { - UpdateData = new Update - { - Message = new Message() - } - }; + Message = new Message() + }); await InvokeMessageLoop(deviceId, mr); } From e3d1652a02328a79a3f5682ba92dc5e91858b1ef Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Wed, 29 May 2024 21:35:09 +0200 Subject: [PATCH 13/15] Fixing on EditableMessage --- TelegramBotBase/Base/MessageResult.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TelegramBotBase/Base/MessageResult.cs b/TelegramBotBase/Base/MessageResult.cs index c4eb955..0b86362 100644 --- a/TelegramBotBase/Base/MessageResult.cs +++ b/TelegramBotBase/Base/MessageResult.cs @@ -21,7 +21,7 @@ public class MessageResult : ResultBase { IsAction = UpdateData.CallbackQuery != null; - IsBotCommand = UpdateData.Message.Entities.Any(a => a.Type == MessageEntityType.BotCommand); + IsBotCommand = Message.Entities?.Any(a => a.Type == MessageEntityType.BotCommand) ?? false; if (!IsBotCommand) return; @@ -34,8 +34,6 @@ public class MessageResult : ResultBase { BotCommand = BotCommand.Substring(0, BotCommand.LastIndexOf('@')); } - - } public Update UpdateData { get; private set; } From 834038ff444b71d2d0346f8dd41fc1de45b3445f Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 9 Jun 2024 14:13:43 +0200 Subject: [PATCH 14/15] Adding additional bot command checks toa void invalid configurations --- TelegramBotBase/BotBase.cs | 2 +- TelegramBotBase/Commands/Extensions.cs | 13 ++++++++++++- TelegramBotBase/Constants/Telegram.cs | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/TelegramBotBase/BotBase.cs b/TelegramBotBase/BotBase.cs index c7d865a..5a50823 100644 --- a/TelegramBotBase/BotBase.cs +++ b/TelegramBotBase/BotBase.cs @@ -265,7 +265,7 @@ public sealed class BotBase { foreach (var scope in BotCommandScopes) { - if (scope.Value.Any(a => "/" + a.Command == command)) + if (scope.Value.Any(a => Constants.Telegram.BotCommandIndicator + a.Command == command)) { return true; } diff --git a/TelegramBotBase/Commands/Extensions.cs b/TelegramBotBase/Commands/Extensions.cs index 6a19ce1..e5b186d 100644 --- a/TelegramBotBase/Commands/Extensions.cs +++ b/TelegramBotBase/Commands/Extensions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Telegram.Bot.Types; @@ -20,6 +21,16 @@ public static class Extensions scope = BotCommandScope.Default(); } + if (string.IsNullOrEmpty(command)) + { + throw new ArgumentNullException(nameof(command), $"{nameof(command)} parameter can not be null or empty"); + } + + if(command.StartsWith(Constants.Telegram.BotCommandIndicator)) + { + throw new ArgumentException($"{nameof(command)} parameter does not have to start with a slash, please remove.", $"{nameof(command)}"); + } + var item = cmds.FirstOrDefault(a => a.Key.Type == scope.Type); if (item.Value != null) diff --git a/TelegramBotBase/Constants/Telegram.cs b/TelegramBotBase/Constants/Telegram.cs index f91642d..10b0eec 100644 --- a/TelegramBotBase/Constants/Telegram.cs +++ b/TelegramBotBase/Constants/Telegram.cs @@ -21,4 +21,10 @@ public static class Telegram /// The maximum length of callback data. Will raise an exception of it exceeds it. /// public const int MaxCallBackDataBytes = 64; + + + /// + /// The slash constant which indicates a bot command. + /// + public const string BotCommandIndicator = "/"; } \ No newline at end of file From 6adcc52ea276b3dcfe3d12971a83534f802a1681 Mon Sep 17 00:00:00 2001 From: Florian Zevedei Date: Sun, 9 Jun 2024 14:19:04 +0200 Subject: [PATCH 15/15] Adding null/empty checks to some controls to prevent invalid behaviour --- TelegramBotBase/Controls/Hybrid/ButtonGrid.cs | 51 ++++++++++++------- .../Controls/Hybrid/CheckedButtonList.cs | 20 +++++++- .../Controls/Hybrid/TaggedButtonGrid.cs | 19 ++++++- TelegramBotBase/Controls/Inline/Label.cs | 8 ++- .../Controls/Inline/MultiToggleButton.cs | 24 ++++++++- .../Controls/Inline/ToggleButton.cs | 26 +++++++++- TelegramBotBase/Localizations/English.cs | 1 + TelegramBotBase/Localizations/German.cs | 1 + TelegramBotBase/Localizations/Persian.cs | 1 + TelegramBotBase/Localizations/Russian.cs | 1 + 10 files changed, 130 insertions(+), 22 deletions(-) diff --git a/TelegramBotBase/Controls/Hybrid/ButtonGrid.cs b/TelegramBotBase/Controls/Hybrid/ButtonGrid.cs index bc06b06..7b4dea8 100644 --- a/TelegramBotBase/Controls/Hybrid/ButtonGrid.cs +++ b/TelegramBotBase/Controls/Hybrid/ButtonGrid.cs @@ -51,7 +51,24 @@ public class ButtonGrid : ControlBase DataSource = new ButtonFormDataSource(form); } - public string Title { get; set; } = Default.Language["ButtonGrid_Title"]; + string m_Title = Default.Language["ButtonGrid_Title"]; + + public string Title + { + get + { + return m_Title; + } + set + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentNullException($"{nameof(Title)}", $"{nameof(Title)} property must have been a value unequal to null/empty"); + } + + m_Title = value; + } + } public string ConfirmationText { get; set; } = ""; @@ -340,14 +357,14 @@ public class ButtonGrid : ControlBase } - //var button = HeadLayoutButtonRow?. .FirstOrDefault(a => a.Text.Trim() == result.MessageText) - // ?? SubHeadLayoutButtonRow?.FirstOrDefault(a => a.Text.Trim() == result.MessageText); + //var button = HeadLayoutButtonRow?. .FirstOrDefault(a => a.Text.Trim() == result.MessageText) + // ?? SubHeadLayoutButtonRow?.FirstOrDefault(a => a.Text.Trim() == result.MessageText); - // bf.ToList().FirstOrDefault(a => a.Text.Trim() == result.MessageText) + // bf.ToList().FirstOrDefault(a => a.Text.Trim() == result.MessageText) - //var index = bf.FindRowByButton(button); + //var index = bf.FindRowByButton(button); - check: + check: //Remove button click message if (DeleteReplyMessage) @@ -449,15 +466,15 @@ public class ButtonGrid : ControlBase } - //var bf = DataSource.ButtonForm; + //var bf = DataSource.ButtonForm; - //var button = HeadLayoutButtonRow?.FirstOrDefault(a => a.Value == result.RawData) - // ?? SubHeadLayoutButtonRow?.FirstOrDefault(a => a.Value == result.RawData) - // ?? bf.ToList().FirstOrDefault(a => a.Value == result.RawData); + //var button = HeadLayoutButtonRow?.FirstOrDefault(a => a.Value == result.RawData) + // ?? SubHeadLayoutButtonRow?.FirstOrDefault(a => a.Value == result.RawData) + // ?? bf.ToList().FirstOrDefault(a => a.Value == result.RawData); - //var index = bf.FindRowByButton(button); + //var index = bf.FindRowByButton(button); - check: + check: if (match != null) { await result.ConfirmAction(ConfirmationText ?? ""); @@ -506,13 +523,13 @@ public class ButtonGrid : ControlBase if (DataSource.RowCount > Constants.Telegram.MaxInlineKeyBoardRows && !EnablePaging) { throw new MaximumRowsReachedException - { Value = DataSource.RowCount, Maximum = Constants.Telegram.MaxInlineKeyBoardRows }; + { Value = DataSource.RowCount, Maximum = Constants.Telegram.MaxInlineKeyBoardRows }; } if (DataSource.ColumnCount > Constants.Telegram.MaxInlineKeyBoardCols) { throw new MaximumColsException - { Value = DataSource.ColumnCount, Maximum = Constants.Telegram.MaxInlineKeyBoardCols }; + { Value = DataSource.ColumnCount, Maximum = Constants.Telegram.MaxInlineKeyBoardCols }; } break; @@ -522,13 +539,13 @@ public class ButtonGrid : ControlBase if (DataSource.RowCount > Constants.Telegram.MaxReplyKeyboardRows && !EnablePaging) { throw new MaximumRowsReachedException - { Value = DataSource.RowCount, Maximum = Constants.Telegram.MaxReplyKeyboardRows }; + { Value = DataSource.RowCount, Maximum = Constants.Telegram.MaxReplyKeyboardRows }; } if (DataSource.ColumnCount > Constants.Telegram.MaxReplyKeyboardCols) { throw new MaximumColsException - { Value = DataSource.ColumnCount, Maximum = Constants.Telegram.MaxReplyKeyboardCols }; + { Value = DataSource.ColumnCount, Maximum = Constants.Telegram.MaxReplyKeyboardCols }; } break; @@ -693,7 +710,7 @@ public class ButtonGrid : ControlBase Updated(); } else - //Remove event handler + //Remove event handler { Device.MessageDeleted -= Device_MessageDeleted; } diff --git a/TelegramBotBase/Controls/Hybrid/CheckedButtonList.cs b/TelegramBotBase/Controls/Hybrid/CheckedButtonList.cs index ed44fc0..83cc657 100644 --- a/TelegramBotBase/Controls/Hybrid/CheckedButtonList.cs +++ b/TelegramBotBase/Controls/Hybrid/CheckedButtonList.cs @@ -13,6 +13,7 @@ using TelegramBotBase.Enums; using TelegramBotBase.Exceptions; using TelegramBotBase.Form; using TelegramBotBase.Localizations; +using static System.Net.Mime.MediaTypeNames; using static TelegramBotBase.Base.Async; namespace TelegramBotBase.Controls.Hybrid; @@ -51,7 +52,24 @@ public class CheckedButtonList : ControlBase DataSource = new ButtonFormDataSource(form); } - public string Title { get; set; } = Default.Language["ButtonGrid_Title"]; + string m_Title = Default.Language["ButtonGrid_Title"]; + + public string Title + { + get + { + return m_Title; + } + set + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentNullException($"{nameof(Title)}", $"{nameof(Title)} property must have been a value unequal to null/empty"); + } + + m_Title = value; + } + } public string ConfirmationText { get; set; } = ""; diff --git a/TelegramBotBase/Controls/Hybrid/TaggedButtonGrid.cs b/TelegramBotBase/Controls/Hybrid/TaggedButtonGrid.cs index 94266b7..d7e1ee4 100644 --- a/TelegramBotBase/Controls/Hybrid/TaggedButtonGrid.cs +++ b/TelegramBotBase/Controls/Hybrid/TaggedButtonGrid.cs @@ -67,7 +67,24 @@ public class TaggedButtonGrid : MultiView DataSource = new ButtonFormDataSource(form); } - public string Title { get; set; } = Default.Language["ButtonGrid_Title"]; + string m_Title = Default.Language["ButtonGrid_Title"]; + + public string Title + { + get + { + return m_Title; + } + set + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentNullException($"{nameof(Title)}", $"{nameof(Title)} property must have been a value unequal to null/empty"); + } + + m_Title = value; + } + } public string ConfirmationText { get; set; } diff --git a/TelegramBotBase/Controls/Inline/Label.cs b/TelegramBotBase/Controls/Inline/Label.cs index 429e505..b327f94 100644 --- a/TelegramBotBase/Controls/Inline/Label.cs +++ b/TelegramBotBase/Controls/Inline/Label.cs @@ -16,7 +16,7 @@ public class Label : ControlBase { private bool _renderNecessary = true; - private string _text = string.Empty; + private string _text = Default.Language["Label_Text"]; public String Text { @@ -29,6 +29,10 @@ public class Label : ControlBase if (_text == value) return; + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentNullException($"{nameof(Text)}", $"{nameof(Text)} property must have been a value unequal to null/empty"); + } _text = value; _renderNecessary = true; @@ -36,6 +40,8 @@ public class Label : ControlBase } } + + private ParseMode _parseMode = ParseMode.Markdown; public ParseMode ParseMode diff --git a/TelegramBotBase/Controls/Inline/MultiToggleButton.cs b/TelegramBotBase/Controls/Inline/MultiToggleButton.cs index 488a5f1..61fb6a7 100644 --- a/TelegramBotBase/Controls/Inline/MultiToggleButton.cs +++ b/TelegramBotBase/Controls/Inline/MultiToggleButton.cs @@ -32,10 +32,32 @@ public class MultiToggleButton : ControlBase /// public string ChangedString { get; set; } = Default.Language["MultiToggleButton_Changed"]; + private string _title = Default.Language["MultiToggleButton_Title"]; + /// /// This holds the title of the control. /// - public string Title { get; set; } = Default.Language["MultiToggleButton_Title"]; + public String Title + { + get + { + return _title; + } + set + { + if (_title == value) + return; + + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentNullException($"{nameof(Title)}", $"{nameof(Title)} must have been a value unequal to null/empty"); + } + + _title = value; + _renderNecessary = true; + + } + } public int? MessageId { get; set; } diff --git a/TelegramBotBase/Controls/Inline/ToggleButton.cs b/TelegramBotBase/Controls/Inline/ToggleButton.cs index 4c7811e..19c7cd2 100644 --- a/TelegramBotBase/Controls/Inline/ToggleButton.cs +++ b/TelegramBotBase/Controls/Inline/ToggleButton.cs @@ -36,7 +36,31 @@ public class ToggleButton : ControlBase public string ChangedString { get; set; } = Default.Language["ToggleButton_Changed"]; - public string Title { get; set; } = Default.Language["ToggleButton_Title"]; + private string _title = Default.Language["ToggleButton_Title"]; + + public String Title + { + get + { + return _title; + } + set + { + if (_title == value) + return; + + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentNullException($"{nameof(Title)}", $"{nameof(Title)} property must have been a value unequal to null/empty"); + } + + _title = value; + _renderNecessary = true; + + } + } + + public int? MessageId { get; set; } diff --git a/TelegramBotBase/Localizations/English.cs b/TelegramBotBase/Localizations/English.cs index 974143b..527b427 100644 --- a/TelegramBotBase/Localizations/English.cs +++ b/TelegramBotBase/Localizations/English.cs @@ -34,5 +34,6 @@ public sealed class English : Localization Values["ToggleButton_Changed"] = "Setting changed"; Values["ButtonGrid_SearchIcon"] = "🔍"; Values["TaggedButtonGrid_TagIcon"] = "📁"; + Values["Label_Text"] = "Default label text"; } } diff --git a/TelegramBotBase/Localizations/German.cs b/TelegramBotBase/Localizations/German.cs index ffe99c4..0d0f362 100644 --- a/TelegramBotBase/Localizations/German.cs +++ b/TelegramBotBase/Localizations/German.cs @@ -34,5 +34,6 @@ public sealed class German : Localization Values["ToggleButton_Changed"] = "Einstellung geändert"; Values["ButtonGrid_SearchIcon"] = "🔍"; Values["TaggedButtonGrid_TagIcon"] = "📁"; + Values["Label_Text"] = "Standard Label Text"; } } \ No newline at end of file diff --git a/TelegramBotBase/Localizations/Persian.cs b/TelegramBotBase/Localizations/Persian.cs index 72c6b40..add3088 100644 --- a/TelegramBotBase/Localizations/Persian.cs +++ b/TelegramBotBase/Localizations/Persian.cs @@ -34,6 +34,7 @@ public sealed class Persian : Localization Values["ToggleButton_Changed"] = "تنظیمات تغییر کرد"; Values["ButtonGrid_SearchIcon"] = "🔍"; Values["TaggedButtonGrid_TagIcon"] = "📁"; + Values["Label_Text"] = "متن برچسب پیش‌فرض"; } } diff --git a/TelegramBotBase/Localizations/Russian.cs b/TelegramBotBase/Localizations/Russian.cs index 08315e6..eff54d3 100644 --- a/TelegramBotBase/Localizations/Russian.cs +++ b/TelegramBotBase/Localizations/Russian.cs @@ -34,5 +34,6 @@ public sealed class Russian : Localization Values["ToggleButton_Changed"] = "Настройки изменены"; Values["ButtonGrid_SearchIcon"] = "🔍"; Values["TaggedButtonGrid_TagIcon"] = "📁"; + Values["Label_Text"] = "Текст метки по умолчанию"; } } \ No newline at end of file