diff --git a/.github/images/label.gif b/.github/images/label.gif new file mode 100644 index 0000000..c96e48a Binary files /dev/null and b/.github/images/label.gif differ diff --git a/Examples/BotAndWebApplication/BotStuff/StartForm.cs b/Examples/BotAndWebApplication/BotStuff/StartForm.cs index dbb2a99..f721ede 100644 --- a/Examples/BotAndWebApplication/BotStuff/StartForm.cs +++ b/Examples/BotAndWebApplication/BotStuff/StartForm.cs @@ -6,7 +6,7 @@ namespace BotAndWebApplication.BotStuff { public class StartForm : FormBase { - ButtonGrid _grid = null; + ButtonGrid? _grid = null; int MyCounter { get; set; } = 0; @@ -34,10 +34,10 @@ namespace BotAndWebApplication.BotStuff AddControl(_grid); } - private async Task _grid_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e) + private Task _grid_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e) { if (e.Button == null || e.Button.Value == null) - return; + return Task.CompletedTask; switch (e.Button.Value) { @@ -60,6 +60,7 @@ namespace BotAndWebApplication.BotStuff } + return Task.CompletedTask; } } } diff --git a/Examples/InlineAndReplyCombination/Baseclasses/MultipleChoiceForm.cs b/Examples/InlineAndReplyCombination/Baseclasses/MultipleChoiceForm.cs new file mode 100644 index 0000000..fce1a74 --- /dev/null +++ b/Examples/InlineAndReplyCombination/Baseclasses/MultipleChoiceForm.cs @@ -0,0 +1,88 @@ +using InlineAndReplyCombination.Forms; +using InlineAndReplyCombination.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TelegramBotBase.Attributes; +using TelegramBotBase.Controls.Hybrid; +using TelegramBotBase.Form; + +namespace InlineAndReplyCombination.Baseclasses +{ + public class MultipleChoiceForm : AutoCleanForm + { + [SaveState] + public UserDetails? UserDetails { get; set; } + + ButtonGrid? ReplyButtonGrid; + + public String ReplyButtonTitle { get; set; } = "Restart"; + + protected int CurrentStep = 1; + protected int MaxSteps = 3; + + public MultipleChoiceForm() + { + this.Init += MultipleChoiceForm_Init; + } + + private Task MultipleChoiceForm_Init(object sender, TelegramBotBase.Args.InitEventArgs e) + { + //Reply keyboard + var bf = new ButtonForm(); + + bf.AddButtonRow(ReplyButtonTitle, "replyButtonID"); + + ReplyButtonGrid = new ButtonGrid(bf); + + ReplyButtonGrid.Title = $"Step {CurrentStep} / {MaxSteps}"; + ReplyButtonGrid.KeyboardType = TelegramBotBase.Enums.EKeyboardType.ReplyKeyboard; + + ReplyButtonGrid.ButtonClicked += ReplyButtonGrid_ButtonClicked; + + AddControl(ReplyButtonGrid); + + return Task.CompletedTask; + } + + + private async Task ReplyButtonGrid_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e) + { + if (e.Button == null) + return; + + switch (e.Button.Value) + { + case "replyButtonID": + + await PressReplyButton(); + + + break; + + } + + } + + + public virtual Task PressReplyButton() + { + return Task.CompletedTask; + } + + public override Task NavigateTo(FormBase newForm, params object[] args) + { + //Move user details over to navigating form + if (newForm is MultipleChoiceForm mcf) + { + mcf.UserDetails = UserDetails; + } + + return base.NavigateTo(newForm, args); + } + + + } +} diff --git a/Examples/InlineAndReplyCombination/Forms/StartForm.cs b/Examples/InlineAndReplyCombination/Forms/StartForm.cs new file mode 100644 index 0000000..54ecd8f --- /dev/null +++ b/Examples/InlineAndReplyCombination/Forms/StartForm.cs @@ -0,0 +1,68 @@ +using InlineAndReplyCombination.Baseclasses; +using InlineAndReplyCombination.Forms.Steps; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TelegramBotBase.Base; +using TelegramBotBase.Controls.Hybrid; +using TelegramBotBase.Form; + +namespace InlineAndReplyCombination.Forms +{ + public class StartForm : AutoCleanForm + { + ButtonGrid? buttonGrid; + + public StartForm() + { + this.Init += StartForm_Init; + + } + + private Task StartForm_Init(object sender, TelegramBotBase.Args.InitEventArgs e) + { + var bf = new ButtonForm(); + + bf.AddButtonRow("Start registration", "start"); + + buttonGrid = new ButtonGrid(bf); + + buttonGrid.Title = "Welcome to The InlineAndReplyCombination Bot!"; + buttonGrid.ButtonClicked += ButtonGrid_ButtonClicked; + buttonGrid.KeyboardType = TelegramBotBase.Enums.EKeyboardType.ReplyKeyboard; + + AddControl(buttonGrid); + + return Task.CompletedTask; + } + + private async Task ButtonGrid_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e) + { + if(e.Button == null) + { + return; + } + + + switch(e.Button.Value) + { + case "start": + + var mf = new MainForm(); + + mf.UserDetails = new Model.UserDetails(); + + await NavigateTo(mf); + + break; + + } + + + } + + + } +} diff --git a/Examples/InlineAndReplyCombination/Forms/Steps/MainForm.cs b/Examples/InlineAndReplyCombination/Forms/Steps/MainForm.cs new file mode 100644 index 0000000..fc1d4f3 --- /dev/null +++ b/Examples/InlineAndReplyCombination/Forms/Steps/MainForm.cs @@ -0,0 +1,96 @@ +using InlineAndReplyCombination.Baseclasses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using Telegram.Bot.Types; +using TelegramBotBase.Base; +using TelegramBotBase.Controls.Hybrid; +using TelegramBotBase.Form; + +namespace InlineAndReplyCombination.Forms.Steps +{ + public class MainForm : MultipleChoiceForm + { + + ButtonGrid? InlineButtonGrid; + + public static List> AllowedInlineInputs; + + static MainForm() + { + AllowedInlineInputs = new List>() + { + new("< 18", "<18"), + new("18 to 25", "18t25"), + new("25 to 35", "25t35"), + new("35 to 50", "35t50"), + new("over 50", "o50") + }; + + } + + public MainForm() + { + + Init += MainForm_Init; + + ReplyButtonTitle = "Start over"; + CurrentStep = 1; + } + + private Task MainForm_Init(object sender, TelegramBotBase.Args.InitEventArgs e) + { + + //Inline Keyboard + var bf_ages = new ButtonForm(); + + //Add all options in a single column + bf_ages.AddSplitted(AllowedInlineInputs.Select(a => new ButtonBase(a.Item1, a.Item2)), 1); + + bf_ages.AddButtonRow("Some invalid input", "Invalid"); + + InlineButtonGrid = new ButtonGrid(bf_ages); + InlineButtonGrid.ConfirmationText = "Thank you"; + InlineButtonGrid.Title = "Please choose your age:"; + InlineButtonGrid.ButtonClicked += InlineButtonGrid_ButtonClicked; + + InlineButtonGrid.KeyboardType = TelegramBotBase.Enums.EKeyboardType.InlineKeyBoard; + + AddControl(InlineButtonGrid); + + return Task.CompletedTask; + } + + private async Task InlineButtonGrid_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e) + { + //Not found + if (!AllowedInlineInputs.Any(a => a.Item2 == e.Button.Value)) + { + await Device.Send("Invalid input!"); + return; + } + + if (UserDetails == null) + { + return; + } + + UserDetails.AgeRange = e.Button?.Value ?? "unknown"; + + var sf = new SecondForm(); + + await NavigateTo(sf); + } + + + public override async Task PressReplyButton() + { + var sf = new StartForm(); + + await NavigateTo(sf); + } + } +} diff --git a/Examples/InlineAndReplyCombination/Forms/Steps/SecondForm.cs b/Examples/InlineAndReplyCombination/Forms/Steps/SecondForm.cs new file mode 100644 index 0000000..8c9fd7a --- /dev/null +++ b/Examples/InlineAndReplyCombination/Forms/Steps/SecondForm.cs @@ -0,0 +1,95 @@ +using InlineAndReplyCombination.Baseclasses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using Telegram.Bot.Types; +using TelegramBotBase.Base; +using TelegramBotBase.Controls.Hybrid; +using TelegramBotBase.Form; + +namespace InlineAndReplyCombination.Forms.Steps +{ + public class SecondForm : MultipleChoiceForm + { + + ButtonGrid? InlineButtonGrid; + + public static List> AllowedInlineInputs; + + static SecondForm() + { + AllowedInlineInputs = new List>() + { + new("Green", "green"), + new("Yellow", "yellow"), + new("Red", "red"), + new("Purple", "purple"), + new("Black", "black"), + new("Gold", "gold") + }; + } + + public SecondForm() + { + + Init += SecondForm_Init; + + ReplyButtonTitle = "Go back"; + CurrentStep = 2; + + } + + private Task SecondForm_Init(object sender, TelegramBotBase.Args.InitEventArgs e) + { + + //Inline Keyboard + var bf_ages = new ButtonForm(); + + //Add all options in a single column + bf_ages.AddSplitted(AllowedInlineInputs.Select(a => new ButtonBase(a.Item1, a.Item2)), 1); + + InlineButtonGrid = new ButtonGrid(bf_ages); + InlineButtonGrid.ConfirmationText = "Thank you"; + InlineButtonGrid.Title = "Please choose your favourite color:"; + InlineButtonGrid.ButtonClicked += InlineButtonGrid_ButtonClicked; + + InlineButtonGrid.KeyboardType = TelegramBotBase.Enums.EKeyboardType.InlineKeyBoard; + + AddControl(InlineButtonGrid); + + return Task.CompletedTask; + } + + private async Task InlineButtonGrid_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e) + { + //Not found + if (!AllowedInlineInputs.Any(a => a.Item2 == e.Button.Value)) + { + await Device.Send("Invalid input!"); + return; + } + + if (UserDetails == null) + { + return; + } + + UserDetails.FavouriteColor = e.Button?.Value ?? "unknown"; + + var tf = new ThirdForm(); + + await NavigateTo(tf); + } + + + public override async Task PressReplyButton() + { + var mf = new MainForm(); + + await NavigateTo(mf); + } + } +} diff --git a/Examples/InlineAndReplyCombination/Forms/Steps/Summary.cs b/Examples/InlineAndReplyCombination/Forms/Steps/Summary.cs new file mode 100644 index 0000000..9e4ffe4 --- /dev/null +++ b/Examples/InlineAndReplyCombination/Forms/Steps/Summary.cs @@ -0,0 +1,84 @@ +using InlineAndReplyCombination.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TelegramBotBase.Attributes; +using TelegramBotBase.Base; +using TelegramBotBase.Controls.Hybrid; +using TelegramBotBase.Form; + +namespace InlineAndReplyCombination.Forms.Steps +{ + public class Summary : AutoCleanForm + { + [SaveState] + public UserDetails? UserDetails { get; set; } + + ButtonGrid? ReplyButtonGrid { get; set; } + + public Summary() + { + Init += Summary_Init; + + } + + private Task Summary_Init(object sender, TelegramBotBase.Args.InitEventArgs e) + { + var bf = new ButtonForm(); + + bf.AddButtonRow("Go back", "back"); + bf.AddButtonRow("Return to Start", "start"); + + + + ReplyButtonGrid = new ButtonGrid(bf); + ReplyButtonGrid.Title = "Thank you for your time!"; + ReplyButtonGrid.ButtonClicked += ReplyButtonGrid_ButtonClicked; + + AddControl(ReplyButtonGrid); + + return Task.CompletedTask; + } + + public override async Task Load(MessageResult message) + { + + if (UserDetails == null) + { + var sf = new StartForm(); + await NavigateTo(sf); + return; + } + + await Device.Send($"Your inputs are:\r\n\r\nYour age: {UserDetails.AgeRange}\r\nYour favourite color: {UserDetails.FavouriteColor}\r\nYour favourite city: {UserDetails.FavouriteCity}"); + } + + private async Task ReplyButtonGrid_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e) + { + switch (e.Button.Value ?? "") + { + case "start": + + var sf = new StartForm(); + + await NavigateTo(sf); + + break; + + case "back": + + var tf = new ThirdForm(); + + tf.UserDetails = UserDetails; + + await NavigateTo(tf); + + break; + + } + + } + } +} diff --git a/Examples/InlineAndReplyCombination/Forms/Steps/ThirdForm.cs b/Examples/InlineAndReplyCombination/Forms/Steps/ThirdForm.cs new file mode 100644 index 0000000..043b744 --- /dev/null +++ b/Examples/InlineAndReplyCombination/Forms/Steps/ThirdForm.cs @@ -0,0 +1,95 @@ +using InlineAndReplyCombination.Baseclasses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using Telegram.Bot.Types; +using TelegramBotBase.Base; +using TelegramBotBase.Controls.Hybrid; +using TelegramBotBase.Form; + +namespace InlineAndReplyCombination.Forms.Steps +{ + public class ThirdForm : MultipleChoiceForm + { + + ButtonGrid? InlineButtonGrid; + + public static List> AllowedInlineInputs; + + static ThirdForm() + { + AllowedInlineInputs = new List>() + { + new("Berlin", "Berlin"), + new("Vienna", "Vienna"), + new("Rome", "Rome"), + new("London", "London"), + new("Moscow", "Moscow"), + new("Bukarest", "Bukarest") + }; + } + + public ThirdForm() + { + Init += SecondForm_Init; + + ReplyButtonTitle = "Go back"; + CurrentStep = 3; + + } + + private Task SecondForm_Init(object sender, TelegramBotBase.Args.InitEventArgs e) + { + + //Inline Keyboard + var bf_ages = new ButtonForm(); + + //Add all options in a single column + bf_ages.AddSplitted(AllowedInlineInputs.Select(a => new ButtonBase(a.Item1, a.Item2)), 1); + + InlineButtonGrid = new ButtonGrid(bf_ages); + InlineButtonGrid.ConfirmationText = "Thank you"; + InlineButtonGrid.Title = "Please choose your favourite city:"; + InlineButtonGrid.ButtonClicked += InlineButtonGrid_ButtonClicked; + + InlineButtonGrid.KeyboardType = TelegramBotBase.Enums.EKeyboardType.InlineKeyBoard; + + AddControl(InlineButtonGrid); + + return Task.CompletedTask; + } + + private async Task InlineButtonGrid_ButtonClicked(object sender, TelegramBotBase.Args.ButtonClickedEventArgs e) + { + //Not found + if (!AllowedInlineInputs.Any(a => a.Item2 == e.Button.Value)) + { + await Device.Send("Invalid input!"); + return; + } + + if (UserDetails == null) + { + return; + } + + UserDetails.FavouriteCity = e.Button?.Value ?? "unknown"; + + var sum = new Summary(); + sum.UserDetails = this.UserDetails; + await NavigateTo(sum); + + } + + + public override async Task PressReplyButton() + { + var sf = new SecondForm(); + + await NavigateTo(sf); + } + } +} diff --git a/Examples/InlineAndReplyCombination/InlineAndReplyCombination.csproj b/Examples/InlineAndReplyCombination/InlineAndReplyCombination.csproj new file mode 100644 index 0000000..352fe2f --- /dev/null +++ b/Examples/InlineAndReplyCombination/InlineAndReplyCombination.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + diff --git a/Examples/InlineAndReplyCombination/Model/UserDetails.cs b/Examples/InlineAndReplyCombination/Model/UserDetails.cs new file mode 100644 index 0000000..fc5409b --- /dev/null +++ b/Examples/InlineAndReplyCombination/Model/UserDetails.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace InlineAndReplyCombination.Model +{ + [DebuggerDisplay("{AgeRange}, {FavouriteColor}, {FavouriteCity}")] + public class UserDetails + { + public String? AgeRange { get; set; } + + public String? FavouriteColor { get; set; } + + public String? FavouriteCity { get; set; } + + } +} diff --git a/Examples/InlineAndReplyCombination/Program.cs b/Examples/InlineAndReplyCombination/Program.cs new file mode 100644 index 0000000..00372c7 --- /dev/null +++ b/Examples/InlineAndReplyCombination/Program.cs @@ -0,0 +1,41 @@ +using InlineAndReplyCombination.Forms; +using TelegramBotBase; +using TelegramBotBase.Builder; + +namespace InlineAndReplyCombination +{ + internal class Program + { + public static BotBase? BotBaseInstance { get; private set; } + + static async Task Main(string[] args) + { + + + BotBaseInstance = BotBaseBuilder.Create() + .WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? + throw new Exception("API_KEY is not set")) + .DefaultMessageLoop() + .WithStartForm() + .NoProxy() + .DefaultCommands() + .UseJSON(Path.Combine(Directory.GetCurrentDirectory(), "states.json")) + .UseEnglish() + .Build(); + + + + await BotBaseInstance.UploadBotCommands(); + + + await BotBaseInstance.Start(); + + Console.WriteLine("Telegram Bot started"); + + Console.ReadLine(); + + + await BotBaseInstance.Stop(); + } + } +} \ No newline at end of file diff --git a/Examples/InlineAndReplyCombination/README.md b/Examples/InlineAndReplyCombination/README.md new file mode 100644 index 0000000..b4b825a --- /dev/null +++ b/Examples/InlineAndReplyCombination/README.md @@ -0,0 +1,16 @@ +# InlineAndReplyCombination Example + + +Here you got a basic example on how to use Inline buttons and a ReplyMarkup at the same time. + +I used 2 ButtonGrid controls for this purpose. + +One for the ReplyKeyboard and one for the Inline buttons. + +The ReplyKeyboard is within the base [*MultipleChoiceForm*](Baseclasses/MultipleChoiceForm.cs) class just for reusing a bit of code. + + +You can put it into all single forms as well, if you wish. Works the same. + + +Session serialization is enabled by default via the JSON serializer. \ No newline at end of file diff --git a/README.md b/README.md index fb5c829..e1fbaba 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ BitTorrent: `TYVZSykaVT1nKZnz9hjDgBRNB9VavU1bpW` * [PromptDialog](#prompt-dialog) * [ConfirmDialog](#confirm-dialog) - [Controls](#controls) + * [Label](#label) * [ProgressBar](#progress-bar) * [CalendarPicker](#calendar-picker) * [MonthPicker](#month-picker) @@ -636,21 +637,36 @@ await this.NavigateTo(cd); ## Controls +### Label + +A minimal control which allows to manage a classic "text" message and update its later without having to keep track of the message id. + + + +Check the example project [TelegramBotBase.Test/Tests/Controls/LabelForm.cs](TelegramBotBase.Test/Tests/Controls/LabelForm.cs) + ### Progress Bar +Check the example project [TelegramBotBase.Test/Tests/ProgressTest.cs](TelegramBotBase.Test/Tests/ProgressTest.cs) + ### Calendar Picker + +Check the example project [TelegramBotBase.Test/Tests/Controls/CalendarPickerForm.cs](TelegramBotBase.Test/Tests/Controls/CalendarPickerForm.cs) + ### Month Picker +Check the example project [TelegramBotBase.Test/Tests/Controls/MonthPickerForm.cs](TelegramBotBase.Test/Tests/Controls/MonthPickerForm.cs) + ### Tree View @@ -658,30 +674,44 @@ await this.NavigateTo(cd); +Check the example project [TelegramBotBase.Test/Tests/Controls/TreeViewForms.cs](TelegramBotBase.Test/Tests/Controls/TreeViewForms.cs) + ### Toggle Button +Check the example project [TelegramBotBase.Test/Tests/Controls/ToggleButtonForm.cs](TelegramBotBase.Test/Tests/Controls/ToggleButtonForm.cs) + ### Button Grid +Check the example project [TelegramBotBase.Test/Tests/Controls/ButtonGridForm.cs](TelegramBotBase.Test/Tests/Controls/ButtonGridForm.cs) + #### Paging & Searching +Check the example project [TelegramBotBase.Test/Tests/Controls/ButtonGridPadingForm.cs](TelegramBotBase.Test/Tests/Controls/ButtonGridPagingForm.cs) + ### Tagged Button Grid +Check the example project [TelegramBotBase.Test/Tests/Controls/ButtonGridTagForm.cs](TelegramBotBase.Test/Tests/Controls/ButtonGridTagForm.cs) + ### Checked Button List +Check the example project [TelegramBotBase.Test/Tests/Controls/CheckedButtonListForm.cs](TelegramBotBase.Test/Tests/Controls/CheckedButtonListForm.cs) + ### Multi Toggle Button +Check the example project [TelegramBotBase.Test/Tests/Controls/MultiToggleButtonForm.cs](TelegramBotBase.Test/Tests/Controls/MultiToggleButtonForm.cs) + ## Groups For groups, there are multiple different tools which help to work with and allows bot also to manage @@ -1046,4 +1076,8 @@ method of BotBase. Having already a web application and want to add a TelegramBot side-by-side with it running ? Here is an example how you could do it. -- [Examples/BotAndWebApplication](Examples/BotAndWebApplication) \ No newline at end of file +- [Examples/BotAndWebApplication](Examples/BotAndWebApplication) + +Want to use Inline- and ReplyMarkup at the same time ? Here is an example how you can do that: + +- [Examples/InlineAndReplyCombination](Examples/InlineAndReplyCombination) \ No newline at end of file diff --git a/TelegramBotBase.Extensions.Images/ImageExtensions.cs b/TelegramBotBase.Extensions.Images/ImageExtensions.cs index 7ed5dc0..e394c74 100644 --- a/TelegramBotBase.Extensions.Images/ImageExtensions.cs +++ b/TelegramBotBase.Extensions.Images/ImageExtensions.cs @@ -3,7 +3,6 @@ using System.Drawing.Imaging; using System.IO; using System.Threading.Tasks; using Telegram.Bot.Types; -using Telegram.Bot.Types.InputFiles; using TelegramBotBase.Form; using TelegramBotBase.Sessions; @@ -34,7 +33,7 @@ namespace TelegramBotBase.Extensions.Images { using (var fileStream = ToStream(image, ImageFormat.Png)) { - var fts = new InputOnlineFile(fileStream, name); + var fts = InputFile.FromStream(fileStream, name); return await session.SendPhoto(fts, caption, buttons, replyTo, disableNotification); } @@ -55,7 +54,7 @@ namespace TelegramBotBase.Extensions.Images { using (var fileStream = ToStream(image, ImageFormat.Png)) { - var fts = new InputOnlineFile(fileStream, name); + var fts = InputFile.FromStream(fileStream, name); return await session.SendPhoto(fts, caption, buttons, replyTo, disableNotification); } diff --git a/TelegramBotBase.Extensions.Images/TelegramBotBase.Extensions.Images.csproj b/TelegramBotBase.Extensions.Images/TelegramBotBase.Extensions.Images.csproj index 942981b..6862517 100644 --- a/TelegramBotBase.Extensions.Images/TelegramBotBase.Extensions.Images.csproj +++ b/TelegramBotBase.Extensions.Images/TelegramBotBase.Extensions.Images.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net5;netcoreapp3.1;net6 + netstandard2.0;netcoreapp3.1;net6 https://github.com/MajMcCloud/TelegramBotFramework https://github.com/MajMcCloud/TelegramBotFramework MIT @@ -14,11 +14,15 @@ 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 4782e67..70f9f3b 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 @@ -1,7 +1,7 @@  - netstandard2.0;net5;netcoreapp3.1;net6 + netstandard2.0;netcoreapp3.1;net6 True https://github.com/MajMcCloud/TelegramBotFramework https://github.com/MajMcCloud/TelegramBotFramework diff --git a/TelegramBotBase.Test/Tests/ArrayPromptDialogTest.cs b/TelegramBotBase.Test/Tests/ArrayPromptDialogTest.cs new file mode 100644 index 0000000..d5c3f9f --- /dev/null +++ b/TelegramBotBase.Test/Tests/ArrayPromptDialogTest.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TelegramBotBase.Form; + +namespace TelegramBotBase.Example.Tests +{ + public class ArrayPromptDialogTest : ArrayPromptDialog + { + + public ArrayPromptDialogTest() : base("Choose an option", new[] { new ButtonBase("Option 1", "option1"), new ButtonBase("Option 2", "option2") }) + { + + this.ButtonClicked += ArrayPromptDialogTest_ButtonClicked; + } + + private void ArrayPromptDialogTest_ButtonClicked(object sender, Args.ButtonClickedEventArgs e) + { + + Console.WriteLine(e.Button.Text + " has been clicked"); + + + } + } +} diff --git a/TelegramBotBase.Test/Tests/Controls/LabelForm.cs b/TelegramBotBase.Test/Tests/Controls/LabelForm.cs new file mode 100644 index 0000000..577a4cd --- /dev/null +++ b/TelegramBotBase.Test/Tests/Controls/LabelForm.cs @@ -0,0 +1,84 @@ +using System; +using System.Threading.Tasks; +using TelegramBotBase.Args; +using TelegramBotBase.Controls.Hybrid; +using TelegramBotBase.Controls.Inline; +using TelegramBotBase.Enums; +using TelegramBotBase.Form; + +namespace TelegramBotBase.Example.Tests.Controls; + +public class LabelForm : AutoCleanForm +{ + + TelegramBotBase.Controls.Inline.LabelControl _label; + + ButtonGrid _buttonGrid; + + String[] string_options = new string[] { "My test label", "Here is a different text", "*And this looks completely different.*", "Aha! another one.", "_Gotcha!_" }; + + public LabelForm() + { + DeleteMode = EDeleteMode.OnLeavingForm; + + Init += LabelForm_Init; + } + + private Task LabelForm_Init(object sender, InitEventArgs e) + { + //The "label" control + _label = new LabelControl("My test label"); + + AddControl(_label); + + //Optional...just for experimentation... + var bf = new ButtonForm(); + + bf.AddButtonRow("Toggle text", "toggle"); + bf.AddButtonRow("Open menu", "menu"); + + _buttonGrid = new ButtonGrid(bf); + _buttonGrid.KeyboardType = EKeyboardType.ReplyKeyboard; + _buttonGrid.Title = "Choose your options:"; + _buttonGrid.ButtonClicked += _buttonGrid_ButtonClicked; + + AddControl(_buttonGrid); + + return Task.CompletedTask; + } + + private async Task _buttonGrid_ButtonClicked(object sender, ButtonClickedEventArgs e) + { + switch (e.Button.Value ?? "") + { + case "menu": + + var mn = new Menu(); + + await NavigateTo(mn); + + break; + + case "toggle": + + + //Pick random string from array + var r = new Random((int)DateTime.UtcNow.Ticks); + + String random_string; + do + { + random_string = string_options[r.Next(0, string_options.Length)]; + if (random_string == null) + continue; + + } while (random_string == _label.Text); + + + _label.Text = random_string; + + break; + + } + } +} \ No newline at end of file diff --git a/TelegramBotBase.Test/Tests/Controls/MultiToggleButtons.cs b/TelegramBotBase.Test/Tests/Controls/MultiToggleButtonForm.cs similarity index 94% rename from TelegramBotBase.Test/Tests/Controls/MultiToggleButtons.cs rename to TelegramBotBase.Test/Tests/Controls/MultiToggleButtonForm.cs index fb46af5..0d2a645 100644 --- a/TelegramBotBase.Test/Tests/Controls/MultiToggleButtons.cs +++ b/TelegramBotBase.Test/Tests/Controls/MultiToggleButtonForm.cs @@ -9,9 +9,9 @@ using TelegramBotBase.Form; namespace TelegramBotBase.Example.Tests.Controls; -public class MultiToggleButtons : AutoCleanForm +public class MultiToggleButtonForm : AutoCleanForm { - public MultiToggleButtons() + public MultiToggleButtonForm() { DeleteMode = EDeleteMode.OnLeavingForm; diff --git a/TelegramBotBase.Test/Tests/Controls/ToggleButtons.cs b/TelegramBotBase.Test/Tests/Controls/ToggleButtonForm.cs similarity index 93% rename from TelegramBotBase.Test/Tests/Controls/ToggleButtons.cs rename to TelegramBotBase.Test/Tests/Controls/ToggleButtonForm.cs index 77c2e96..6efa25c 100644 --- a/TelegramBotBase.Test/Tests/Controls/ToggleButtons.cs +++ b/TelegramBotBase.Test/Tests/Controls/ToggleButtonForm.cs @@ -7,9 +7,9 @@ using TelegramBotBase.Form; namespace TelegramBotBase.Example.Tests.Controls; -public class ToggleButtons : AutoCleanForm +public class ToggleButtonForm : AutoCleanForm { - public ToggleButtons() + public ToggleButtonForm() { DeleteMode = EDeleteMode.OnLeavingForm; diff --git a/TelegramBotBase.Test/Tests/DataForm.cs b/TelegramBotBase.Test/Tests/DataForm.cs index 49554d0..aa77bc1 100644 --- a/TelegramBotBase.Test/Tests/DataForm.cs +++ b/TelegramBotBase.Test/Tests/DataForm.cs @@ -1,8 +1,8 @@ using System.Linq; using System.Threading.Tasks; using Telegram.Bot; +using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; using Telegram.Bot.Types.ReplyMarkups; using TelegramBotBase.Base; using TelegramBotBase.Form; @@ -14,7 +14,7 @@ public class DataForm : AutoCleanForm public override async Task SentData(DataResult data) { var tmp = ""; - InputOnlineFile file; + InputFile file; switch (data.Type) { @@ -31,7 +31,7 @@ public class DataForm : AutoCleanForm case MessageType.Document: - file = new InputOnlineFile(data.Document.FileId); + file = InputFile.FromString(data.Document.FileId); await Device.SendDocument(file, "Your uploaded document"); @@ -40,7 +40,7 @@ public class DataForm : AutoCleanForm case MessageType.Video: - file = new InputOnlineFile(data.Document.FileId); + file = InputFile.FromString(data.Document.FileId); await Device.SendDocument(file, "Your uploaded video"); @@ -48,7 +48,7 @@ public class DataForm : AutoCleanForm case MessageType.Audio: - file = new InputOnlineFile(data.Document.FileId); + file = InputFile.FromString(data.Document.FileId); await Device.SendDocument(file, "Your uploaded audio"); @@ -65,7 +65,7 @@ public class DataForm : AutoCleanForm case MessageType.Photo: - var photo = new InputOnlineFile(data.Photos.Last().FileId); + var photo = InputFile.FromString(data.Photos.Last().FileId); await Device.Send("Your image: ", replyTo: data.MessageId); await Client.TelegramClient.SendPhotoAsync(Device.DeviceId, photo); diff --git a/TelegramBotBase.Test/Tests/Groups/LinkReplaceTest.cs b/TelegramBotBase.Test/Tests/Groups/LinkReplaceTest.cs index 69bc1ad..9d8e6c5 100644 --- a/TelegramBotBase.Test/Tests/Groups/LinkReplaceTest.cs +++ b/TelegramBotBase.Test/Tests/Groups/LinkReplaceTest.cs @@ -102,7 +102,13 @@ public class LinkReplaceTest : GroupForm CanChangeInfo = false, CanInviteUsers = false, CanPinMessages = false, - CanSendMediaMessages = false, + CanManageTopics = false, + CanSendAudios = false, + CanSendVideos = false, + CanSendDocuments = false, + CanSendPhotos = false, + CanSendVideoNotes = false, + CanSendVoiceNotes = false, CanSendMessages = false, CanSendOtherMessages = false, CanSendPolls = false @@ -128,7 +134,7 @@ public class LinkReplaceTest : GroupForm } else { - await e.Device.RestrictUser(from, cp, DateTime.UtcNow.AddSeconds(30)); + await e.Device.RestrictUser(from, cp, null, DateTime.UtcNow.AddSeconds(30)); await e.Device.Send(e.Message.From.FirstName + " " + e.Message.From.LastName + " has been blocked for 30 seconds"); diff --git a/TelegramBotBase.Test/Tests/Menu.cs b/TelegramBotBase.Test/Tests/Menu.cs index 740cfd7..6c74cf8 100644 --- a/TelegramBotBase.Test/Tests/Menu.cs +++ b/TelegramBotBase.Test/Tests/Menu.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; using Telegram.Bot.Types.Enums; using TelegramBotBase.Base; using TelegramBotBase.Enums; @@ -127,7 +128,7 @@ public class Menu : AutoCleanForm case "togglebuttons": - var tb = new ToggleButtons(); + var tb = new ToggleButtonForm(); await NavigateTo(tb); @@ -135,7 +136,7 @@ public class Menu : AutoCleanForm case "multitogglebuttons": - var mtb = new MultiToggleButtons(); + var mtb = new MultiToggleButtonForm(); await NavigateTo(mtb); @@ -207,6 +208,22 @@ public class Menu : AutoCleanForm break; + case "label": + + var lf = new LabelForm(); + + await NavigateTo(lf); + + break; + + case "arraypromptdialog": + + var apt = new ArrayPromptDialogTest(); + + await NavigateTo(apt); + + break; + default: message.Handled = false; @@ -260,6 +277,11 @@ public class Menu : AutoCleanForm btn.AddButtonRow(new ButtonBase("#19 Notifications", new CallbackData("a", "notifications").Serialize())); + + btn.AddButtonRow(new ButtonBase("#20 Label", new CallbackData("a", "label").Serialize())); + + btn.AddButtonRow(new ButtonBase("#21 ArrayPromptDialogTest", new CallbackData("a", "arraypromptdialog").Serialize())); + await Device.Send("Choose your test:", btn); } } diff --git a/TelegramBotBase.Test/packages.config b/TelegramBotBase.Test/packages.config deleted file mode 100644 index 5f28270..0000000 --- a/TelegramBotBase.Test/packages.config +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/TelegramBotBase/Base/DataResult.cs b/TelegramBotBase/Base/DataResult.cs index 14c7d9b..56ca7ca 100644 --- a/TelegramBotBase/Base/DataResult.cs +++ b/TelegramBotBase/Base/DataResult.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; namespace TelegramBotBase.Base; @@ -17,6 +16,7 @@ public class DataResult : ResultBase public DataResult(UpdateResult update) { UpdateData = update; + Device = update.Device; } //public Telegram.Bot.Args.MessageEventArgs RawMessageData { get; set; } @@ -51,14 +51,14 @@ public class DataResult : ResultBase Photos.FirstOrDefault()?.FileId; - public async Task DownloadDocument() + public async Task DownloadDocument() { var encryptedContent = new MemoryStream(); encryptedContent.SetLength(Document.FileSize.Value); var file = await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(Document.FileId, encryptedContent); - return new InputOnlineFile(encryptedContent, Document.FileName); + return InputFile.FromStream(encryptedContent, Document.FileName); } @@ -112,13 +112,13 @@ public class DataResult : ResultBase return sr.ReadToEnd(); } - public async Task DownloadVideo() + public async Task DownloadVideo() { var encryptedContent = new MemoryStream(); encryptedContent.SetLength(Video.FileSize.Value); var file = await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(Video.FileId, encryptedContent); - return new InputOnlineFile(encryptedContent, ""); + return InputFile.FromStream(encryptedContent, ""); } public async Task DownloadVideo(string path) @@ -130,13 +130,13 @@ public class DataResult : ResultBase fs.Dispose(); } - public async Task DownloadAudio() + public async Task DownloadAudio() { var encryptedContent = new MemoryStream(); encryptedContent.SetLength(Audio.FileSize.Value); var file = await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(Audio.FileId, encryptedContent); - return new InputOnlineFile(encryptedContent, ""); + return InputFile.FromStream(encryptedContent, ""); } public async Task DownloadAudio(string path) @@ -148,14 +148,14 @@ public class DataResult : ResultBase fs.Dispose(); } - public async Task DownloadPhoto(int index) + public async Task DownloadPhoto(int index) { var photo = Photos[index]; var encryptedContent = new MemoryStream(); encryptedContent.SetLength(photo.FileSize.Value); var file = await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(photo.FileId, encryptedContent); - return new InputOnlineFile(encryptedContent, ""); + return InputFile.FromStream(encryptedContent, ""); } public async Task DownloadPhoto(int index, string path) diff --git a/TelegramBotBase/Base/MessageClient.cs b/TelegramBotBase/Base/MessageClient.cs index db7e27b..b5f9b3a 100644 --- a/TelegramBotBase/Base/MessageClient.cs +++ b/TelegramBotBase/Base/MessageClient.cs @@ -7,7 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Telegram.Bot; using Telegram.Bot.Exceptions; -using Telegram.Bot.Extensions.Polling; +using Telegram.Bot.Polling; using Telegram.Bot.Types; namespace TelegramBotBase.Base; diff --git a/TelegramBotBase/Builder/BotBaseBuilder.cs b/TelegramBotBase/Builder/BotBaseBuilder.cs index dc22976..a936b6e 100644 --- a/TelegramBotBase/Builder/BotBaseBuilder.cs +++ b/TelegramBotBase/Builder/BotBaseBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net.Http; using Telegram.Bot; using Telegram.Bot.Types; @@ -314,19 +315,63 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage, return this; } + /// + /// Uses the application runtime path to load and write a states.json file. + /// + /// + public ILanguageSelectionStage UseJSON() + { + var path = Path.Combine(Directory.GetCurrentDirectory(), "states.json"); + _stateMachine = new JsonStateMachine(path); + return this; + } + /// + /// Uses the given path to load and write a states.json file. + /// + /// public ILanguageSelectionStage UseJSON(string path) { _stateMachine = new JsonStateMachine(path); return this; } + /// + /// Uses the application runtime path to load and write a states.json file. + /// + /// + public ILanguageSelectionStage UseSimpleJSON() + { + var path = Path.Combine(Directory.GetCurrentDirectory(), "states.json"); + _stateMachine = new SimpleJsonStateMachine(path); + return this; + } + + /// + /// Uses the given path to load and write a states.json file. + /// + /// public ILanguageSelectionStage UseSimpleJSON(string path) { _stateMachine = new SimpleJsonStateMachine(path); return this; } + /// + /// Uses the application runtime path to load and write a states.xml file. + /// + /// + public ILanguageSelectionStage UseXML() + { + var path = Path.Combine(Directory.GetCurrentDirectory(), "states.xml"); + _stateMachine = new XmlStateMachine(path); + return this; + } + + /// + /// Uses the given path to load and write a states.xml file. + /// + /// public ILanguageSelectionStage UseXML(string path) { _stateMachine = new XmlStateMachine(path); diff --git a/TelegramBotBase/Builder/Interfaces/ISessionSerializationStage.cs b/TelegramBotBase/Builder/Interfaces/ISessionSerializationStage.cs index 5ed022b..2a453e4 100644 --- a/TelegramBotBase/Builder/Interfaces/ISessionSerializationStage.cs +++ b/TelegramBotBase/Builder/Interfaces/ISessionSerializationStage.cs @@ -18,6 +18,13 @@ public interface ISessionSerializationStage /// ILanguageSelectionStage UseSerialization(IStateMachine machine); + /// + /// Using the complex version of .Net JSON, which can serialize all objects. + /// Saves in application directory. + /// + /// + /// + ILanguageSelectionStage UseJSON(); /// /// Using the complex version of .Net JSON, which can serialize all objects. @@ -26,6 +33,13 @@ public interface ISessionSerializationStage /// ILanguageSelectionStage UseJSON(string path); + /// + /// Use the easy version of .Net JSON, which can serialize basic types, but not generics and others. + /// Saves in application directory. + /// + /// + /// + ILanguageSelectionStage UseSimpleJSON(); /// /// Use the easy version of .Net JSON, which can serialize basic types, but not generics and others. @@ -34,6 +48,13 @@ public interface ISessionSerializationStage /// ILanguageSelectionStage UseSimpleJSON(string path); + /// + /// Uses the XML serializer for session serialization. + /// Saves in application directory. + /// + /// + /// + ILanguageSelectionStage UseXML(); /// /// Uses the XML serializer for session serialization. diff --git a/TelegramBotBase/Controls/Inline/Label.cs b/TelegramBotBase/Controls/Inline/Label.cs new file mode 100644 index 0000000..429e505 --- /dev/null +++ b/TelegramBotBase/Controls/Inline/Label.cs @@ -0,0 +1,110 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Threading.Tasks; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using TelegramBotBase.Base; +using TelegramBotBase.Form; +using TelegramBotBase.Localizations; + +namespace TelegramBotBase.Controls.Inline; + +[DebuggerDisplay("{Text}")] +public class Label : ControlBase +{ + private bool _renderNecessary = true; + + private string _text = string.Empty; + + public String Text + { + get + { + return _text; + } + set + { + if (_text == value) + return; + + + _text = value; + _renderNecessary = true; + + } + } + + private ParseMode _parseMode = ParseMode.Markdown; + + public ParseMode ParseMode + { + get + { + return _parseMode; + } + set + { + _parseMode = value; + _renderNecessary = true; + } + } + + + public Label() + { + } + + public Label(string text) + { + _text = text; + } + + public Label(string text, ParseMode parseMode) + { + _text = text; + _parseMode = parseMode; + } + + public int? MessageId { get; set; } + + + + public override async Task Render(MessageResult result) + { + if (!_renderNecessary) + { + return; + } + + Message m; + + //Update ? + if (MessageId != null) + { + m = await Device.Raw(a => a.EditMessageTextAsync(Device.DeviceId, MessageId.Value, Text, _parseMode)); + _renderNecessary = false; + + return; + } + + //New Message + m = await Device.Raw(a => a.SendTextMessageAsync(Device.DeviceId, Text, disableNotification: true, parseMode: _parseMode)); + if (m != null) + { + MessageId = m.MessageId; + } + + _renderNecessary = false; + } + + public override async Task Cleanup() + { + if (this.MessageId == null) + return; + + + await Device.DeleteMessage(MessageId.Value); + } +} \ No newline at end of file diff --git a/TelegramBotBase/Form/ArrayPromptDialog.cs b/TelegramBotBase/Form/ArrayPromptDialog.cs index 7481563..e57aa7b 100644 --- a/TelegramBotBase/Form/ArrayPromptDialog.cs +++ b/TelegramBotBase/Form/ArrayPromptDialog.cs @@ -41,8 +41,6 @@ public class ArrayPromptDialog : FormBase public ButtonBase[][] Buttons { get; set; } - [Obsolete] public Dictionary ButtonForms { get; set; } = new(); - private static object EvButtonClicked { get; } = new(); public override async Task Action(MessageResult message) @@ -75,13 +73,6 @@ public class ArrayPromptDialog : FormBase } OnButtonClicked(new ButtonClickedEventArgs(button) { Tag = Tag }); - - var fb = ButtonForms.ContainsKey(call.Value) ? ButtonForms[call.Value] : null; - - if (fb != null) - { - await NavigateTo(fb); - } } diff --git a/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs b/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs index f1a2d39..0069c1b 100644 --- a/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs +++ b/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs @@ -44,6 +44,7 @@ public class FormBaseMessageLoop : IMessageLoopFactory } mr.Device = session; + ur.Device = session; var activeForm = session.ActiveForm; diff --git a/TelegramBotBase/MessageLoops/FullMessageLoop.cs b/TelegramBotBase/MessageLoops/FullMessageLoop.cs index b7855c6..2c4b1b9 100644 --- a/TelegramBotBase/MessageLoops/FullMessageLoop.cs +++ b/TelegramBotBase/MessageLoops/FullMessageLoop.cs @@ -37,6 +37,7 @@ public class FullMessageLoop : IMessageLoopFactory } mr.Device = session; + ur.Device = session; var activeForm = session.ActiveForm; diff --git a/TelegramBotBase/Properties/AssemblyInfo.cs b/TelegramBotBase/Properties/AssemblyInfo.cs index 7f6a35f..03dc3df 100644 --- a/TelegramBotBase/Properties/AssemblyInfo.cs +++ b/TelegramBotBase/Properties/AssemblyInfo.cs @@ -7,9 +7,9 @@ using System.Runtime.InteropServices; [assembly: AssemblyTitle("TelegramBotBase Framework")] [assembly: AssemblyDescription("This is a context based application framework for the C# TelegramBot library.")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Florian Dahn")] +[assembly: AssemblyCompany("Florian Zevedei")] [assembly: AssemblyProduct("TelegramBotBase Framework")] -[assembly: AssemblyCopyright("Copyright © Florian Dahn 2020")] +[assembly: AssemblyCopyright("Copyright © Florian Zevedei 2023")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // übernehmen, indem Sie "*" eingeben: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.1.0.0")] -[assembly: AssemblyFileVersion("3.1.0.0")] \ No newline at end of file +[assembly: AssemblyVersion("6.0.0.0")] +[assembly: AssemblyFileVersion("6.0.0.0")] \ No newline at end of file diff --git a/TelegramBotBase/Sessions/DeviceSession.cs b/TelegramBotBase/Sessions/DeviceSession.cs index f823c59..50ad65e 100644 --- a/TelegramBotBase/Sessions/DeviceSession.cs +++ b/TelegramBotBase/Sessions/DeviceSession.cs @@ -9,7 +9,6 @@ using Telegram.Bot; using Telegram.Bot.Exceptions; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; using Telegram.Bot.Types.ReplyMarkups; using TelegramBotBase.Args; using TelegramBotBase.Base; @@ -280,7 +279,7 @@ public class DeviceSession : IDeviceSession try { - var t = Api(a => a.SendTextMessageAsync(deviceId, text, parseMode, replyToMessageId: replyTo, + var t = Api(a => a.SendTextMessageAsync(deviceId, text, null, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification)); var o = GetOrigin(new StackTrace()); @@ -339,7 +338,7 @@ public class DeviceSession : IDeviceSession try { - var t = Api(a => a.SendTextMessageAsync(DeviceId, text, parseMode, replyToMessageId: replyTo, + var t = Api(a => a.SendTextMessageAsync(DeviceId, text, null, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification)); var o = GetOrigin(new StackTrace()); @@ -382,7 +381,7 @@ public class DeviceSession : IDeviceSession try { - var t = Api(a => a.SendTextMessageAsync(DeviceId, text, parseMode, replyToMessageId: replyTo, + var t = Api(a => a.SendTextMessageAsync(DeviceId, text, null, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification)); var o = GetOrigin(new StackTrace()); @@ -404,7 +403,7 @@ public class DeviceSession : IDeviceSession /// /// /// - public async Task SendPhoto(InputOnlineFile file, string caption = null, ButtonForm buttons = null, + public async Task SendPhoto(InputFile file, string caption = null, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Markdown) { @@ -417,7 +416,7 @@ public class DeviceSession : IDeviceSession try { - var t = Api(a => a.SendPhotoAsync(DeviceId, file, caption, parseMode, replyToMessageId: replyTo, + var t = Api(a => a.SendPhotoAsync(DeviceId, file, null, caption, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification)); var o = GetOrigin(new StackTrace()); @@ -439,7 +438,7 @@ public class DeviceSession : IDeviceSession /// /// /// - public async Task SendVideo(InputOnlineFile file, string caption = null, ButtonForm buttons = null, + public async Task SendVideo(InputFile file, string caption = null, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Markdown) { @@ -487,7 +486,7 @@ public class DeviceSession : IDeviceSession try { - var t = Api(a => a.SendVideoAsync(DeviceId, new InputOnlineFile(url), parseMode: parseMode, + var t = Api(a => a.SendVideoAsync(DeviceId, InputFile.FromUri(url), parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification)); @@ -525,7 +524,7 @@ public class DeviceSession : IDeviceSession { var ms = new MemoryStream(video); - var fts = new InputOnlineFile(ms, filename); + var fts = InputFile.FromStream(ms, filename); var t = Api(a => a.SendVideoAsync(DeviceId, fts, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification)); @@ -567,7 +566,7 @@ public class DeviceSession : IDeviceSession var filename = Path.GetFileName(filepath); - var fts = new InputOnlineFile(fs, filename); + var fts = InputFile.FromStream(fs, filename); var t = Api(a => a.SendVideoAsync(DeviceId, fts, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification)); @@ -599,7 +598,7 @@ public class DeviceSession : IDeviceSession { var ms = new MemoryStream(document); - var fts = new InputOnlineFile(ms, filename); + var fts = InputFile.FromStream(ms, filename); return await SendDocument(fts, caption, buttons, replyTo, disableNotification); } @@ -641,7 +640,7 @@ public class DeviceSession : IDeviceSession /// /// /// - public async Task SendDocument(InputOnlineFile document, string caption = "", + public async Task SendDocument(InputFile document, string caption = "", ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false) { @@ -653,7 +652,7 @@ public class DeviceSession : IDeviceSession try { - var t = Api(a => a.SendDocumentAsync(DeviceId, document, caption, replyMarkup: markup, + var t = Api(a => a.SendDocumentAsync(DeviceId, document, null, null, caption, replyMarkup: markup, disableNotification: disableNotification, replyToMessageId: replyTo)); var o = GetOrigin(new StackTrace()); @@ -866,11 +865,11 @@ public class DeviceSession : IDeviceSession #region "Users" - public virtual async Task RestrictUser(long userId, ChatPermissions permissions, DateTime until = default) + public virtual async Task RestrictUser(long userId, ChatPermissions permissions, bool? useIndependentGroupPermission = null, DateTime until = default) { try { - await Api(a => a.RestrictChatMemberAsync(DeviceId, userId, permissions, until)); + await Api(a => a.RestrictChatMemberAsync(DeviceId, userId, permissions, useIndependentGroupPermission, until)); } catch { diff --git a/TelegramBotBase/TelegramBotBase.csproj b/TelegramBotBase/TelegramBotBase.csproj index 12c0a79..2e16171 100644 --- a/TelegramBotBase/TelegramBotBase.csproj +++ b/TelegramBotBase/TelegramBotBase.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net5;netcoreapp3.1;net6 + netstandard2.0;netcoreapp3.1;net6 10 false False @@ -57,8 +57,7 @@ - - + diff --git a/TelegramBotBase/TelegramBotBase.nuspec b/TelegramBotBase/TelegramBotBase.nuspec index 7e14769..5dfff90 100644 --- a/TelegramBotBase/TelegramBotBase.nuspec +++ b/TelegramBotBase/TelegramBotBase.nuspec @@ -15,12 +15,12 @@ - + - + diff --git a/TelegramBotFramework.sln b/TelegramBotFramework.sln index 4a5f86b..885b8a0 100644 --- a/TelegramBotFramework.sln +++ b/TelegramBotFramework.sln @@ -28,7 +28,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBotBase.Extensions. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCoreBot", "Examples\EFCoreBot\EFCoreBot.csproj", "{261BED47-0404-4A9A-86FC-047DE42A7D25}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotAndWebApplication", "Examples\BotAndWebApplication\BotAndWebApplication.csproj", "{52EA3201-02E8-46F5-87C4-B4752C8A815C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotAndWebApplication", "Examples\BotAndWebApplication\BotAndWebApplication.csproj", "{52EA3201-02E8-46F5-87C4-B4752C8A815C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InlineAndReplyCombination", "Examples\InlineAndReplyCombination\InlineAndReplyCombination.csproj", "{067E8EBE-F90A-4AFF-A0FF-20578216486E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -72,6 +74,10 @@ Global {52EA3201-02E8-46F5-87C4-B4752C8A815C}.Debug|Any CPU.Build.0 = Debug|Any CPU {52EA3201-02E8-46F5-87C4-B4752C8A815C}.Release|Any CPU.ActiveCfg = Release|Any CPU {52EA3201-02E8-46F5-87C4-B4752C8A815C}.Release|Any CPU.Build.0 = Release|Any CPU + {067E8EBE-F90A-4AFF-A0FF-20578216486E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {067E8EBE-F90A-4AFF-A0FF-20578216486E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {067E8EBE-F90A-4AFF-A0FF-20578216486E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {067E8EBE-F90A-4AFF-A0FF-20578216486E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -84,6 +90,7 @@ Global {889B170E-32E9-4F26-BB04-8D06EA367857} = {E3193182-6FDA-4FA3-AD26-A487291E7681} {261BED47-0404-4A9A-86FC-047DE42A7D25} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5} {52EA3201-02E8-46F5-87C4-B4752C8A815C} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5} + {067E8EBE-F90A-4AFF-A0FF-20578216486E} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {59CB40E1-9FA7-4867-A56F-4F418286F057}