Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6d22cdd82 | ||
|
|
ee4a3d765c | ||
|
|
703c99eb8d | ||
|
|
138fee9772 | ||
|
|
d60399514f | ||
|
|
ae0fa3b0e3 | ||
|
|
6a2ac7a309 | ||
|
|
1a76b2b3f8 | ||
|
|
5893108bd3 | ||
|
|
d668f57711 | ||
|
|
56c7754408 | ||
|
|
805ffb9ec7 | ||
|
|
aeddd82ea9 | ||
|
|
1ec14ce680 | ||
|
|
3a309baeae | ||
|
|
e02af0fc76 | ||
|
|
530e01f971 | ||
|
|
dcf3cf804f | ||
|
|
a42d3934b5 | ||
|
|
2126b45fed | ||
|
|
b6b9d5b6b1 | ||
|
|
eed5f012dc | ||
|
|
de4cc138ae | ||
|
|
e4da70d37d | ||
|
|
cb4a797b12 | ||
|
|
94d153e141 | ||
|
|
e13cb6d4ef | ||
|
|
c0e285d39e | ||
|
|
8338c5c066 | ||
|
|
52c01b3dfd | ||
|
|
fe1aafc9a5 | ||
|
|
022eee4b57 | ||
|
|
ea971979e2 | ||
|
|
9585a231bd | ||
|
|
c07aca96a4 | ||
|
|
01de9ec932 | ||
|
|
94fe263676 | ||
|
|
4f1eae543d | ||
|
|
1491fc1795 | ||
|
|
b2db44fe4c | ||
|
|
3a78a98b9e | ||
|
|
b14fa2dc87 | ||
|
|
5cd54fc746 | ||
|
|
fb68da6ab1 | ||
|
|
2f7ded8ce5 | ||
|
|
906177a5f9 | ||
|
|
873c91a165 | ||
|
|
46c1acbf99 | ||
|
|
acd06a6948 | ||
|
|
a97305fa35 | ||
|
|
16baef0c45 | ||
|
|
211bc55aff | ||
|
|
19f3c9c195 | ||
|
|
c6666f72bc | ||
|
|
bf7f6f851a | ||
|
|
816bf4cbbe | ||
|
|
da80af86e3 | ||
|
|
929db3ae88 | ||
|
|
582f005b35 | ||
|
|
bbf90deccc | ||
|
|
1d8b367bea |
@@ -1,26 +1,41 @@
|
||||
|
||||
|
||||
# .Net Telegram Bot Framework - Context based addon
|
||||
|
||||
[](https://www.nuget.org/packages/TelegramBotBase/)
|
||||
[](https://t.me/tgbotbase)
|
||||
[](https://www.t.me/tgbotbase)
|
||||
|
||||
|
||||
[](https://raw.githubusercontent.com/MajMcCloud/TelegramBotFramework/master/LICENCE.md)
|
||||
[](https://www.nuget.org/packages/TelegramBotBase)
|
||||
|
||||
Test the Testproject: [@TGBaseBot](https://www.t.me/TGBaseBot)
|
||||
|
||||
Join the Telegram Group: [https://www.t.me/tgbotbase](https://www.t.me/tgbotbase)
|
||||
|
||||
Download a release: [Releases](https://github.com/MajMcCloud/TelegramBotFramework/releases)
|
||||
|
||||
---
|
||||
|
||||
Donations
|
||||
|
||||
Bitcoin: 1NqyGWmZg8HLp9qQELbf6bChEoba3mxaFc
|
||||
|
||||
ETH: 0x795B70CFC27C69603ce115F2b450cbAC5a5460D0
|
||||
|
||||
Litecoin: LM5iCN6Nz22wAi8LSFnKgdGGWEtxWfJZXv
|
||||
|
||||
DASH: Xb2qyVefvbKTXusHoxZ4Soja2S6R4vLsSr
|
||||
|
||||
Paypal: https://paypal.me/majmccloud
|
||||
|
||||
|
||||
Hey guys,
|
||||
|
||||
here we are. After some time and thoughts i give my TelegramBot framework to public.
|
||||
It is based on C#.
|
||||
|
||||
It is a module which is based on the original [TelegramBotLibrary](https://github.com/TelegramBots/Telegram.Bot) you will find in nuget.
|
||||
|
||||
It gives you features which will look/feel like WinForms or have a good way to create apps with actions and forms.
|
||||
Thanks !
|
||||
|
||||
---
|
||||
|
||||
## Index
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [How to Start](#how-to-start)
|
||||
- [Message Handling](#message-handling)
|
||||
* [Example #0 - System Calls](#add-some-system-calls-example-0---system-calls)
|
||||
@@ -33,6 +48,37 @@ It gives you features which will look/feel like WinForms or have a good way to c
|
||||
|
||||
* [Example #4 - Registration Formular](#registration-example-example-4---registration-form-test)
|
||||
|
||||
- [Special Forms](#forms)
|
||||
|
||||
* [AlertDialog](#alert-dialog)
|
||||
|
||||
* [AutoCleanForm](#autocleanform)
|
||||
|
||||
* [PromptDialog](#prompt-dialog)
|
||||
|
||||
- [Controls](#controls)
|
||||
* [ProgressBar](#progress-bar)
|
||||
|
||||
* [CalendarPicker](#calendar-picker)
|
||||
|
||||
* [MonthPicker](#month-picker)
|
||||
|
||||
* [TreeView](#tree-view)
|
||||
|
||||
* [ToggleButton](#toggle-button)
|
||||
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
Hey guys,
|
||||
|
||||
here we are. After some time and thoughts i give my TelegramBot framework to public.
|
||||
It is based on C#.
|
||||
|
||||
It is a module which is based on the original [TelegramBotLibrary](https://github.com/TelegramBots/Telegram.Bot) you will find in nuget.
|
||||
|
||||
It gives you features which will look/feel like WinForms or have a good way to create apps with actions and forms.
|
||||
|
||||
---
|
||||
|
||||
@@ -41,7 +87,7 @@ It gives you features which will look/feel like WinForms or have a good way to c
|
||||
Within your empty App your need to put some initial lines including your APIKey to get things started.
|
||||
The "BotBase" Class will manage a lot of things for you, like system calls, action events and so on.
|
||||
"StartForm" is your first Formular which every user will get internally redirected to, like a start page, you could redirect from there later in code, so users won't recognize it.
|
||||
It needs to be a subclass of "FormBase" you will find in Namespace TelegramBotBase.Form.
|
||||
It needs to be a subclass of "FormBase" you will find in Namespace TelegramBotBase.Base
|
||||
|
||||
|
||||
```
|
||||
@@ -68,36 +114,46 @@ public class StartForm : FormBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Gets invoked during Navigation to this form
|
||||
public override async Task Init(params object[] param)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Gets invoked if the form gets opened (with Form.NavigateTo(NewForm))
|
||||
public override async Task Opened()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Gets invoked if the form gets leaved
|
||||
public override async Task Closed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Gets invoked on every Message/Action/Data in this context
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
await this.Device.Send("Hello world!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Gets invoked on Button clicks
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Gets invoked on Data uploades by the user (of type Photo, Audio, Video, Contact, Location, Document)
|
||||
public override async Task SentData(DataResult data)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Gets invoked on every Message/Action/Data to render Design or Response
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
|
||||
@@ -132,7 +188,7 @@ Inside of the BotFather you are able to add "Commands" to your TelegramBot. The
|
||||
I'm calling them Systemcalls. Before start (and later for sure) you could add them to your BotBase. Every time a message comes in they will get checked if they are one of them.
|
||||
If so, a special event Handler will get raised where you are easier able to manage the action behind.
|
||||
|
||||
Below we have 3 options.
|
||||
Below we have 4 options.
|
||||
|
||||
/start - opens the Startformular
|
||||
|
||||
@@ -145,46 +201,46 @@ Below we have 3 options.
|
||||
|
||||
|
||||
```
|
||||
BotBase<Start> bb = new BotBase<Start>("{YOUR API KEY}");
|
||||
BotBase<Start> bb = new BotBase<Start>("{YOUR API KEY}");
|
||||
|
||||
bb.SystemCalls.Add("/start");
|
||||
bb.SystemCalls.Add("/form1");
|
||||
bb.SystemCalls.Add("/form2");
|
||||
bb.SystemCalls.Add("/start");
|
||||
bb.SystemCalls.Add("/form1");
|
||||
bb.SystemCalls.Add("/form2");
|
||||
|
||||
bb.SystemCalls.Add("/params");
|
||||
bb.SystemCalls.Add("/params");
|
||||
|
||||
bb.SystemCall += async (s, en) =>
|
||||
{
|
||||
switch (en.Command)
|
||||
{
|
||||
case "/form1":
|
||||
bb.SystemCall += async (s, en) =>
|
||||
{
|
||||
switch (en.Command)
|
||||
{
|
||||
case "/form1":
|
||||
|
||||
var form1 = new TestForm();
|
||||
var form1 = new TestForm();
|
||||
|
||||
await en.Device.ActiveForm.NavigateTo(form1);
|
||||
await en.Device.ActiveForm.NavigateTo(form1);
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case "/form2":
|
||||
case "/form2":
|
||||
|
||||
var form2 = new TestForm2();
|
||||
var form2 = new TestForm2();
|
||||
|
||||
await en.Device.ActiveForm.NavigateTo(form2);
|
||||
await en.Device.ActiveForm.NavigateTo(form2);
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case "/params":
|
||||
case "/params":
|
||||
|
||||
String m = en.Parameters.DefaultIfEmpty("").Aggregate((a, b) => a + " and " + b);
|
||||
String m = en.Parameters.DefaultIfEmpty("").Aggregate((a, b) => a + " and " + b);
|
||||
|
||||
await en.Device.Send("Your parameters are " + m, replyTo: en.Device.LastMessage);
|
||||
await en.Device.Send("Your parameters are " + m, replyTo: en.Device.LastMessage);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
bb.Start();
|
||||
bb.Start();
|
||||
|
||||
```
|
||||
|
||||
@@ -193,50 +249,53 @@ On every input the user is sending back to the bot the Action event gets raised.
|
||||
|
||||
### Lets start with text messages (Example #1 - Simple Test)
|
||||
|
||||
|
||||
<img src="images/example1.PNG" />
|
||||
|
||||
```
|
||||
public class SimpleForm : FormBase
|
||||
public class SimpleForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public override async Task Opened()
|
||||
public SimpleForm()
|
||||
{
|
||||
await this.Device.Send("Hello world!");
|
||||
this.DeleteSide = eSide.Both;
|
||||
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
{
|
||||
await this.Device.Send("Hello world! (send 'back' to get back to Start)\r\nOr\r\nhi, hello, maybe, bye and ciao");
|
||||
}
|
||||
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
//message.MessageText will work also, cause it is a string you could manage a lot different scenerios here
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
//message.MessageText will work also, cause it is a string you could manage a lot different scenerios here
|
||||
|
||||
var messageId = message.MessageId;
|
||||
var messageId = message.MessageId;
|
||||
|
||||
switch (message.Command)
|
||||
{
|
||||
case "hello":
|
||||
case "hi":
|
||||
switch (message.Command)
|
||||
{
|
||||
case "hello":
|
||||
case "hi":
|
||||
|
||||
//Send him a simple message
|
||||
await this.Device.Send("Hello you there !");
|
||||
break;
|
||||
//Send him a simple message
|
||||
await this.Device.Send("Hello you there !");
|
||||
break;
|
||||
|
||||
case "maybe":
|
||||
case "maybe":
|
||||
|
||||
//Send him a simple message and reply to the one of himself
|
||||
await this.Device.Send("Maybe what?", replyTo: messageId);
|
||||
//Send him a simple message and reply to the one of himself
|
||||
await this.Device.Send("Maybe what?", replyTo: messageId);
|
||||
|
||||
break;
|
||||
|
||||
case "bye":
|
||||
case "ciao":
|
||||
|
||||
//Send him a simple message
|
||||
await this.Device.Send("Ok, take care !");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "bye":
|
||||
case "ciao":
|
||||
|
||||
//Send him a simple message
|
||||
await this.Device.Send("Ok, take care !");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@@ -245,6 +304,7 @@ public class SimpleForm : FormBase
|
||||
|
||||
I using a different base class (AutoCleanForm) I created for a better "feeling" inside the bot which will delete "old" messages from this form. You have some settings within this class to manage when messages should be getting deleted.
|
||||
|
||||
<img src="images/example2.PNG" />
|
||||
|
||||
```
|
||||
public class ButtonTestForm : AutoCleanForm
|
||||
@@ -322,6 +382,8 @@ public class ButtonTestForm : AutoCleanForm
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Button 3", new CallbackData("a", "button3").Serialize()), new ButtonBase("Button 4", new CallbackData("a", "button4").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Google.com", "google", "https://www.google.com"), new ButtonBase("Telegram", "telegram", "https://telegram.org/"));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||
|
||||
await this.Device.Send("Click a button", btn);
|
||||
@@ -337,133 +399,135 @@ public class ButtonTestForm : AutoCleanForm
|
||||
Sometimes it makes sense to show the end user a type of progressbar or status. For this i tried to make a simple control, which is useful for some situations.
|
||||
Maybe, if i got more ideas, i will add other "controls" in the future.
|
||||
|
||||
<img src="images/example3.PNG" />
|
||||
|
||||
```
|
||||
|
||||
public class ProgressTest : AutoCleanForm
|
||||
public class ProgressTest : AutoCleanForm
|
||||
{
|
||||
|
||||
public ProgressTest()
|
||||
{
|
||||
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
{
|
||||
await this.Device.Send("Welcome to ProgressTest");
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
|
||||
await message.ConfirmAction();
|
||||
|
||||
|
||||
if (call == null)
|
||||
return;
|
||||
|
||||
TelegramBotBase.Controls.ProgressBar Bar = null;
|
||||
|
||||
switch (call.Value)
|
||||
{
|
||||
case "standard":
|
||||
|
||||
public ProgressTest()
|
||||
{
|
||||
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
||||
}
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.standard);
|
||||
Bar.Device = this.Device;
|
||||
|
||||
public override async Task Opened()
|
||||
{
|
||||
await this.Device.Send("Welcome to ProgressTest");
|
||||
}
|
||||
break;
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
case "squares":
|
||||
|
||||
await message.ConfirmAction();
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.squares);
|
||||
Bar.Device = this.Device;
|
||||
|
||||
break;
|
||||
|
||||
if (call == null)
|
||||
return;
|
||||
case "circles":
|
||||
|
||||
TelegramBotBase.Controls.ProgressBar Bar = null;
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.circles);
|
||||
Bar.Device = this.Device;
|
||||
|
||||
switch (call.Value)
|
||||
{
|
||||
case "standard":
|
||||
break;
|
||||
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.standard);
|
||||
Bar.Device = this.Device;
|
||||
case "lines":
|
||||
|
||||
break;
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.lines);
|
||||
Bar.Device = this.Device;
|
||||
|
||||
case "squares":
|
||||
break;
|
||||
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.squares);
|
||||
Bar.Device = this.Device;
|
||||
case "squaredlines":
|
||||
|
||||
break;
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.squaredLines);
|
||||
Bar.Device = this.Device;
|
||||
|
||||
case "circles":
|
||||
break;
|
||||
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.circles);
|
||||
Bar.Device = this.Device;
|
||||
case "start":
|
||||
|
||||
break;
|
||||
var sf = new Start();
|
||||
|
||||
case "lines":
|
||||
await sf.Init();
|
||||
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.lines);
|
||||
Bar.Device = this.Device;
|
||||
await this.NavigateTo(sf);
|
||||
|
||||
break;
|
||||
|
||||
case "squaredlines":
|
||||
|
||||
Bar = new TelegramBotBase.Controls.ProgressBar(0, 100, TelegramBotBase.Controls.ProgressBar.eProgressStyle.squaredLines);
|
||||
Bar.Device = this.Device;
|
||||
|
||||
break;
|
||||
|
||||
case "start":
|
||||
|
||||
var sf = new Start();
|
||||
|
||||
await sf.Init();
|
||||
|
||||
await this.NavigateTo(sf);
|
||||
|
||||
return;
|
||||
|
||||
default:
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Render Progress bar and show some "example" progress
|
||||
await Bar.Render();
|
||||
|
||||
this.Controls.Add(Bar);
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
Bar.Value++;
|
||||
await Bar.Render();
|
||||
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
ButtonForm btn = new ButtonForm();
|
||||
btn.AddButtonRow(new ButtonBase("Standard", new CallbackData("a", "standard").Serialize()), new ButtonBase("Squares", new CallbackData("a", "squares").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Circles", new CallbackData("a", "circles").Serialize()), new ButtonBase("Lines", new CallbackData("a", "lines").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Squared Line", new CallbackData("a", "squaredlines").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Back to start", new CallbackData("a", "start").Serialize()));
|
||||
|
||||
await this.Device.Send("Choose your progress bar:", btn);
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
await b.Cleanup();
|
||||
}
|
||||
|
||||
await this.Device.Send("Ciao from ProgressTest");
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Render Progress bar and show some "example" progress
|
||||
await Bar.Render();
|
||||
|
||||
this.Controls.Add(Bar);
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
Bar.Value++;
|
||||
await Bar.Render();
|
||||
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
ButtonForm btn = new ButtonForm();
|
||||
btn.AddButtonRow(new ButtonBase("Standard", new CallbackData("a", "standard").Serialize()), new ButtonBase("Squares", new CallbackData("a", "squares").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Circles", new CallbackData("a", "circles").Serialize()), new ButtonBase("Lines", new CallbackData("a", "lines").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Squared Line", new CallbackData("a", "squaredlines").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Back to start", new CallbackData("a", "start").Serialize()));
|
||||
|
||||
await this.Device.Send("Choose your progress bar:", btn);
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
await b.Cleanup();
|
||||
}
|
||||
|
||||
await this.Device.Send("Ciao from ProgressTest");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
### Registration Example (Example #4 - Registration Form Test)
|
||||
@@ -471,107 +535,222 @@ Maybe, if i got more ideas, i will add other "controls" in the future.
|
||||
I read it a lot in different Telegram groups that some developers are searching for easy solutions to create context based apps. For this is my project an ideal solution here.
|
||||
To give you an example about the possiblities, i added into the Test project an example for a registration form.
|
||||
|
||||
<img src="images/example4.1.PNG" />
|
||||
|
||||
<img src="images/example4.2.PNG" />
|
||||
|
||||
<img src="images/example4.3.PNG" />
|
||||
|
||||
<img src="images/example4.4.PNG" />
|
||||
|
||||
```
|
||||
|
||||
public class PerForm : AutoCleanForm
|
||||
public class PerForm : AutoCleanForm
|
||||
{
|
||||
public String EMail { get; set; }
|
||||
|
||||
public String Firstname { get; set; }
|
||||
|
||||
public String Lastname { get; set; }
|
||||
|
||||
public async override Task Load(MessageResult message)
|
||||
{
|
||||
if (message.MessageText.Trim() == "")
|
||||
return;
|
||||
|
||||
if (this.Firstname == null)
|
||||
{
|
||||
public String EMail { get; set; }
|
||||
this.Firstname = message.MessageText;
|
||||
return;
|
||||
}
|
||||
|
||||
public String Firstname { get; set; }
|
||||
if (this.Lastname == null)
|
||||
{
|
||||
this.Lastname = message.MessageText;
|
||||
return;
|
||||
}
|
||||
|
||||
public String Lastname { get; set; }
|
||||
if (this.EMail == null)
|
||||
{
|
||||
this.EMail = message.MessageText;
|
||||
return;
|
||||
}
|
||||
|
||||
public async override Task Load(MessageResult message)
|
||||
{
|
||||
if (message.MessageText.Trim() == "")
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.Firstname == null)
|
||||
{
|
||||
this.Firstname = message.MessageText;
|
||||
return;
|
||||
}
|
||||
public async override Task Action(MessageResult message)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
|
||||
if (this.Lastname == null)
|
||||
{
|
||||
this.Lastname = message.MessageText;
|
||||
return;
|
||||
}
|
||||
await message.ConfirmAction();
|
||||
|
||||
if (this.EMail == null)
|
||||
{
|
||||
this.EMail = message.MessageText;
|
||||
return;
|
||||
}
|
||||
if (call == null)
|
||||
return;
|
||||
|
||||
}
|
||||
switch (call.Value)
|
||||
{
|
||||
case "back":
|
||||
|
||||
public async override Task Action(MessageResult message)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
var start = new Start();
|
||||
|
||||
await message.ConfirmAction();
|
||||
|
||||
if (call == null)
|
||||
return;
|
||||
|
||||
switch (call.Value)
|
||||
{
|
||||
case "back":
|
||||
|
||||
var start = new Start();
|
||||
|
||||
await this.NavigateTo(start);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async override Task Render(MessageResult message)
|
||||
{
|
||||
if (this.Firstname == null)
|
||||
{
|
||||
await this.Device.Send("Please sent your firstname:");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.Lastname == null)
|
||||
{
|
||||
await this.Device.Send("Please sent your lastname:");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.EMail == null)
|
||||
{
|
||||
await this.Device.Send("Please sent your email address:");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String s = "";
|
||||
|
||||
s += "Firstname: " + this.Firstname + "\r\n";
|
||||
s += "Lastname: " + this.Lastname + "\r\n";
|
||||
s += "E-Mail: " + this.EMail + "\r\n";
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||
|
||||
await this.Device.Send("Your details:\r\n" + s, bf);
|
||||
}
|
||||
await this.NavigateTo(start);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async override Task Render(MessageResult message)
|
||||
{
|
||||
if (this.Firstname == null)
|
||||
{
|
||||
await this.Device.Send("Please sent your firstname:");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.Lastname == null)
|
||||
{
|
||||
await this.Device.Send("Please sent your lastname:");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.EMail == null)
|
||||
{
|
||||
await this.Device.Send("Please sent your email address:");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String s = "";
|
||||
|
||||
s += "Firstname: " + this.Firstname + "\r\n";
|
||||
s += "Lastname: " + this.Lastname + "\r\n";
|
||||
s += "E-Mail: " + this.EMail + "\r\n";
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||
|
||||
await this.Device.Send("Your details:\r\n" + s, bf);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
There is also a second example, where every of these 3 inputs gets requested by a different formular (class). Just for imagination of the possiblites.
|
||||
Cause its to much Text, i didnt have added it here. You will find it under [TelegramBaseTest/Tests/Register/PerStep.cs](TelegramBaseTest/Tests/Register/PerStep.cs)
|
||||
Beginn there and navigate your way through these Steps in the subfolder.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Forms
|
||||
|
||||
There are some default types of forms to make the interaction with users easier.
|
||||
For now we have the following:
|
||||
|
||||
- [AlertDialog](#alert-dialog)
|
||||
Just a simple dialog with one Button.
|
||||
|
||||
- [AutoCleanForm](#autocleanform)
|
||||
A form which needs to be derived from. It will be delete all in the context sent messages to the user after every new message or on leaving the formular and navigates somewhere else.
|
||||
Makes sense to create a "feeling" of a clean environment for the user. For instance if you have a multilevel menu. This will remove the previously shown menu, and renders the new sub/top level.
|
||||
|
||||
- [PromptDialog](#prompt-dialog)
|
||||
A simple dialog which is able to show multiple buttons and a Text message. The user could select one option and will get redirected to a different form, depending on the click.
|
||||
|
||||
### Alert Dialog
|
||||
|
||||
<img src="images/alertdialog.PNG" />
|
||||
|
||||
```
|
||||
|
||||
var fto = new TestForm2();
|
||||
|
||||
AlertDialog ad = new AlertDialog("This is a message", "Ok", fto);
|
||||
|
||||
await this.NavigateTo(ad);
|
||||
|
||||
```
|
||||
|
||||
|
||||
### AutoCleanForm
|
||||
|
||||
No example yet
|
||||
|
||||
### Prompt Dialog
|
||||
|
||||
<img src="images/promptdialog.PNG" />
|
||||
|
||||
#### Without Eventhandler (pre-init of form necessary)
|
||||
|
||||
```
|
||||
|
||||
PromptDialog pd = new PromptDialog("Please confirm");
|
||||
|
||||
pd.AddButton(new ButtonBase("Ok", "ok"));
|
||||
pd.AddButton(new ButtonBase("Cancel", "cancel"));
|
||||
|
||||
var tf = new TestForm2();
|
||||
|
||||
pd.ButtonForms.Add("ok", tf);
|
||||
pd.ButtonForms.Add("cancel", tf);
|
||||
|
||||
await this.NavigateTo(pd);
|
||||
|
||||
```
|
||||
|
||||
|
||||
#### With Eventhandler (no pre-init of form necessary)
|
||||
|
||||
```
|
||||
|
||||
PromptDialog pd = new PromptDialog("Please confirm", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
|
||||
|
||||
pd.ButtonClicked += async (s, en) =>
|
||||
{
|
||||
var tf = new TestForm2();
|
||||
|
||||
//Remember only to navigate from the current running form. (here it is the prompt dialog, cause we have left the above already)
|
||||
await pd.NavigateTo(tf);
|
||||
};
|
||||
|
||||
await this.NavigateTo(pd);
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Controls
|
||||
|
||||
### Progress Bar
|
||||
<img src="images/progressbar.PNG?raw=true" />
|
||||
|
||||
|
||||
### Calendar Picker
|
||||
<img src="images/calendarpicker.PNG?raw=true" />
|
||||
|
||||
<img src="images/calendarpicker.gif?raw=true" />
|
||||
|
||||
### Month Picker
|
||||
<img src="images/monthpicker1.PNG?raw=true" />
|
||||
<img src="images/monthpicker2.PNG?raw=true" />
|
||||
|
||||
|
||||
### Tree View
|
||||
<img src="images/treeview1.PNG?raw=true" />
|
||||
<img src="images/treeview2.PNG?raw=true" />
|
||||
<img src="images/treeview3.PNG?raw=true" />
|
||||
<img src="images/treeview4.PNG?raw=true" />
|
||||
|
||||
|
||||
### Toggle Button
|
||||
<img src="images/togglebutton.gif?raw=true" />
|
||||
|
||||
---
|
||||
|
||||
I will add more notes to it soon, so stay tuned.
|
||||
|
||||
@@ -21,13 +21,19 @@ namespace TelegramBaseTest
|
||||
bb.SystemCalls.Add("/start");
|
||||
bb.SystemCalls.Add("/form1");
|
||||
bb.SystemCalls.Add("/form2");
|
||||
|
||||
bb.SystemCalls.Add("/params");
|
||||
|
||||
bb.SystemCall += async (s, en) =>
|
||||
{
|
||||
switch (en.Command)
|
||||
{
|
||||
case "/start":
|
||||
|
||||
var start = new Start();
|
||||
|
||||
await en.Device.ActiveForm.NavigateTo(start);
|
||||
|
||||
break;
|
||||
case "/form1":
|
||||
|
||||
var form1 = new TestForm();
|
||||
@@ -47,8 +53,10 @@ namespace TelegramBaseTest
|
||||
case "/params":
|
||||
|
||||
String m = en.Parameters.DefaultIfEmpty("").Aggregate((a, b) => a + " and " + b);
|
||||
|
||||
await en.Device.Send("Your parameters are: " + m, replyTo: en.Device.LastMessageId);
|
||||
|
||||
await en.Device.Send("Your parameters are " + m, replyTo: en.Device.LastMessage);
|
||||
en.Handled = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Tests\ButtonTestForm.cs" />
|
||||
<Compile Include="Tests\DataForm.cs" />
|
||||
<Compile Include="Tests\ProgressTest.cs" />
|
||||
<Compile Include="Tests\Register\PerForm.cs" />
|
||||
<Compile Include="Tests\Register\PerStep.cs" />
|
||||
|
||||
@@ -11,7 +11,12 @@ namespace TelegramBaseTest.Tests
|
||||
public class ButtonTestForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public override async Task Opened()
|
||||
public ButtonTestForm()
|
||||
{
|
||||
this.Opened += ButtonTestForm_Opened;
|
||||
}
|
||||
|
||||
private async Task ButtonTestForm_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Hello world! (Click 'back' to get back to Start)");
|
||||
}
|
||||
@@ -59,8 +64,6 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
var st = new Start();
|
||||
|
||||
await st.Init();
|
||||
|
||||
await this.NavigateTo(st);
|
||||
|
||||
break;
|
||||
@@ -85,6 +88,8 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Button 3", new CallbackData("a", "button3").Serialize()), new ButtonBase("Button 4", new CallbackData("a", "button4").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Google.com", "google", "https://www.google.com"), new ButtonBase("Telegram", "telegram", "https://telegram.org/"));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||
|
||||
await this.Device.Send("Click a button", btn);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Controls;
|
||||
|
||||
namespace TelegramBaseTest.Tests.Controls
|
||||
{
|
||||
public class CalendarPickerForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public CalendarPicker Picker { get; set; }
|
||||
|
||||
int? selectedDateMessage { get; set; }
|
||||
|
||||
public CalendarPickerForm()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
this.Init += CalendarPickerForm_Init;
|
||||
}
|
||||
|
||||
private async Task CalendarPickerForm_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
this.Picker = new CalendarPicker();
|
||||
this.Picker.Title = "Datum auswählen / Pick date";
|
||||
|
||||
this.AddControl(Picker);
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
switch(message.RawData)
|
||||
{
|
||||
case "back":
|
||||
|
||||
var s = new Start();
|
||||
|
||||
await this.NavigateTo(s);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
String s = "";
|
||||
|
||||
s = "Selected date is " + this.Picker.SelectedDate.ToShortDateString() + "\r\n";
|
||||
s += "Selected month is " + this.Picker.Culture.DateTimeFormat.MonthNames[this.Picker.VisibleMonth.Month - 1] + "\r\n";
|
||||
s += "Selected year is " + this.Picker.VisibleMonth.Year.ToString();
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase("Back","back"));
|
||||
|
||||
if (selectedDateMessage != null)
|
||||
{
|
||||
await this.Device.Edit(this.selectedDateMessage.Value, s, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(s, bf);
|
||||
this.selectedDateMessage = m.MessageId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Controls;
|
||||
|
||||
namespace TelegramBaseTest.Tests.Controls
|
||||
{
|
||||
public class MonthPickerForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public MonthPicker Picker { get; set; }
|
||||
|
||||
int? selectedDateMessage { get; set; }
|
||||
|
||||
public MonthPickerForm()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
this.Init += MonthPickerForm_Init;
|
||||
}
|
||||
|
||||
private async Task MonthPickerForm_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
this.Picker = new MonthPicker();
|
||||
this.Picker.Title = "Monat auswählen / Pick month";
|
||||
this.AddControl(Picker);
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
switch(message.RawData)
|
||||
{
|
||||
case "back":
|
||||
|
||||
var s = new Start();
|
||||
|
||||
await this.NavigateTo(s);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
String s = "";
|
||||
|
||||
s += "Selected month is " + this.Picker.Culture.DateTimeFormat.MonthNames[this.Picker.SelectedDate.Month - 1] + "\r\n";
|
||||
s += "Selected year is " + this.Picker.VisibleMonth.Year.ToString();
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase("Back","back"));
|
||||
|
||||
if (selectedDateMessage != null)
|
||||
{
|
||||
await this.Device.Edit(this.selectedDateMessage.Value, s, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(s, bf);
|
||||
this.selectedDateMessage = m.MessageId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Controls;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests.Controls
|
||||
{
|
||||
public class ToggleButtons : AutoCleanForm
|
||||
{
|
||||
public ToggleButtons()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
|
||||
this.Init += ToggleButtons_Init;
|
||||
}
|
||||
|
||||
private async Task ToggleButtons_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
|
||||
{
|
||||
|
||||
var tb = new ToggleButton();
|
||||
tb.Checked = true;
|
||||
tb.Toggled += Tb_Toggled;
|
||||
|
||||
this.AddControl(tb);
|
||||
|
||||
tb = new ToggleButton();
|
||||
tb.Checked = false;
|
||||
tb.Toggled += Tb_Toggled;
|
||||
|
||||
this.AddControl(tb);
|
||||
|
||||
tb = new ToggleButton();
|
||||
tb.Checked = true;
|
||||
tb.Toggled += Tb_Toggled;
|
||||
|
||||
this.AddControl(tb);
|
||||
|
||||
}
|
||||
|
||||
private void Tb_Toggled(object sender, EventArgs e)
|
||||
{
|
||||
var tb = sender as ToggleButton;
|
||||
Console.WriteLine(tb.ID.ToString() + " was pressed, and toggled to " + (tb.Checked ? "Checked" : "Unchecked"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Controls;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBaseTest.Tests.Controls
|
||||
{
|
||||
public class TreeViewForms : AutoCleanForm
|
||||
{
|
||||
public TreeView view { get; set; }
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public TreeViewForms()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
this.Init += TreeViewForms_Init;
|
||||
}
|
||||
|
||||
private async Task TreeViewForms_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
|
||||
{
|
||||
view = new TreeView();
|
||||
|
||||
var tvn = new TreeViewNode("Cars", "cars");
|
||||
|
||||
tvn.AddNode(new TreeViewNode("Porsche", "porsche", new TreeViewNode("Website", "web", "https://www.porsche.com/germany/"), new TreeViewNode("911", "911"), new TreeViewNode("918 Spyder", "918")));
|
||||
tvn.AddNode(new TreeViewNode("BMW", "bmw"));
|
||||
tvn.AddNode(new TreeViewNode("Audi", "audi"));
|
||||
tvn.AddNode(new TreeViewNode("VW", "vw"));
|
||||
tvn.AddNode(new TreeViewNode("Lamborghini", "lamborghini"));
|
||||
|
||||
view.Nodes.Add(tvn);
|
||||
|
||||
tvn = new TreeViewNode("Fruits", "fruits");
|
||||
|
||||
tvn.AddNode(new TreeViewNode("Apple", "apple"));
|
||||
tvn.AddNode(new TreeViewNode("Orange", "orange"));
|
||||
tvn.AddNode(new TreeViewNode("Lemon", "lemon"));
|
||||
|
||||
view.Nodes.Add(tvn);
|
||||
|
||||
this.AddControl(view);
|
||||
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
await message.ConfirmAction();
|
||||
|
||||
if (message.Handled)
|
||||
return;
|
||||
|
||||
switch (message.RawData)
|
||||
{
|
||||
case "back":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var start = new Start();
|
||||
|
||||
await this.NavigateTo(start);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
String s = "";
|
||||
|
||||
s += "Selected Node: " + (this.view.SelectedNode?.Text ?? "(null)") + "\r\n";
|
||||
|
||||
s += "Visible Node: " + (this.view.VisibleNode?.Text ?? "(top)") + "\r\n";
|
||||
|
||||
s += "Visible Path: " + this.view.GetPath() + "\r\n";
|
||||
s += "Selected Path: " + (this.view.SelectedNode?.GetPath() ?? "(null)") + "\r\n";
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase("Back", "back"));
|
||||
|
||||
if (MessageId != null)
|
||||
{
|
||||
await this.Device.Edit(this.MessageId.Value, s, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(s, bf);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.InputFiles;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests
|
||||
{
|
||||
public class DataForm : AutoCleanForm
|
||||
{
|
||||
|
||||
|
||||
public override async Task SentData(DataResult data)
|
||||
{
|
||||
String tmp = "";
|
||||
InputOnlineFile file;
|
||||
|
||||
switch (data.Type)
|
||||
{
|
||||
case Telegram.Bot.Types.Enums.MessageType.Contact:
|
||||
|
||||
tmp += "Firstname: " + data.Contact.FirstName + "\r\n";
|
||||
tmp += "Lastname: " + data.Contact.LastName + "\r\n";
|
||||
tmp += "Phonenumber: " + data.Contact.PhoneNumber + "\r\n";
|
||||
tmp += "UserId: " + data.Contact.UserId + "\r\n";
|
||||
|
||||
await this.Device.Send("Your contact: \r\n" + tmp, replyTo: data.MessageId);
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Document:
|
||||
|
||||
file = new InputOnlineFile(data.Document.FileId);
|
||||
|
||||
await this.Device.SendDocument(file, "Your uploaded document");
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Video:
|
||||
|
||||
file = new InputOnlineFile(data.Document.FileId);
|
||||
|
||||
await this.Device.SendDocument(file, "Your uploaded video");
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Audio:
|
||||
|
||||
file = new InputOnlineFile(data.Document.FileId);
|
||||
|
||||
await this.Device.SendDocument(file, "Your uploaded audio");
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Location:
|
||||
|
||||
tmp += "Lat: " + data.Location.Latitude + "\r\n";
|
||||
tmp += "Lng: " + data.Location.Longitude + "\r\n";
|
||||
|
||||
await this.Device.Send("Your location: \r\n" + tmp, replyTo: data.MessageId);
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Photo:
|
||||
|
||||
InputOnlineFile photo = new InputOnlineFile(data.Photos.Last().FileId);
|
||||
|
||||
await this.Device.Send("Your image: ", replyTo: data.MessageId);
|
||||
await this.Client.TelegramClient.SendPhotoAsync(this.Device.DeviceId, photo);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
await this.Device.Send("Unknown response");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
await message.ConfirmAction();
|
||||
|
||||
if (message.Handled)
|
||||
return;
|
||||
|
||||
switch (message.RawData)
|
||||
{
|
||||
case "contact":
|
||||
|
||||
await this.Device.RequestContact();
|
||||
|
||||
break;
|
||||
|
||||
case "location":
|
||||
|
||||
await this.Device.RequestLocation();
|
||||
|
||||
break;
|
||||
|
||||
case "back":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var start = new Start();
|
||||
|
||||
await this.NavigateTo(start);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("Request User contact", "contact"));
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("Request User location", "location"));
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("Back", "back"));
|
||||
|
||||
InlineKeyboardMarkup ikv = bf;
|
||||
|
||||
await this.Device.Send("Please upload a contact, photo, video, audio, document or location.", bf);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,13 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
public ProgressTest()
|
||||
{
|
||||
this.DeleteMode = eDeleteMode.OnLeavingForm;
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
this.Opened += ProgressTest_Opened;
|
||||
this.Closed += ProgressTest_Closed;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
|
||||
private async Task ProgressTest_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Welcome to ProgressTest");
|
||||
}
|
||||
@@ -75,8 +78,6 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
var sf = new Start();
|
||||
|
||||
await sf.Init();
|
||||
|
||||
await this.NavigateTo(sf);
|
||||
|
||||
return;
|
||||
@@ -89,14 +90,14 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
|
||||
//Render Progress bar and show some "example" progress
|
||||
await Bar.Render();
|
||||
await Bar.Render(message);
|
||||
|
||||
this.Controls.Add(Bar);
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
Bar.Value++;
|
||||
await Bar.Render();
|
||||
await Bar.Render(message);
|
||||
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
@@ -119,17 +120,10 @@ namespace TelegramBaseTest.Tests
|
||||
await this.Device.Send("Choose your progress bar:", btn);
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task ProgressTest_Closed(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
await b.Cleanup();
|
||||
}
|
||||
|
||||
await this.Device.Send("Ciao from ProgressTest");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,17 @@ namespace TelegramBaseTest.Tests.Register.Steps
|
||||
{
|
||||
public Data UserData { get; set; }
|
||||
|
||||
public async override Task Init(params object[] args)
|
||||
public Step1()
|
||||
{
|
||||
this.Init += Step1_Init;
|
||||
}
|
||||
|
||||
private async Task Step1_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
this.UserData = new Data();
|
||||
}
|
||||
|
||||
|
||||
public async override Task Load(MessageResult message)
|
||||
{
|
||||
if (message.Handled)
|
||||
|
||||
@@ -8,14 +8,21 @@ using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests
|
||||
{
|
||||
public class SimpleForm : FormBase
|
||||
public class SimpleForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public override async Task Opened()
|
||||
public SimpleForm()
|
||||
{
|
||||
await this.Device.Send("Hello world! (send 'back' to get back to Start)");
|
||||
this.DeleteSide = TelegramBotBase.Enums.eSide.Both;
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
|
||||
this.Opened += SimpleForm_Opened;
|
||||
}
|
||||
|
||||
private async Task SimpleForm_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Hello world! (send 'back' to get back to Start)\r\nOr\r\nhi, hello, maybe, bye and ciao");
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
@@ -50,8 +57,6 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
var st = new Start();
|
||||
|
||||
await st.Init();
|
||||
|
||||
await this.NavigateTo(st);
|
||||
|
||||
break;
|
||||
|
||||
@@ -8,8 +8,12 @@ using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests
|
||||
{
|
||||
public class Start : FormBase
|
||||
public class Start : AutoCleanForm
|
||||
{
|
||||
public Start()
|
||||
{
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
@@ -53,6 +57,72 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
await this.NavigateTo(reg);
|
||||
|
||||
break;
|
||||
|
||||
case "form1":
|
||||
|
||||
var form1 = new TestForm();
|
||||
|
||||
await this.NavigateTo(form1);
|
||||
|
||||
break;
|
||||
|
||||
case "form2":
|
||||
|
||||
var form2 = new TestForm2();
|
||||
|
||||
await this.NavigateTo(form2);
|
||||
|
||||
break;
|
||||
|
||||
case "data":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var data = new DataForm();
|
||||
|
||||
await this.NavigateTo(data);
|
||||
|
||||
break;
|
||||
|
||||
case "calendar":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var calendar = new Controls.CalendarPickerForm();
|
||||
|
||||
await this.NavigateTo(calendar);
|
||||
|
||||
break;
|
||||
|
||||
case "month":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var month = new Controls.MonthPickerForm();
|
||||
|
||||
await this.NavigateTo(month);
|
||||
|
||||
break;
|
||||
|
||||
case "treeview":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var tree = new Controls.TreeViewForms();
|
||||
|
||||
await this.NavigateTo(tree);
|
||||
|
||||
break;
|
||||
|
||||
case "togglebuttons":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var tb = new Controls.ToggleButtons();
|
||||
|
||||
await this.NavigateTo(tb);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -68,6 +138,18 @@ namespace TelegramBaseTest.Tests
|
||||
btn.AddButtonRow(new ButtonBase("#3 Progress Bar", new CallbackData("a", "progress").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#4 Registration Example", new CallbackData("a", "registration").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#5 Form1 Command", new CallbackData("a", "form1").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#6 Form2 Command", new CallbackData("a", "form2").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#7 Data Handling", new CallbackData("a", "data").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#8 Calendar Picker", new CallbackData("a", "calendar").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#9 Month Picker", new CallbackData("a", "month").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#10 TreeView", new CallbackData("a", "treeview").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#11 ToggleButtons", new CallbackData("a", "togglebuttons").Serialize()));
|
||||
|
||||
await this.Device.Send("Choose your test:", btn);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,27 +15,22 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
String LastMessage { get; set; }
|
||||
|
||||
public override async Task Init(params object[] param)
|
||||
public TestForm()
|
||||
{
|
||||
|
||||
this.Opened += TestForm_Opened;
|
||||
this.Closed += TestForm_Closed;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
private async Task TestForm_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Welcome to Form 1");
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task TestForm_Closed(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Ciao from Form 1");
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
@@ -51,8 +46,6 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
var tf = new TestForm2();
|
||||
|
||||
await tf.Init();
|
||||
|
||||
await this.NavigateTo(tf);
|
||||
|
||||
break;
|
||||
|
||||
@@ -15,25 +15,25 @@ namespace TelegramBaseTest.Tests
|
||||
public class TestForm2 : FormBase
|
||||
{
|
||||
|
||||
public override async Task Init(params object[] param)
|
||||
{
|
||||
|
||||
public TestForm2()
|
||||
{
|
||||
this.Opened += TestForm2_Opened;
|
||||
this.Closed += TestForm2_Closed;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
private async Task TestForm2_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Welcome to Form 2");
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task TestForm2_Closed(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Ciao from Form 2");
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
@@ -48,30 +48,40 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
var tf = new TestForm();
|
||||
|
||||
await tf.Init();
|
||||
|
||||
await this.NavigateTo(tf);
|
||||
}
|
||||
else if (call.Value == "alert")
|
||||
{
|
||||
var fto = new TestForm2();
|
||||
await fto.Init();
|
||||
|
||||
AlertDialog ad = new AlertDialog("This is a message", "Ok", fto);
|
||||
|
||||
|
||||
|
||||
await this.NavigateTo(ad);
|
||||
}
|
||||
else if (call.Value == "prompt")
|
||||
{
|
||||
PromptDialog pd = new PromptDialog("Please confirm", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
|
||||
PromptDialog pd = new PromptDialog("Please confirm");
|
||||
|
||||
pd.AddButton(new ButtonBase("Ok", "ok"));
|
||||
pd.AddButton(new ButtonBase("Cancel", "cancel"));
|
||||
|
||||
var tf = new TestForm2();
|
||||
|
||||
await tf.Init();
|
||||
|
||||
pd.ButtonForms.Add("ok", tf);
|
||||
pd.ButtonForms.Add("cancel", tf);
|
||||
|
||||
await this.NavigateTo(pd);
|
||||
}
|
||||
else if (call.Value == "promptevt")
|
||||
{
|
||||
PromptDialog pd = new PromptDialog("Please confirm", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
|
||||
|
||||
pd.ButtonClicked += async (s, en) =>
|
||||
{
|
||||
var tf = new TestForm2();
|
||||
|
||||
await pd.NavigateTo(tf);
|
||||
};
|
||||
|
||||
await this.NavigateTo(pd);
|
||||
}
|
||||
@@ -98,7 +108,11 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
//btn.AddButtonRow(new ButtonBase("Zum Testformular 1", CallbackData.Create("navigate", "testform1")), new ButtonBase("Zum Testformular 1", CallbackData.Create("navigate", "testform1")));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Information Prompt", CallbackData.Create("navigate", "alert")), new ButtonBase("Confirmation Prompt", CallbackData.Create("navigate", "prompt")));
|
||||
btn.AddButtonRow(new ButtonBase("Information Prompt", CallbackData.Create("navigate", "alert")));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Confirmation Prompt without event", CallbackData.Create("navigate", "prompt")));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Confirmation Prompt with event", CallbackData.Create("navigate", "promptevt")));
|
||||
|
||||
|
||||
await this.Device.SendPhoto(bmp, "Test", btn);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net452" />
|
||||
<package id="System.Net.Requests" version="4.3.0" targetFramework="net452" />
|
||||
<package id="Telegram.Bot" version="14.10.0" targetFramework="net452" />
|
||||
<package id="Telegram.Bot" version="14.12.0" targetFramework="net452" />
|
||||
</packages>
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public static class Async
|
||||
{
|
||||
public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;
|
||||
|
||||
public static IEnumerable<AsyncEventHandler<TEventArgs>> GetHandlers<TEventArgs>(
|
||||
this AsyncEventHandler<TEventArgs> handler)
|
||||
where TEventArgs : EventArgs
|
||||
=> handler.GetInvocationList().Cast<AsyncEventHandler<TEventArgs>>();
|
||||
|
||||
public static Task InvokeAllAsync<TEventArgs>(this AsyncEventHandler<TEventArgs> handler, object sender, TEventArgs e)
|
||||
where TEventArgs : EventArgs
|
||||
=> Task.WhenAll(
|
||||
handler.GetHandlers()
|
||||
.Select(handleAsync => handleAsync(sender, e)));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,35 @@ namespace TelegramBotBase.Base
|
||||
{
|
||||
public Sessions.DeviceSession Device { get; set; }
|
||||
|
||||
public virtual async Task Render()
|
||||
public int ID { get; set; }
|
||||
|
||||
public String ControlID
|
||||
{
|
||||
get
|
||||
{
|
||||
return "#c" + this.ID.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the control should be rendered and invoked with actions
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
public virtual async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public virtual async Task Render(MessageResult result)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.InputFiles;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a class to manage attachments within messages.
|
||||
/// </summary>
|
||||
public class DataResult : ResultBase
|
||||
{
|
||||
public Telegram.Bot.Args.MessageEventArgs RawMessageData { get; set; }
|
||||
|
||||
public Contact Contact
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Contact;
|
||||
}
|
||||
}
|
||||
|
||||
public Location Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Location;
|
||||
}
|
||||
}
|
||||
|
||||
public Document Document
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Document;
|
||||
}
|
||||
}
|
||||
|
||||
public Audio Audio
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Audio;
|
||||
}
|
||||
}
|
||||
|
||||
public Video Video
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Video;
|
||||
}
|
||||
}
|
||||
|
||||
public PhotoSize[] Photos
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Photo;
|
||||
}
|
||||
}
|
||||
|
||||
public Telegram.Bot.Types.Enums.MessageType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.RawMessageData?.Message?.Type ?? Telegram.Bot.Types.Enums.MessageType.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the FileId of the first reachable element.
|
||||
/// </summary>
|
||||
public String FileId
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.Document?.FileId ??
|
||||
this.Audio?.FileId ??
|
||||
this.Video?.FileId ??
|
||||
this.Photos.FirstOrDefault()?.FileId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DataResult(Telegram.Bot.Args.MessageEventArgs rawdata)
|
||||
{
|
||||
this.RawMessageData = rawdata;
|
||||
this.Message = rawdata.Message;
|
||||
}
|
||||
|
||||
public DataResult(MessageResult message)
|
||||
{
|
||||
this.RawMessageData = message.RawMessageData;
|
||||
this.Message = message.Message;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<InputOnlineFile> DownloadDocument()
|
||||
{
|
||||
var encryptedContent = new System.IO.MemoryStream(this.Document.FileSize);
|
||||
var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, encryptedContent);
|
||||
|
||||
return new InputOnlineFile(encryptedContent, this.Document.FileName);
|
||||
}
|
||||
|
||||
public async Task<InputOnlineFile> DownloadVideo()
|
||||
{
|
||||
var encryptedContent = new System.IO.MemoryStream(this.Video.FileSize);
|
||||
var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Video.FileId, encryptedContent);
|
||||
|
||||
return new InputOnlineFile(encryptedContent, "");
|
||||
}
|
||||
|
||||
public async Task<InputOnlineFile> DownloadPhoto(int index)
|
||||
{
|
||||
var photo = this.Photos[index];
|
||||
var encryptedContent = new System.IO.MemoryStream(photo.FileSize);
|
||||
var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(photo.FileId, encryptedContent);
|
||||
|
||||
return new InputOnlineFile(encryptedContent, "");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Sessions;
|
||||
using static TelegramBotBase.Base.Async;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -13,43 +15,131 @@ namespace TelegramBotBase.Form
|
||||
/// </summary>
|
||||
public class FormBase : IDisposable
|
||||
{
|
||||
|
||||
public DeviceSession Device { get; set; }
|
||||
|
||||
public MessageClient Client { get; set; }
|
||||
|
||||
public bool CustomEventManagement { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// contains if the form has been switched (navigated)
|
||||
/// has this formular already been disposed ?
|
||||
/// </summary>
|
||||
public bool FormSwitched { get; set; } = false;
|
||||
public bool IsDisposed { get; set; } = false;
|
||||
|
||||
public List<ControlBase> Controls { get; set; }
|
||||
|
||||
|
||||
private EventHandlerList Events = new EventHandlerList();
|
||||
|
||||
|
||||
private static object __evInit = new object();
|
||||
|
||||
private static object __evOpened = new object();
|
||||
|
||||
private static object __evClosed = new object();
|
||||
|
||||
|
||||
public FormBase()
|
||||
{
|
||||
this.Controls = new List<Base.ControlBase>();
|
||||
}
|
||||
|
||||
public FormBase(MessageClient Client): this()
|
||||
public FormBase(MessageClient Client) : this()
|
||||
{
|
||||
this.Client = Client;
|
||||
}
|
||||
|
||||
|
||||
public async Task OnInit(InitEventArgs e)
|
||||
{
|
||||
if (this.Events[__evInit] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evInit].GetInvocationList().Cast<AsyncEventHandler<InitEventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<InitEventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Will get called at the initialization (once per context)
|
||||
///// </summary>
|
||||
public event AsyncEventHandler<InitEventArgs> Init
|
||||
{
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evInit, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evInit, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task OnOpened(EventArgs e)
|
||||
{
|
||||
if (this.Events[__evOpened] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evOpened].GetInvocationList().Cast<AsyncEventHandler<EventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<EventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will get called at the initialization (once per context)
|
||||
/// Gets invoked if gets navigated to this form
|
||||
/// </summary>
|
||||
public virtual async Task Init(params object[] args)
|
||||
/// <returns></returns>
|
||||
public event AsyncEventHandler<EventArgs> Opened
|
||||
{
|
||||
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evOpened, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evOpened, value);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task Opened()
|
||||
public async Task OnClosed(EventArgs e)
|
||||
{
|
||||
if (this.Events[__evClosed] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evClosed].GetInvocationList().Cast<AsyncEventHandler<EventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<EventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task Closed()
|
||||
/// <summary>
|
||||
/// Form has been closed (left)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public event AsyncEventHandler<EventArgs> Closed
|
||||
{
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evClosed, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evClosed, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Pre to form close, cleanup all controls
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task CloseControls()
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
@@ -62,22 +152,91 @@ namespace TelegramBotBase.Form
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the form gets loaded and on every message belongs to this context
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the user clicked a button.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task ActionControls(MessageResult message)
|
||||
{
|
||||
//Looking for the control by id, if not listened, raise event for all
|
||||
if (message.RawData.StartsWith("#c"))
|
||||
{
|
||||
var c = this.Controls.FirstOrDefault(a => a.ControlID == message.RawData.Split('_')[0]);
|
||||
if (c != null)
|
||||
{
|
||||
await c.Action(message, message.RawData.Split('_')[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
if (!b.Enabled)
|
||||
continue;
|
||||
|
||||
await b.Action(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the user has clicked a button.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the user has sent some media (Photo, Audio, Video, Contact, Location, Document)
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task SentData(DataResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked at the end of the cycle to "Render" text, images, buttons, etc...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task RenderControls(MessageResult message)
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
if (!b.Enabled)
|
||||
continue;
|
||||
|
||||
await b.Render(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked at the end of the cycle to "Render" text, images, buttons, etc...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task Render(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Navigates to a new form
|
||||
/// </summary>
|
||||
@@ -89,17 +248,28 @@ namespace TelegramBotBase.Form
|
||||
if (ds == null)
|
||||
return;
|
||||
|
||||
this.FormSwitched = true;
|
||||
ds.FormSwitched = true;
|
||||
|
||||
ds.PreviousForm = ds.ActiveForm;
|
||||
|
||||
ds.ActiveForm = newForm;
|
||||
newForm.Client = this.Client;
|
||||
newForm.Device = ds;
|
||||
|
||||
await newForm.Init(args);
|
||||
await newForm.OnInit(new InitEventArgs(args));
|
||||
|
||||
await this.Closed();
|
||||
await this.CloseControls();
|
||||
|
||||
await newForm.Opened();
|
||||
await this.OnClosed(new EventArgs());
|
||||
|
||||
await newForm.OnOpened(new EventArgs());
|
||||
}
|
||||
|
||||
public void AddControl(ControlBase control)
|
||||
{
|
||||
control.ID = this.Controls.Count + 1;
|
||||
control.Device = this.Device;
|
||||
this.Controls.Add(control);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -109,7 +279,7 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
this.Client = null;
|
||||
this.Device = null;
|
||||
this.FormSwitched = false;
|
||||
this.IsDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public class InitEventArgs : EventArgs
|
||||
{
|
||||
public object[] Args { get; set; }
|
||||
|
||||
public InitEventArgs(params object[] args)
|
||||
{
|
||||
this.Args = args;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -32,6 +34,43 @@ namespace TelegramBotBase.Base
|
||||
Prepare();
|
||||
}
|
||||
|
||||
public MessageClient(String APIKey, HttpClient proxy)
|
||||
{
|
||||
this.APIKey = APIKey;
|
||||
this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, proxy);
|
||||
|
||||
|
||||
Prepare();
|
||||
}
|
||||
|
||||
public MessageClient(String APIKey, Uri proxyUrl)
|
||||
{
|
||||
this.APIKey = APIKey;
|
||||
|
||||
var proxy = new WebProxy(proxyUrl);
|
||||
|
||||
this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, proxy);
|
||||
|
||||
Prepare();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the client with a proxy
|
||||
/// </summary>
|
||||
/// <param name="APIKey"></param>
|
||||
/// <param name="proxyHost">i.e. 127.0.0.1</param>
|
||||
/// <param name="proxyPort">i.e. 10000</param>
|
||||
public MessageClient(String APIKey, String proxyHost, int proxyPort)
|
||||
{
|
||||
this.APIKey = APIKey;
|
||||
|
||||
var proxy = new WebProxy(proxyHost, proxyPort);
|
||||
|
||||
this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, proxy);
|
||||
|
||||
Prepare();
|
||||
}
|
||||
|
||||
public MessageClient(String APIKey, Telegram.Bot.TelegramBotClient Client)
|
||||
{
|
||||
this.APIKey = APIKey;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public class MessageReceivedEventArgs
|
||||
{
|
||||
public int MessageId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public Message Message { get; set; }
|
||||
|
||||
public MessageReceivedEventArgs(Message m)
|
||||
{
|
||||
this.Message = m;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
@@ -23,6 +24,9 @@ namespace TelegramBotBase.Base
|
||||
}
|
||||
}
|
||||
|
||||
public DeviceSession Device
|
||||
{ get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The message id
|
||||
/// </summary>
|
||||
@@ -62,7 +66,7 @@ namespace TelegramBotBase.Base
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this a system call ? Starts with a slash and command
|
||||
/// Is this a system call ? Starts with a slash '/' and a command
|
||||
/// </summary>
|
||||
public bool IsSystemCall
|
||||
{
|
||||
|
||||
@@ -9,18 +9,18 @@ namespace TelegramBotBase.Base
|
||||
{
|
||||
public class MessageSentEventArgs
|
||||
{
|
||||
public int MessageId { get; set; }
|
||||
public int MessageId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public Message Message { get; set; }
|
||||
|
||||
public MessageSentEventArgs()
|
||||
public MessageSentEventArgs(Message message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MessageSentEventArgs(int MessageId, Message message)
|
||||
{
|
||||
this.MessageId = MessageId;
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
@@ -22,6 +23,8 @@ namespace TelegramBotBase.Base
|
||||
|
||||
public bool Handled { get; set; } = false;
|
||||
|
||||
public Message OriginalMessage { get; set; }
|
||||
|
||||
|
||||
public SystemCallEventArgs()
|
||||
{
|
||||
@@ -29,10 +32,11 @@ namespace TelegramBotBase.Base
|
||||
|
||||
}
|
||||
|
||||
public SystemCallEventArgs(String Command, List<String> Parameters, long DeviceId, DeviceSession Device)
|
||||
public SystemCallEventArgs(String Command, List<String> Parameters, Message Message, long DeviceId, DeviceSession Device)
|
||||
{
|
||||
this.Command = Command;
|
||||
this.Parameters = Parameters;
|
||||
this.OriginalMessage = Message;
|
||||
this.DeviceId = DeviceId;
|
||||
this.Device = Device;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Sessions;
|
||||
@@ -42,6 +43,8 @@ namespace TelegramBotBase
|
||||
|
||||
private static object __evSystemCall = new object();
|
||||
|
||||
public delegate Task SystemCallEventHandler(object sender, SystemCallEventArgs e);
|
||||
|
||||
private static object __evException = new object();
|
||||
|
||||
private static object __evUnhandledCall = new object();
|
||||
@@ -78,6 +81,77 @@ namespace TelegramBotBase
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple start of your Bot with the APIKey and a proxyAdress
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="proxyBaseAddress">i.e. https://127.0.0.1:10000</param>
|
||||
public BotBase(String apiKey, System.Net.Http.HttpClient proxy)
|
||||
{
|
||||
this.APIKey = apiKey;
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey, proxy);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
this.Sessions = new SessionBase();
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple start of your Bot with the APIKey and a TelegramBotClient instance.
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="client"></param>
|
||||
public BotBase(String apiKey, TelegramBotClient client)
|
||||
{
|
||||
this.APIKey = apiKey;
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey, client);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
this.Sessions = new SessionBase();
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple start of your Bot with the APIKey and a proxyAdress
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="proxyBaseAddress">i.e. https://127.0.0.1:10000</param>
|
||||
public BotBase(String apiKey, String proxyBaseAddress)
|
||||
{
|
||||
this.APIKey = apiKey;
|
||||
|
||||
var url = new Uri(proxyBaseAddress);
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey, url);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
this.Sessions = new SessionBase();
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple start of your Bot with the APIKey and a proxyAdress
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="proxyHost">i.e. 127.0.0.1</param>
|
||||
/// <param name="proxyPort">i.e. 10000</param>
|
||||
public BotBase(String apiKey, String proxyHost, int proxyPort)
|
||||
{
|
||||
this.APIKey = apiKey;
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey, proxyHost, proxyPort);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
this.Sessions = new SessionBase();
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start your Bot
|
||||
/// </summary>
|
||||
@@ -127,12 +201,15 @@ namespace TelegramBotBase
|
||||
|
||||
try
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
if (LogAllMessages)
|
||||
{
|
||||
DeviceSession ds2 = this.Sessions.GetSession(e.DeviceId);
|
||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds2, e));
|
||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds, e));
|
||||
}
|
||||
|
||||
ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message));
|
||||
|
||||
Client_TryMessage(sender, e);
|
||||
}
|
||||
@@ -149,26 +226,28 @@ namespace TelegramBotBase
|
||||
|
||||
private async void Client_TryMessage(object sender, MessageResult e)
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
DeviceSession ds = e.Device;
|
||||
if (ds == null)
|
||||
{
|
||||
ds = await this.Sessions.StartSession<T>(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
ds.LastMessage = e.MessageId;
|
||||
ds.LastMessage = e.Message;
|
||||
|
||||
OnSessionBegins(new SessionBeginResult(e.DeviceId, ds));
|
||||
}
|
||||
|
||||
ds.LastAction = DateTime.Now;
|
||||
ds.LastMessage = e.MessageId;
|
||||
ds.LastMessage = e.Message;
|
||||
|
||||
//Is this a systemcall ?
|
||||
if (e.IsSystemCall && this.SystemCalls.Contains(e.SystemCommand))
|
||||
{
|
||||
var sce = new SystemCallEventArgs(e.SystemCommand, e.SystemCallParameters, ds.DeviceId, ds);
|
||||
OnSystemCall(sce);
|
||||
var sce = new SystemCallEventArgs(e.SystemCommand, e.SystemCallParameters, e.Message, ds.DeviceId, ds);
|
||||
await OnSystemCall(sce);
|
||||
|
||||
return;
|
||||
if (sce.Handled)
|
||||
return;
|
||||
}
|
||||
|
||||
FormBase activeForm = null;
|
||||
@@ -180,11 +259,10 @@ namespace TelegramBotBase
|
||||
{
|
||||
i++;
|
||||
|
||||
activeForm = ds.ActiveForm;
|
||||
//Reset navigation
|
||||
ds.FormSwitched = false;
|
||||
|
||||
//If the form manages the events by itselfs, skip here
|
||||
if (activeForm.CustomEventManagement)
|
||||
return;
|
||||
activeForm = ds.ActiveForm;
|
||||
|
||||
//Pre Loading Event
|
||||
await activeForm.PreLoad(e);
|
||||
@@ -192,11 +270,18 @@ namespace TelegramBotBase
|
||||
//Loading Event
|
||||
await activeForm.Load(e);
|
||||
|
||||
//Is Attachment ? (Photo, Audio, Video, Contact, Location, Document)
|
||||
if (e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Contact | e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Document | e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Location |
|
||||
e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Photo | e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Video | e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Audio)
|
||||
{
|
||||
await activeForm.SentData(new DataResult(e));
|
||||
}
|
||||
|
||||
//Render Event
|
||||
if (!activeForm.FormSwitched)
|
||||
if (!ds.FormSwitched)
|
||||
await activeForm.Render(e);
|
||||
|
||||
} while (activeForm.FormSwitched && i < NavigationMaximum);
|
||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
||||
|
||||
}
|
||||
|
||||
@@ -204,6 +289,14 @@ namespace TelegramBotBase
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
if (LogAllMessages)
|
||||
{
|
||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds, e));
|
||||
}
|
||||
|
||||
Client_TryAction(sender, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -215,15 +308,16 @@ namespace TelegramBotBase
|
||||
|
||||
private async void Client_TryAction(object sender, MessageResult e)
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
DeviceSession ds = e.Device;
|
||||
if (ds == null)
|
||||
{
|
||||
ds = await this.Sessions.StartSession<T>(e.DeviceId);
|
||||
e.Device = ds;
|
||||
}
|
||||
|
||||
|
||||
ds.LastAction = DateTime.Now;
|
||||
ds.LastMessage = e.MessageId;
|
||||
ds.LastMessage = e.Message;
|
||||
|
||||
FormBase activeForm = null;
|
||||
|
||||
@@ -234,11 +328,10 @@ namespace TelegramBotBase
|
||||
{
|
||||
i++;
|
||||
|
||||
activeForm = ds.ActiveForm;
|
||||
//Reset navigation
|
||||
ds.FormSwitched = false;
|
||||
|
||||
//If the form manages the events by itselfs, skip here
|
||||
if (activeForm.CustomEventManagement)
|
||||
return;
|
||||
activeForm = ds.ActiveForm;
|
||||
|
||||
//Pre Loading Event
|
||||
await activeForm.PreLoad(e);
|
||||
@@ -247,8 +340,12 @@ namespace TelegramBotBase
|
||||
await activeForm.Load(e);
|
||||
|
||||
//Action Event
|
||||
if (!activeForm.FormSwitched)
|
||||
if (!ds.FormSwitched)
|
||||
{
|
||||
//Send Action event to controls
|
||||
await activeForm.ActionControls(e);
|
||||
|
||||
//Send Action event to form itself
|
||||
await activeForm.Action(e);
|
||||
|
||||
if (!e.Handled)
|
||||
@@ -258,7 +355,7 @@ namespace TelegramBotBase
|
||||
|
||||
if (uhc.Handled)
|
||||
{
|
||||
if (activeForm.FormSwitched)
|
||||
if (ds.FormSwitched)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -272,10 +369,14 @@ namespace TelegramBotBase
|
||||
}
|
||||
|
||||
//Render Event
|
||||
if (!activeForm.FormSwitched)
|
||||
await activeForm.Render(e);
|
||||
if (!ds.FormSwitched)
|
||||
{
|
||||
await activeForm.RenderControls(e);
|
||||
|
||||
} while (activeForm.FormSwitched && i < NavigationMaximum);
|
||||
await activeForm.Render(e);
|
||||
}
|
||||
|
||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
||||
|
||||
}
|
||||
|
||||
@@ -325,21 +426,13 @@ namespace TelegramBotBase
|
||||
/// <summary>
|
||||
/// Will be called if a system call gets raised
|
||||
/// </summary>
|
||||
public event EventHandler<SystemCallEventArgs> SystemCall
|
||||
{
|
||||
add
|
||||
{
|
||||
this.__Events.AddHandler(__evSystemCall, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.__Events.RemoveHandler(__evSystemCall, value);
|
||||
}
|
||||
}
|
||||
public event SystemCallEventHandler SystemCall;
|
||||
|
||||
public void OnSystemCall(SystemCallEventArgs e)
|
||||
|
||||
public async Task OnSystemCall(SystemCallEventArgs e)
|
||||
{
|
||||
(this.__Events[__evSystemCall] as EventHandler<SystemCallEventArgs>)?.Invoke(this, e);
|
||||
if (this.SystemCall != null)
|
||||
await SystemCall(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Constants
|
||||
{
|
||||
public static class Telegram
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum length of message text before the API throws an exception. (We will catch it before)
|
||||
/// </summary>
|
||||
public const int MaxMessageLength = 4096;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
using static TelegramBotBase.Tools.Arrays;
|
||||
using static TelegramBotBase.Tools.Time;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class CalendarPicker : Base.ControlBase
|
||||
{
|
||||
|
||||
public DateTime SelectedDate { get; set; }
|
||||
|
||||
public DateTime VisibleMonth { get; set; }
|
||||
|
||||
public DayOfWeek FirstDayOfWeek { get; set; }
|
||||
|
||||
public CultureInfo Culture { get; set; }
|
||||
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public String Title { get; set; } = "Pick Date";
|
||||
|
||||
public eMonthPickerMode PickerMode { get; set; }
|
||||
|
||||
public bool EnableDayView { get; set; } = true;
|
||||
|
||||
public bool EnableMonthView { get; set; } = true;
|
||||
|
||||
public bool EnableYearView { get; set; } = true;
|
||||
|
||||
public CalendarPicker()
|
||||
{
|
||||
this.SelectedDate = DateTime.Today;
|
||||
this.VisibleMonth = DateTime.Today;
|
||||
this.FirstDayOfWeek = DayOfWeek.Monday;
|
||||
this.Culture = new CultureInfo("de-de");
|
||||
this.PickerMode = eMonthPickerMode.day;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
await result.ConfirmAction();
|
||||
|
||||
switch (result.RawData)
|
||||
{
|
||||
case "next":
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
this.VisibleMonth = this.VisibleMonth.AddMonths(1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(10);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case "prev":
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
this.VisibleMonth = this.VisibleMonth.AddMonths(-1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(-1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(-10);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "monthtitle":
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "yeartitle":
|
||||
|
||||
if (this.EnableYearView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.year;
|
||||
}
|
||||
|
||||
break;
|
||||
case "yearstitle":
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
int day = 0;
|
||||
if (result.RawData.StartsWith("d-") && int.TryParse(result.RawData.Split('-')[1], out day))
|
||||
{
|
||||
this.SelectedDate = new DateTime(this.VisibleMonth.Year, this.VisibleMonth.Month, day);
|
||||
}
|
||||
|
||||
int month = 0;
|
||||
if (result.RawData.StartsWith("m-") && int.TryParse(result.RawData.Split('-')[1], out month))
|
||||
{
|
||||
this.SelectedDate = new DateTime(this.VisibleMonth.Year, month, 1);
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
if (this.EnableDayView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.day;
|
||||
}
|
||||
}
|
||||
|
||||
int year = 0;
|
||||
if (result.RawData.StartsWith("y-") && int.TryParse(result.RawData.Split('-')[1], out year))
|
||||
{
|
||||
this.SelectedDate = new DateTime(year, SelectedDate.Month, SelectedDate.Day);
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
|
||||
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
|
||||
var month = this.VisibleMonth;
|
||||
|
||||
string[] dayNamesNormal = this.Culture.DateTimeFormat.ShortestDayNames;
|
||||
string[] dayNamesShifted = Shift(dayNamesNormal, (int)this.FirstDayOfWeek);
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase(this.Culture.DateTimeFormat.MonthNames[month.Month - 1] + " " + month.Year.ToString(), "monthtitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
bf.AddButtonRow(dayNamesShifted.Select(a => new ButtonBase(a, a)).ToList());
|
||||
|
||||
//First Day of month
|
||||
var firstDay = new DateTime(month.Year, month.Month, 1);
|
||||
|
||||
//Last Day of month
|
||||
var lastDay = firstDay.LastDayOfMonth();
|
||||
|
||||
//Start of Week where first day of month is (left border)
|
||||
var start = firstDay.StartOfWeek(this.FirstDayOfWeek);
|
||||
|
||||
//End of week where last day of month is (right border)
|
||||
var end = lastDay.EndOfWeek(this.FirstDayOfWeek);
|
||||
|
||||
for (int i = 0; i <= ((end - start).Days / 7); i++)
|
||||
{
|
||||
var lst = new List<ButtonBase>();
|
||||
for (int id = 0; id < 7; id++)
|
||||
{
|
||||
var d = start.AddDays((i * 7) + id);
|
||||
if (d < firstDay | d > lastDay)
|
||||
{
|
||||
lst.Add(new ButtonBase("-", "m-" + d.Day.ToString()));
|
||||
continue;
|
||||
}
|
||||
|
||||
var day = d.Day.ToString();
|
||||
|
||||
if (d == DateTime.Today)
|
||||
{
|
||||
day = "(" + day + ")";
|
||||
}
|
||||
|
||||
lst.Add(new ButtonBase((this.SelectedDate == d ? "[" + day + "]" : day), "d-" + d.Day.ToString()));
|
||||
}
|
||||
bf.AddButtonRow(lst);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase(this.VisibleMonth.Year.ToString("0000"), "yeartitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
var months = this.Culture.DateTimeFormat.MonthNames;
|
||||
|
||||
var buttons = months.Select((a, b) => new ButtonBase((b == this.SelectedDate.Month - 1 && this.SelectedDate.Year == this.VisibleMonth.Year ? "[ " + a + " ]" : a), "m-" + (b + 1).ToString()));
|
||||
|
||||
bf.AddSplitted(buttons, 2);
|
||||
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase("Year", "yearstitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
var starti = Math.Floor(this.VisibleMonth.Year / 10f) * 10;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var m = starti + (i * 2);
|
||||
bf.AddButtonRow(new ButtonBase((this.SelectedDate.Year == m ? "[ " + m.ToString() + " ]" : m.ToString()), "y-" + m.ToString()), new ButtonBase((this.SelectedDate.Year == (m + 1) ? "[ " + (m + 1).ToString() + " ]" : (m + 1).ToString()), "y-" + (m + 1).ToString()));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Cleanup()
|
||||
{
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
await this.Device.DeleteMessage(this.MessageId.Value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class MonthPicker : CalendarPicker
|
||||
{
|
||||
|
||||
|
||||
|
||||
public MonthPicker()
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
this.EnableDayView = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
@@ -220,7 +221,7 @@ namespace TelegramBotBase.Controls
|
||||
|
||||
}
|
||||
|
||||
public async override Task Render()
|
||||
public async override Task Render(MessageResult result)
|
||||
{
|
||||
if (!this.RenderNecessary)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class ToggleButton : ControlBase
|
||||
{
|
||||
|
||||
public String UncheckedIcon { get; set; } = "⚪";
|
||||
|
||||
public String CheckedIcon { get; set; } = "⚫";
|
||||
|
||||
public String CheckedString { get; set; } = "On";
|
||||
|
||||
public String UncheckedString { get; set; } = "Off";
|
||||
|
||||
public String Title { get; set; } = "Toggle";
|
||||
|
||||
public int? MessageId { get; set; }
|
||||
|
||||
public bool Checked { get; set; }
|
||||
|
||||
private bool RenderNecessary = true;
|
||||
|
||||
private static readonly object __evToggled = new object();
|
||||
|
||||
private readonly EventHandlerList Events = new EventHandlerList();
|
||||
|
||||
|
||||
public ToggleButton()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ToggleButton(String CheckedString, String UncheckedString)
|
||||
{
|
||||
this.CheckedString = CheckedString;
|
||||
this.UncheckedString = UncheckedString;
|
||||
}
|
||||
|
||||
public event EventHandler Toggled
|
||||
{
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evToggled, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evToggled, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnToggled(EventArgs e)
|
||||
{
|
||||
(this.Events[__evToggled] as EventHandler)?.Invoke(this, e);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
|
||||
if (result.Handled)
|
||||
return;
|
||||
|
||||
await result.ConfirmAction();
|
||||
|
||||
switch (value ?? "unknown")
|
||||
{
|
||||
case "on":
|
||||
|
||||
if (this.Checked)
|
||||
return;
|
||||
|
||||
RenderNecessary = true;
|
||||
|
||||
this.Checked = true;
|
||||
|
||||
OnToggled(new EventArgs());
|
||||
|
||||
break;
|
||||
|
||||
case "off":
|
||||
|
||||
if (!this.Checked)
|
||||
return;
|
||||
|
||||
RenderNecessary = true;
|
||||
|
||||
this.Checked = false;
|
||||
|
||||
OnToggled(new EventArgs());
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
RenderNecessary = false;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
if (!RenderNecessary)
|
||||
return;
|
||||
|
||||
var bf = new ButtonForm(this);
|
||||
|
||||
ButtonBase bOn = new ButtonBase((this.Checked ? CheckedIcon : UncheckedIcon) + " " + CheckedString, "on");
|
||||
|
||||
ButtonBase bOff = new ButtonBase((!this.Checked ? CheckedIcon : UncheckedIcon) + " " + UncheckedString, "off");
|
||||
|
||||
bf.AddButtonRow(bOn, bOff);
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf, disableNotification: true);
|
||||
if (m != null)
|
||||
{
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
this.RenderNecessary = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class TreeView : ControlBase
|
||||
{
|
||||
public List<TreeViewNode> Nodes { get; set; }
|
||||
|
||||
public TreeViewNode SelectedNode { get; set; }
|
||||
|
||||
public TreeViewNode VisibleNode { get; set; }
|
||||
|
||||
public String Title { get; set; }
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public String MoveUpIcon { get; set; } = "🔼 up";
|
||||
|
||||
public TreeView()
|
||||
{
|
||||
this.Nodes = new List<TreeViewNode>();
|
||||
this.Title = "Select node";
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
await result.ConfirmAction();
|
||||
|
||||
if (result.Handled)
|
||||
return;
|
||||
|
||||
var val = result.RawData;
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case "up":
|
||||
case "parent":
|
||||
|
||||
this.VisibleNode = (this.VisibleNode?.ParentNode);
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
var n = (this.VisibleNode != null ? this.VisibleNode.FindNodeByValue(val) : this.Nodes.FirstOrDefault(a => a.Value == val));
|
||||
|
||||
if (n != null)
|
||||
{
|
||||
if (n.ChildNodes.Count > 0)
|
||||
{
|
||||
this.VisibleNode = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.SelectedNode = (this.SelectedNode != n ? n : null);
|
||||
}
|
||||
|
||||
result.Handled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
var startnode = this.VisibleNode;
|
||||
|
||||
var nodes = (startnode?.ChildNodes ?? this.Nodes);
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
if (startnode != null)
|
||||
{
|
||||
bf.AddButtonRow(new ButtonBase(this.MoveUpIcon, "up"), new ButtonBase(startnode.Text, "parent"));
|
||||
}
|
||||
|
||||
foreach (var n in nodes)
|
||||
{
|
||||
var s = n.Text;
|
||||
if (this.SelectedNode == n)
|
||||
{
|
||||
s = "[ " + s + " ]";
|
||||
}
|
||||
|
||||
bf.AddButtonRow(new ButtonBase(s, n.Value, n.Url));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public String GetPath()
|
||||
{
|
||||
return (this.VisibleNode?.GetPath() ?? "\\");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class TreeViewNode
|
||||
{
|
||||
public String Text { get; set; }
|
||||
|
||||
public String Value { get; set; }
|
||||
|
||||
public String Url { get; set; }
|
||||
|
||||
public List<TreeViewNode> ChildNodes { get; set; } = new List<TreeViewNode>();
|
||||
|
||||
public TreeViewNode ParentNode { get; set; }
|
||||
|
||||
public TreeViewNode(String Text, String Value)
|
||||
{
|
||||
this.Text = Text;
|
||||
this.Value = Value;
|
||||
}
|
||||
|
||||
public TreeViewNode(String Text, String Value, String Url) : this(Text, Value)
|
||||
{
|
||||
this.Url = Url;
|
||||
}
|
||||
|
||||
public TreeViewNode(String Text, String Value, params TreeViewNode[] childnodes) : this(Text, Value)
|
||||
{
|
||||
foreach(var c in childnodes)
|
||||
{
|
||||
AddNode(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddNode(TreeViewNode node)
|
||||
{
|
||||
node.ParentNode = this;
|
||||
ChildNodes.Add(node);
|
||||
}
|
||||
|
||||
public TreeViewNode FindNodeByValue(String Value)
|
||||
{
|
||||
return this.ChildNodes.FirstOrDefault(a => a.Value == Value);
|
||||
}
|
||||
|
||||
public String GetPath()
|
||||
{
|
||||
String s = "\\" + this.Value;
|
||||
var p = this;
|
||||
while (p.ParentNode != null)
|
||||
{
|
||||
s = "\\" + p.ParentNode.Value + s;
|
||||
p = p.ParentNode;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Enums
|
||||
{
|
||||
public enum eDeleteMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Don't delete any message.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// Delete messages on every callback/action.
|
||||
/// </summary>
|
||||
OnEveryCall = 1,
|
||||
/// <summary>
|
||||
/// Delete on leaving this form.
|
||||
/// </summary>
|
||||
OnLeavingForm = 2
|
||||
}
|
||||
|
||||
public enum eSide
|
||||
{
|
||||
/// <summary>
|
||||
/// Delete only messages from this bot.
|
||||
/// </summary>
|
||||
BotOnly = 0,
|
||||
/// <summary>
|
||||
/// Delete only user messages.
|
||||
/// </summary>
|
||||
UserOnly = 1,
|
||||
/// <summary>
|
||||
/// Delete all messages in this context.
|
||||
/// </summary>
|
||||
Both = 2
|
||||
}
|
||||
|
||||
public enum eMonthPickerMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Shows the calendar with day picker mode
|
||||
/// </summary>
|
||||
day = 0,
|
||||
/// <summary>
|
||||
/// Shows the calendar with month overview
|
||||
/// </summary>
|
||||
month = 1,
|
||||
/// <summary>
|
||||
/// Shows the calendar with year overview
|
||||
/// </summary>
|
||||
year = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Exceptions
|
||||
{
|
||||
public class MaxLengthException : Exception
|
||||
{
|
||||
public MaxLengthException(int length) : base($"Your messages with a length of {length} is too long for telegram. Actually is {Constants.Telegram.MaxMessageLength} characters allowed. Please split it.")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,14 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
public String ButtonText { get; set; }
|
||||
|
||||
public AlertDialog(String Message, String ButtonText) : base(Message)
|
||||
{
|
||||
this.Buttons.Add(new ButtonBase(ButtonText, "ok"));
|
||||
this.ButtonText = ButtonText;
|
||||
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public AlertDialog(String Message, String ButtonText, FormBase FormToOpen = null) : base(Message)
|
||||
{
|
||||
this.Buttons.Add(new ButtonBase(ButtonText, "ok"));
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public ButtonBase[][] Buttons { get; set; }
|
||||
|
||||
[Obsolete]
|
||||
public Dictionary<String, FormBase> ButtonForms { get; set; } = new Dictionary<string, FormBase>();
|
||||
|
||||
private EventHandlerList __Events { get; set; } = new EventHandlerList();
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -17,30 +18,47 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public eDeleteMode DeleteMode { get; set; }
|
||||
|
||||
public enum eDeleteMode
|
||||
{
|
||||
None = 0,
|
||||
OnEveryCall = 1,
|
||||
OnLeavingForm = 2
|
||||
}
|
||||
public eSide DeleteSide { get; set; }
|
||||
|
||||
|
||||
|
||||
public AutoCleanForm()
|
||||
{
|
||||
this.OldMessages = new List<Message>();
|
||||
this.DeleteMode = eDeleteMode.OnEveryCall;
|
||||
this.DeleteSide = eSide.BotOnly;
|
||||
|
||||
this.Init += AutoCleanForm_Init;
|
||||
|
||||
this.Closed += AutoCleanForm_Closed;
|
||||
|
||||
}
|
||||
|
||||
public override async Task Init(params object[] args)
|
||||
|
||||
private async Task AutoCleanForm_Init(object sender, InitEventArgs e)
|
||||
{
|
||||
if (this.Device == null)
|
||||
return;
|
||||
|
||||
this.Device.MessageSent += Device_MessageSent;
|
||||
|
||||
this.Device.MessageReceived += Device_MessageReceived;
|
||||
}
|
||||
|
||||
|
||||
private void Device_MessageReceived(object sender, MessageReceivedEventArgs e)
|
||||
{
|
||||
if (this.DeleteSide == eSide.BotOnly)
|
||||
return;
|
||||
|
||||
this.OldMessages.Add(e.Message);
|
||||
}
|
||||
|
||||
private void Device_MessageSent(object sender, MessageSentEventArgs e)
|
||||
{
|
||||
if (this.DeleteSide == eSide.UserOnly)
|
||||
return;
|
||||
|
||||
this.OldMessages.Add(e.Message);
|
||||
}
|
||||
|
||||
@@ -49,19 +67,11 @@ namespace TelegramBotBase.Form
|
||||
if (this.DeleteMode != eDeleteMode.OnEveryCall)
|
||||
return;
|
||||
|
||||
while (this.OldMessages.Count > 0)
|
||||
{
|
||||
if (!await this.Device.DeleteMessage(this.OldMessages[0].MessageId))
|
||||
{
|
||||
//Nachricht konnte nicht gelöscht werden, vermutlich existiert diese nicht mehr
|
||||
if (this.OldMessages.Count > 0)
|
||||
this.OldMessages.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
await MessageCleanup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fügt eine Nachricht zu der Liste der löschenden hinzu.
|
||||
/// Adds a message to this of removable ones
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void AddMessage(Message m)
|
||||
@@ -70,7 +80,7 @@ namespace TelegramBotBase.Form
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Behält die Nachricht mit der angegebenen Id.
|
||||
/// Keeps the message by removing it from the list
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void LeaveMessage(int Id)
|
||||
@@ -83,7 +93,7 @@ namespace TelegramBotBase.Form
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Behält die zuletzt gesendete Nachricht.
|
||||
/// Keeps the last sent message
|
||||
/// </summary>
|
||||
public void LeaveLastMessage()
|
||||
{
|
||||
@@ -93,14 +103,28 @@ namespace TelegramBotBase.Form
|
||||
this.OldMessages.RemoveAt(this.OldMessages.Count - 1);
|
||||
}
|
||||
|
||||
public async override Task Closed()
|
||||
private async Task AutoCleanForm_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (this.DeleteMode != eDeleteMode.OnLeavingForm)
|
||||
return;
|
||||
|
||||
foreach (var m in this.OldMessages)
|
||||
await MessageCleanup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up all remembered messages.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task MessageCleanup()
|
||||
{
|
||||
while (this.OldMessages.Count > 0)
|
||||
{
|
||||
await this.Device.DeleteMessage(m.MessageId);
|
||||
if (!await this.Device.DeleteMessage(this.OldMessages[0].MessageId))
|
||||
{
|
||||
//Message can't be deleted cause it seems not to exist anymore
|
||||
if (this.OldMessages.Count > 0)
|
||||
this.OldMessages.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -15,15 +16,36 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public String Value { get; set; }
|
||||
|
||||
public String Url { get; set; }
|
||||
|
||||
public ButtonBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ButtonBase(String Text, String Value)
|
||||
public ButtonBase(String Text, String Value, String Url = null)
|
||||
{
|
||||
this.Text = Text;
|
||||
this.Value = Value;
|
||||
this.Url = Url;
|
||||
}
|
||||
|
||||
|
||||
public InlineKeyboardButton ToInlineButton(ButtonForm form)
|
||||
{
|
||||
String id = (form.DependencyControl != null ? form.DependencyControl.ControlID + "_" : "");
|
||||
if (this.Url == null)
|
||||
{
|
||||
return InlineKeyboardButton.WithCallbackData(this.Text, id + this.Value);
|
||||
}
|
||||
|
||||
var ikb = new InlineKeyboardButton();
|
||||
|
||||
ikb.Text = this.Text;
|
||||
ikb.Url = this.Url;
|
||||
|
||||
return ikb;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -14,14 +15,24 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
List<List<ButtonBase>> Buttons = new List<List<ButtonBase>>();
|
||||
|
||||
|
||||
public IReplyMarkup Markup { get; set; }
|
||||
|
||||
public ControlBase DependencyControl { get; set; }
|
||||
|
||||
public ButtonForm()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddButtonRow(List<ButtonBase> row)
|
||||
public ButtonForm(ControlBase control)
|
||||
{
|
||||
Buttons.Add(row);
|
||||
this.DependencyControl = control;
|
||||
}
|
||||
|
||||
public void AddButtonRow(IEnumerable<ButtonBase> row)
|
||||
{
|
||||
Buttons.Add(row.ToList());
|
||||
}
|
||||
|
||||
public void AddButtonRow(params ButtonBase[] row)
|
||||
@@ -58,7 +69,7 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
var sp = SplitTo<ButtonBase>(buttons, buttonsPerRow);
|
||||
|
||||
foreach(var bl in sp)
|
||||
foreach (var bl in sp)
|
||||
{
|
||||
AddButtonRow(bl);
|
||||
}
|
||||
@@ -66,13 +77,16 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public InlineKeyboardButton[][] ToArray()
|
||||
{
|
||||
var ikb = this.Buttons.Select(a => a.Select(b => InlineKeyboardButton.WithCallbackData(b.Text, b.Value)).ToArray()).ToArray();
|
||||
var ikb = this.Buttons.Select(a => a.Select(b => b.ToInlineButton(this)).ToArray()).ToArray();
|
||||
|
||||
return ikb;
|
||||
}
|
||||
|
||||
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
|
||||
{
|
||||
if (form == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup ikm = new InlineKeyboardMarkup(form.ToArray());
|
||||
|
||||
return ikm;
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public List<ButtonBase> Buttons { get; set; }
|
||||
|
||||
[Obsolete]
|
||||
public Dictionary<String, FormBase> ButtonForms { get; set; } = new Dictionary<string, FormBase>();
|
||||
|
||||
private EventHandlerList __Events { get; set; } = new EventHandlerList();
|
||||
@@ -38,6 +39,15 @@ namespace TelegramBotBase.Form
|
||||
this.Buttons = Buttons.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds one Button
|
||||
/// </summary>
|
||||
/// <param name="button"></param>
|
||||
public void AddButton(ButtonBase button)
|
||||
{
|
||||
this.Buttons.Add(button);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
@@ -50,7 +60,6 @@ namespace TelegramBotBase.Form
|
||||
|
||||
await message.DeleteMessage();
|
||||
|
||||
|
||||
ButtonBase button = this.Buttons.FirstOrDefault(a => a.Value == call.Value);
|
||||
|
||||
if (button == null)
|
||||
@@ -73,7 +82,6 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
ButtonForm btn = new ButtonForm();
|
||||
|
||||
|
||||
var buttons = this.Buttons.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList();
|
||||
btn.AddButtonRow(buttons);
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
|
||||
namespace TelegramBotBase.Markdown
|
||||
{
|
||||
public static class Generator
|
||||
{
|
||||
public static ParseMode OutputMode { get; set; } = ParseMode.Markdown;
|
||||
|
||||
/// <summary>
|
||||
/// Generates a link with title in Markdown or HTML
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="title"></param>
|
||||
/// <param name="tooltip"></param>
|
||||
/// <returns></returns>
|
||||
public static String Link(this String url, String title = null, String tooltip = null)
|
||||
{
|
||||
switch (OutputMode)
|
||||
{
|
||||
case ParseMode.Markdown:
|
||||
return "[" + (title ?? url) + "](" + url + " " + (tooltip ?? "") + ")";
|
||||
case ParseMode.Html:
|
||||
return $"<a href=\"{url}\" title=\"{tooltip ?? ""}\">{title ?? ""}</b>";
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a Link to the User, title is optional.
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="title"></param>
|
||||
/// <returns></returns>
|
||||
public static String MentionUser(this long userId, String title = null)
|
||||
{
|
||||
return Link("tg://user?id=" + userId.ToString(), title);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a bold link in Markdown or HTML
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static String Bold(this String text)
|
||||
{
|
||||
switch (OutputMode)
|
||||
{
|
||||
case ParseMode.Markdown:
|
||||
return "**" + text + "**";
|
||||
case ParseMode.Html:
|
||||
return "<b>" + text + "</b>";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a italic link in Markdown or HTML
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static String Italic(this String text)
|
||||
{
|
||||
switch (OutputMode)
|
||||
{
|
||||
case ParseMode.Markdown:
|
||||
return "__" + text + "__";
|
||||
case ParseMode.Html:
|
||||
return "<i>" + text + "</i>";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a monospace link in Markdown or HTML
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static String Monospace(this String text)
|
||||
{
|
||||
switch (OutputMode)
|
||||
{
|
||||
case ParseMode.Markdown:
|
||||
return "`" + text + "`";
|
||||
case ParseMode.Html:
|
||||
return "<code>" + text + "</code>";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a multi monospace link in Markdown or HTML
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static String MultiMonospace(this String text)
|
||||
{
|
||||
switch (OutputMode)
|
||||
{
|
||||
case ParseMode.Markdown:
|
||||
return "```" + text + "```";
|
||||
case ParseMode.Html:
|
||||
return "<pre>" + text + "</pre>";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("TelegramBotBase Framework")]
|
||||
[assembly: AssemblyDescription("A simple addon for the original C# Telegram Bot library.")]
|
||||
[assembly: AssemblyDescription("This is a context based application framework for the C# TelegramBot library.")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Florian Dahn")]
|
||||
[assembly: AssemblyProduct("TelegramBotBase Framework")]
|
||||
@@ -32,5 +32,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("1.3.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.3.0.0")]
|
||||
[assembly: AssemblyVersion("1.5.2.0")]
|
||||
[assembly: AssemblyFileVersion("1.5.2.0")]
|
||||
|
||||
@@ -67,9 +67,9 @@ namespace TelegramBotBase
|
||||
DeviceSession ds = new Sessions.DeviceSession(deviceId, start);
|
||||
|
||||
start.Device = ds;
|
||||
await start.Init();
|
||||
await start.OnInit(new InitEventArgs());
|
||||
|
||||
await start.Opened();
|
||||
await start.OnOpened(new EventArgs());
|
||||
|
||||
this[deviceId] = ds;
|
||||
return ds;
|
||||
|
||||
@@ -13,6 +13,7 @@ using Telegram.Bot.Types.Enums;
|
||||
using Telegram.Bot.Types.InputFiles;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Exceptions;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Sessions
|
||||
@@ -27,11 +28,41 @@ namespace TelegramBotBase.Sessions
|
||||
/// </summary>
|
||||
public long DeviceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When did any last action happend (message received or button clicked)
|
||||
/// </summary>
|
||||
public DateTime LastAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the form where the user/group is at the moment.
|
||||
/// </summary>
|
||||
public FormBase ActiveForm { get; set; }
|
||||
|
||||
public int LastMessage { get; set; }
|
||||
/// <summary>
|
||||
/// Returns the previous shown form
|
||||
/// </summary>
|
||||
public FormBase PreviousForm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// contains if the form has been switched (navigated)
|
||||
/// </summary>
|
||||
public bool FormSwitched { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ID of the last received message.
|
||||
/// </summary>
|
||||
public int LastMessageId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.LastMessage?.MessageId ?? -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the last received message.
|
||||
/// </summary>
|
||||
public Message LastMessage { get; set; }
|
||||
|
||||
private MessageClient Client
|
||||
{
|
||||
@@ -41,13 +72,36 @@ namespace TelegramBotBase.Sessions
|
||||
}
|
||||
}
|
||||
|
||||
public EventHandlerList __Events = new EventHandlerList();
|
||||
/// <summary>
|
||||
/// Returns if the messages is posted within a group.
|
||||
/// </summary>
|
||||
public bool IsGroup
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.LastMessage != null && (this.LastMessage.Chat.Type == ChatType.Group | this.LastMessage.Chat.Type == ChatType.Supergroup);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if the messages is posted within a channel.
|
||||
/// </summary>
|
||||
public bool IsChannel
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.LastMessage != null && this.LastMessage.Chat.Type == ChatType.Channel;
|
||||
}
|
||||
}
|
||||
|
||||
private EventHandlerList __Events = new EventHandlerList();
|
||||
|
||||
private static object __evMessageSent = new object();
|
||||
private static object __evMessageReceived = new object();
|
||||
|
||||
public DeviceSession()
|
||||
{
|
||||
this.LastMessage = 0;
|
||||
|
||||
}
|
||||
|
||||
public DeviceSession(long DeviceId)
|
||||
@@ -74,20 +128,56 @@ namespace TelegramBotBase.Sessions
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = null;
|
||||
if (buttons != null)
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
if (text.Length > Constants.Telegram.MaxMessageLength)
|
||||
{
|
||||
markup = buttons;
|
||||
throw new MaxLengthException(text.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var m = await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, messageId, text, replyMarkup: markup);
|
||||
|
||||
return m;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Edits the text message
|
||||
/// </summary>
|
||||
/// <param name="messageId"></param>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="buttons"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> Edit(Message message, ButtonForm buttons = null)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
if (message.Text.Length > Constants.Telegram.MaxMessageLength)
|
||||
{
|
||||
throw new MaxLengthException(message.Text.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var m = await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, message.MessageId, message.Text, replyMarkup: markup);
|
||||
|
||||
return m;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -102,24 +192,27 @@ namespace TelegramBotBase.Sessions
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> Send(String text, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
|
||||
public async Task<Message> Send(String text, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = null;
|
||||
if (buttons != null)
|
||||
{
|
||||
markup = buttons;
|
||||
}
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
Message m = null;
|
||||
|
||||
if (text.Length > Constants.Telegram.MaxMessageLength)
|
||||
{
|
||||
throw new MaxLengthException(text.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -128,9 +221,6 @@ namespace TelegramBotBase.Sessions
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -142,18 +232,25 @@ namespace TelegramBotBase.Sessions
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> Send(String text, InlineKeyboardMarkup markup, int replyTo = 0, bool disableNotification = false)
|
||||
public async Task<Message> Send(String text, InlineKeyboardMarkup markup, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
Message m = null;
|
||||
|
||||
if (text.Length > Constants.Telegram.MaxMessageLength)
|
||||
{
|
||||
throw new MaxLengthException(text.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -162,7 +259,43 @@ namespace TelegramBotBase.Sessions
|
||||
return null;
|
||||
}
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a simple text message
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="markup"></param>
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> Send(String text, ReplyKeyboardMarkup markup, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
Message m = null;
|
||||
|
||||
if (text.Length > Constants.Telegram.MaxMessageLength)
|
||||
{
|
||||
throw new MaxLengthException(text.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -175,24 +308,22 @@ namespace TelegramBotBase.Sessions
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> SendPhoto(InputOnlineFile file, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
|
||||
public async Task<Message> SendPhoto(InputOnlineFile file, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = null;
|
||||
if (buttons != null)
|
||||
{
|
||||
markup = buttons;
|
||||
}
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
Message m = null;
|
||||
|
||||
try
|
||||
{
|
||||
m = await this.Client.TelegramClient.SendPhotoAsync(this.DeviceId, file, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification);
|
||||
m = await this.Client.TelegramClient.SendPhotoAsync(this.DeviceId, file, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification);
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -201,8 +332,6 @@ namespace TelegramBotBase.Sessions
|
||||
return null;
|
||||
}
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -288,7 +417,7 @@ namespace TelegramBotBase.Sessions
|
||||
|
||||
var m = await this.Client.TelegramClient.SendDocumentAsync(this.DeviceId, document, caption, replyMarkup: markup, disableNotification: disableNotification, replyToMessageId: replyTo);
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -303,6 +432,34 @@ namespace TelegramBotBase.Sessions
|
||||
await this.Client.TelegramClient.SendChatActionAsync(this.DeviceId, action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the contact from the user.
|
||||
/// </summary>
|
||||
/// <param name="buttonText"></param>
|
||||
/// <param name="requestMessage"></param>
|
||||
/// <param name="OneTimeOnly"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> RequestContact(String buttonText = "Send your contact", String requestMessage = "Give me your phone number!", bool OneTimeOnly = true)
|
||||
{
|
||||
var rck = new ReplyKeyboardMarkup(KeyboardButton.WithRequestContact(buttonText));
|
||||
rck.OneTimeKeyboard = OneTimeOnly;
|
||||
return await this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, requestMessage, replyMarkup: rck);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the location from the user.
|
||||
/// </summary>
|
||||
/// <param name="buttonText"></param>
|
||||
/// <param name="requestMessage"></param>
|
||||
/// <param name="OneTimeOnly"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> RequestLocation(String buttonText = "Send your location", String requestMessage = "Give me your location!", bool OneTimeOnly = true)
|
||||
{
|
||||
var rcl = new ReplyKeyboardMarkup(KeyboardButton.WithRequestLocation(buttonText));
|
||||
rcl.OneTimeKeyboard = OneTimeOnly;
|
||||
return await this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, requestMessage, replyMarkup: rcl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a message
|
||||
/// </summary>
|
||||
@@ -316,7 +473,7 @@ namespace TelegramBotBase.Sessions
|
||||
|
||||
return true;
|
||||
}
|
||||
catch(ApiRequestException ex)
|
||||
catch (ApiRequestException ex)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -355,5 +512,25 @@ namespace TelegramBotBase.Sessions
|
||||
(this.__Events[__evMessageSent] as EventHandler<MessageSentEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eventhandler for received messages
|
||||
/// </summary>
|
||||
public event EventHandler<MessageReceivedEventArgs> MessageReceived
|
||||
{
|
||||
add
|
||||
{
|
||||
this.__Events.AddHandler(__evMessageReceived, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.__Events.RemoveHandler(__evMessageReceived, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnMessageReceived(MessageReceivedEventArgs e)
|
||||
{
|
||||
(this.__Events[__evMessageReceived] as EventHandler<MessageReceivedEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Base\ButtonClickedEventArgs.cs" />
|
||||
<Compile Include="Base\ControlBase.cs" />
|
||||
<Compile Include="Base\DataResult.cs" />
|
||||
<Compile Include="Base\MessageClient.cs" />
|
||||
<Compile Include="Base\MessageIncomeResult.cs" />
|
||||
<Compile Include="Base\MessageResult.cs" />
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Tools
|
||||
{
|
||||
public static class Arrays
|
||||
{
|
||||
public static T[] Shift<T>(T[] array, int positions)
|
||||
{
|
||||
T[] copy = new T[array.Length];
|
||||
Array.Copy(array, 0, copy, array.Length - positions, positions);
|
||||
Array.Copy(array, positions, copy, 0, array.Length - positions);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Tools
|
||||
{
|
||||
public static class Time
|
||||
{
|
||||
public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
|
||||
{
|
||||
int diff = dt.DayOfWeek - startOfWeek;
|
||||
if (diff < 0)
|
||||
{
|
||||
diff += 7;
|
||||
}
|
||||
return dt.AddDays(-1 * diff).Date;
|
||||
}
|
||||
|
||||
public static DateTime EndOfWeek(this DateTime dt, DayOfWeek startOfWeek)
|
||||
{
|
||||
return StartOfWeek(dt, startOfWeek).AddDays(6);
|
||||
}
|
||||
|
||||
public static DateTime FirstDayOfMonth(this DateTime date)
|
||||
{
|
||||
return new DateTime(date.Year, date.Month, 1);
|
||||
}
|
||||
|
||||
public static DateTime LastDayOfMonth(this DateTime date)
|
||||
{
|
||||
return FirstDayOfMonth(date).AddMonths(1).AddDays(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 307 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 5.7 KiB |