Merge pull request #45 from MajMcCloud/development
Integrate development branch into master
This commit is contained in:
commit
9548be4afc
BIN
.github/images/label.gif
vendored
Normal file
BIN
.github/images/label.gif
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 658 KiB |
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
68
Examples/InlineAndReplyCombination/Forms/StartForm.cs
Normal file
68
Examples/InlineAndReplyCombination/Forms/StartForm.cs
Normal file
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
96
Examples/InlineAndReplyCombination/Forms/Steps/MainForm.cs
Normal file
96
Examples/InlineAndReplyCombination/Forms/Steps/MainForm.cs
Normal file
@ -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<Tuple<String, String>> AllowedInlineInputs;
|
||||
|
||||
static MainForm()
|
||||
{
|
||||
AllowedInlineInputs = new List<Tuple<string, string>>()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Examples/InlineAndReplyCombination/Forms/Steps/SecondForm.cs
Normal file
95
Examples/InlineAndReplyCombination/Forms/Steps/SecondForm.cs
Normal file
@ -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<Tuple<String, String>> AllowedInlineInputs;
|
||||
|
||||
static SecondForm()
|
||||
{
|
||||
AllowedInlineInputs = new List<Tuple<string, string>>()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
Examples/InlineAndReplyCombination/Forms/Steps/Summary.cs
Normal file
84
Examples/InlineAndReplyCombination/Forms/Steps/Summary.cs
Normal file
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Examples/InlineAndReplyCombination/Forms/Steps/ThirdForm.cs
Normal file
95
Examples/InlineAndReplyCombination/Forms/Steps/ThirdForm.cs
Normal file
@ -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<Tuple<String, String>> AllowedInlineInputs;
|
||||
|
||||
static ThirdForm()
|
||||
{
|
||||
AllowedInlineInputs = new List<Tuple<string, string>>()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\TelegramBotBase\TelegramBotBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
20
Examples/InlineAndReplyCombination/Model/UserDetails.cs
Normal file
20
Examples/InlineAndReplyCombination/Model/UserDetails.cs
Normal file
@ -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; }
|
||||
|
||||
}
|
||||
}
|
||||
41
Examples/InlineAndReplyCombination/Program.cs
Normal file
41
Examples/InlineAndReplyCombination/Program.cs
Normal file
@ -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<StartForm>()
|
||||
.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Examples/InlineAndReplyCombination/README.md
Normal file
16
Examples/InlineAndReplyCombination/README.md
Normal file
@ -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.
|
||||
36
README.md
36
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.
|
||||
|
||||
<img src=".github/images/label.gif?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/LabelForm.cs](TelegramBotBase.Test/Tests/Controls/LabelForm.cs)
|
||||
|
||||
### Progress Bar
|
||||
|
||||
<img src=".github/images/progressbar.PNG?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/ProgressTest.cs](TelegramBotBase.Test/Tests/ProgressTest.cs)
|
||||
|
||||
### Calendar Picker
|
||||
|
||||
<img src=".github/images/calendarpicker.PNG?raw=true" />
|
||||
|
||||
<img src=".github/images/calendarpicker.gif?raw=true" />
|
||||
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/CalendarPickerForm.cs](TelegramBotBase.Test/Tests/Controls/CalendarPickerForm.cs)
|
||||
|
||||
### Month Picker
|
||||
|
||||
<img src=".github/images/monthpicker1.PNG?raw=true" />
|
||||
<img src=".github/images/monthpicker2.PNG?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/MonthPickerForm.cs](TelegramBotBase.Test/Tests/Controls/MonthPickerForm.cs)
|
||||
|
||||
### Tree View
|
||||
|
||||
<img src=".github/images/treeview1.PNG?raw=true" />
|
||||
@ -658,30 +674,44 @@ await this.NavigateTo(cd);
|
||||
<img src=".github/images/treeview3.PNG?raw=true" />
|
||||
<img src=".github/images/treeview4.PNG?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/TreeViewForms.cs](TelegramBotBase.Test/Tests/Controls/TreeViewForms.cs)
|
||||
|
||||
### Toggle Button
|
||||
|
||||
<img src=".github/images/togglebutton.gif?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/ToggleButtonForm.cs](TelegramBotBase.Test/Tests/Controls/ToggleButtonForm.cs)
|
||||
|
||||
### Button Grid
|
||||
|
||||
<img src=".github/images/buttongrid.gif?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/ButtonGridForm.cs](TelegramBotBase.Test/Tests/Controls/ButtonGridForm.cs)
|
||||
|
||||
#### Paging & Searching
|
||||
|
||||
<img src=".github/images/buttongrid_pagingfilter.gif?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/ButtonGridPadingForm.cs](TelegramBotBase.Test/Tests/Controls/ButtonGridPagingForm.cs)
|
||||
|
||||
### Tagged Button Grid
|
||||
|
||||
<img src=".github/images/taggedbuttongrid.gif?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/ButtonGridTagForm.cs](TelegramBotBase.Test/Tests/Controls/ButtonGridTagForm.cs)
|
||||
|
||||
### Checked Button List
|
||||
|
||||
<img src=".github/images/checkedbuttonlist.gif?raw=true" />
|
||||
|
||||
Check the example project [TelegramBotBase.Test/Tests/Controls/CheckedButtonListForm.cs](TelegramBotBase.Test/Tests/Controls/CheckedButtonListForm.cs)
|
||||
|
||||
### Multi Toggle Button
|
||||
|
||||
<img src=".github/images/multitogglebutton.gif?raw=true" />
|
||||
|
||||
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)
|
||||
- [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)
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net5;netcoreapp3.1;net6</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net6</TargetFrameworks>
|
||||
<RepositoryUrl>https://github.com/MajMcCloud/TelegramBotFramework</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/MajMcCloud/TelegramBotFramework</PackageProjectUrl>
|
||||
<Copyright>MIT</Copyright>
|
||||
@ -14,11 +14,15 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Drawing.Common" Version="6.0.0"/>
|
||||
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\TelegramBotBase\TelegramBotBase.csproj"/>
|
||||
<ProjectReference Include="..\TelegramBotBase\TelegramBotBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net5;netcoreapp3.1;net6</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net6</TargetFrameworks>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<RepositoryUrl>https://github.com/MajMcCloud/TelegramBotFramework</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/MajMcCloud/TelegramBotFramework</PackageProjectUrl>
|
||||
|
||||
27
TelegramBotBase.Test/Tests/ArrayPromptDialogTest.cs
Normal file
27
TelegramBotBase.Test/Tests/ArrayPromptDialogTest.cs
Normal file
@ -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");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
84
TelegramBotBase.Test/Tests/Controls/LabelForm.cs
Normal file
84
TelegramBotBase.Test/Tests/Controls/LabelForm.cs
Normal file
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1 +0,0 @@
|
||||
|
||||
@ -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<InputOnlineFile> DownloadDocument()
|
||||
public async Task<InputFileStream> 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<InputOnlineFile> DownloadVideo()
|
||||
public async Task<InputFileStream> 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<InputOnlineFile> DownloadAudio()
|
||||
public async Task<InputFileStream> 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<InputOnlineFile> DownloadPhoto(int index)
|
||||
public async Task<InputFileStream> 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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses the application runtime path to load and write a states.json file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ILanguageSelectionStage UseJSON()
|
||||
{
|
||||
var path = Path.Combine(Directory.GetCurrentDirectory(), "states.json");
|
||||
_stateMachine = new JsonStateMachine(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses the given path to load and write a states.json file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ILanguageSelectionStage UseJSON(string path)
|
||||
{
|
||||
_stateMachine = new JsonStateMachine(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses the application runtime path to load and write a states.json file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ILanguageSelectionStage UseSimpleJSON()
|
||||
{
|
||||
var path = Path.Combine(Directory.GetCurrentDirectory(), "states.json");
|
||||
_stateMachine = new SimpleJsonStateMachine(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses the given path to load and write a states.json file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ILanguageSelectionStage UseSimpleJSON(string path)
|
||||
{
|
||||
_stateMachine = new SimpleJsonStateMachine(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses the application runtime path to load and write a states.xml file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ILanguageSelectionStage UseXML()
|
||||
{
|
||||
var path = Path.Combine(Directory.GetCurrentDirectory(), "states.xml");
|
||||
_stateMachine = new XmlStateMachine(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses the given path to load and write a states.xml file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ILanguageSelectionStage UseXML(string path)
|
||||
{
|
||||
_stateMachine = new XmlStateMachine(path);
|
||||
|
||||
@ -18,6 +18,13 @@ public interface ISessionSerializationStage
|
||||
/// <returns></returns>
|
||||
ILanguageSelectionStage UseSerialization(IStateMachine machine);
|
||||
|
||||
/// <summary>
|
||||
/// Using the complex version of .Net JSON, which can serialize all objects.
|
||||
/// Saves in application directory.
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
ILanguageSelectionStage UseJSON();
|
||||
|
||||
/// <summary>
|
||||
/// Using the complex version of .Net JSON, which can serialize all objects.
|
||||
@ -26,6 +33,13 @@ public interface ISessionSerializationStage
|
||||
/// <returns></returns>
|
||||
ILanguageSelectionStage UseJSON(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Use the easy version of .Net JSON, which can serialize basic types, but not generics and others.
|
||||
/// Saves in application directory.
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
ILanguageSelectionStage UseSimpleJSON();
|
||||
|
||||
/// <summary>
|
||||
/// Use the easy version of .Net JSON, which can serialize basic types, but not generics and others.
|
||||
@ -34,6 +48,13 @@ public interface ISessionSerializationStage
|
||||
/// <returns></returns>
|
||||
ILanguageSelectionStage UseSimpleJSON(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Uses the XML serializer for session serialization.
|
||||
/// Saves in application directory.
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
ILanguageSelectionStage UseXML();
|
||||
|
||||
/// <summary>
|
||||
/// Uses the XML serializer for session serialization.
|
||||
|
||||
110
TelegramBotBase/Controls/Inline/Label.cs
Normal file
110
TelegramBotBase/Controls/Inline/Label.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
@ -41,8 +41,6 @@ public class ArrayPromptDialog : FormBase
|
||||
|
||||
public ButtonBase[][] Buttons { get; set; }
|
||||
|
||||
[Obsolete] public Dictionary<string, FormBase> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ public class FormBaseMessageLoop : IMessageLoopFactory
|
||||
}
|
||||
|
||||
mr.Device = session;
|
||||
ur.Device = session;
|
||||
|
||||
var activeForm = session.ActiveForm;
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ public class FullMessageLoop : IMessageLoopFactory
|
||||
}
|
||||
|
||||
mr.Device = session;
|
||||
ur.Device = session;
|
||||
|
||||
var activeForm = session.ActiveForm;
|
||||
|
||||
|
||||
@ -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")]
|
||||
[assembly: AssemblyVersion("6.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("6.0.0.0")]
|
||||
@ -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
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> SendPhoto(InputOnlineFile file, string caption = null, ButtonForm buttons = null,
|
||||
public async Task<Message> 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
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> SendVideo(InputOnlineFile file, string caption = null, ButtonForm buttons = null,
|
||||
public async Task<Message> 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
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> SendDocument(InputOnlineFile document, string caption = "",
|
||||
public async Task<Message> 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
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net5;netcoreapp3.1;net6</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net6</TargetFrameworks>
|
||||
<LangVersion>10</LangVersion>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
|
||||
@ -57,8 +57,7 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Telegram.Bot" Version="18.0.0" />
|
||||
<PackageReference Include="Telegram.Bot.Extensions.Polling" Version="1.0.2" />
|
||||
<PackageReference Include="Telegram.Bot" Version="19.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -15,12 +15,12 @@
|
||||
<group targetFramework=".NETFramework4.6.1">
|
||||
<dependency id="Newtonsoft.Json" version="13.0.1" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Drawing.Common" version="4.6.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Telegram.Bot" version="15.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Telegram.Bot" version="19.0.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
<group targetFramework=".NETStandard2.0">
|
||||
<dependency id="Newtonsoft.Json" version="13.0.1" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Drawing.Common" version="4.6.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Telegram.Bot" version="15.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Telegram.Bot" version="19.0.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
|
||||
@ -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}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user