Compare commits

...
60 Commits
Author SHA1 Message Date
FlorianDahn 7be0f15ca4 - updated readme for groups
- adding readme to project solution
2019-11-28 15:41:44 +01:00
FlorianDahn e29be4f1f4 Merge branch 'master' of https://github.com/MajMcCloud/TelegramBotFramework 2019-11-23 02:44:59 +01:00
FlorianDahn 176107300b - adding group examples for:
link replacing
   group change notifications
   welcoming users
2019-11-23 02:44:50 +01:00
FlorianDahn 0ceab58059 - updating namespaces in test project
- adding chat splitter to testproject to allow single chat and group chat examples at the same time
2019-11-23 02:44:05 +01:00
FlorianDahn 6ebdd9f208 - additional stuff for group management 2019-11-23 02:41:17 +01:00
FlorianDahn 595efd2276 - adding base class for group management 2019-11-23 02:40:51 +01:00
FlorianDahn 85a479d826 - adding useful tasks for groups 2019-11-23 02:40:25 +01:00
FlorianDahn 150e9f731d - addes SplitterForm to switch between "normal" chats and group chats 2019-11-23 02:39:56 +01:00
FlorianDahn 0eab45bdbb - making Events property of FormBase public, for use in sub classes
- making ResultBase derive from Eventargs
- adding messagetype to messageresult
2019-11-21 21:38:20 +01:00
Florian Dahn a33cf5b841 Create dotnetcore.yml 2019-11-14 22:58:50 +01:00
FlorianDahn 1f9539a23d - updating readme 2019-10-11 22:38:50 +02:00
FlorianDahn 9cbde4830e - adding OpenModal/CloseModal features to leave a form open and "just" show a prompt and get back
- added new "ModalDialog" class to present modal forms
- updating examples for prompt dialog to use the modal feature
2019-10-11 22:37:54 +02:00
FlorianDahn 3bea2783b1 - updated Readme 2019-10-11 21:41:02 +02:00
FlorianDahn 038a941d33 - PromptDialog has been changed to ConfirmDialog
- PromptDialog is now (like in JavaScript) for text inputs
- examples corrected
2019-10-11 21:33:33 +02:00
FlorianDahn 48c62e57f8 - moving TelegramBaseTest to TelegramBotBaseTest 2019-09-29 00:47:18 +02:00
FlorianDahn b0e6a8b981 -migrate from .net 4.7.2 to .Net standard 2.0 for the library and .Net core 3.0 for the example project 2019-09-28 14:06:19 +02:00
FlorianDahn 2e0656dc06 - update readme 2019-09-28 01:19:55 +02:00
FlorianDahn d1456d5bd1 - update readme and formbase 2019-09-28 01:17:38 +02:00
FlorianDahn 058539777f - removing obsolete Property and methods
- updating test project
2019-09-27 23:24:31 +02:00
FlorianDahn 5c69289198 - small additions 2019-09-27 23:18:18 +02:00
FlorianDahn 4c8b085655 - small cleanup 2019-09-27 23:14:28 +02:00
FlorianDahn 94d22318f8 - change SetKeyboardType method to Property 2019-09-27 23:08:55 +02:00
FlorianDahn 2028e2f9e6 - adding ButtonGrid control to Readme 2019-09-27 21:26:43 +02:00
FlorianDahn 394209b303 updating both projects to .Net 4.7.2 2019-09-27 00:01:20 +02:00
FlorianDahn f0fa953819 Updating csproj Files 2019-09-26 23:27:38 +02:00
FlorianDahn 1d44b50883 - small change 2019-09-26 20:57:51 +02:00
FlorianDahn 3c21af8f68 - small change and adding comments 2019-09-26 20:57:16 +02:00
FlorianDahn 1b811e1786 - added ToKeyboardButton to ButtonBase
- added eKeyboardType to switch between Inline and KeykboardButtons
- addes some small functions to ButtonForm
- added new control "ButtonGrid" which manages Button handling with Event Handler for each Button and can switch between InlineMode and KeyboardMode during runtime
- added also Examples to it
2019-09-26 20:54:35 +02:00
FlorianDahn 94195ec5bf - added another Edit Method for InlineKeyboardMarkup
- change Send method parameter ReplyKeyboardMarkup to ReplyMarkupBase to allow also RemoveKeyboard
2019-09-26 20:51:30 +02:00
FlorianDahn 256cac825f - adding Load method for controls 2019-09-26 20:50:33 +02:00
FlorianDahn 69e5a6717b - Splitting enums into single files for more structure
- remove old Enum file
2019-09-26 17:14:12 +02:00
FlorianDahn a6d22cdd82 Update version 2019-09-17 16:44:14 +02:00
FlorianDahn ee4a3d765c Merge branch 'master' of https://github.com/MajMcCloud/TelegramBotFramework 2019-09-17 16:43:10 +02:00
FlorianDahn 703c99eb8d - added a custom exception for maximum length messages, saves to time to sent to API
- added a constants file, for have constants to work with
- catching maximum message length
2019-09-17 16:43:02 +02:00
Florian Dahn 138fee9772 Update README.md
adding paypal
2019-09-17 16:33:51 +02:00
Florian Dahn d60399514f Update README.md 2019-09-04 15:13:42 +02:00
FlorianDahn ae0fa3b0e3 Added simple Markdown/HTML Generator
Use with:

"Bold Text".Bold();

"Other text".Italic();

"www.google.de".Link("Google")
2019-08-28 17:33:18 +02:00
FlorianDahn 6a2ac7a309 Added simple Markdown/HTML Generator
Use with:

"Bold Text".Bold();

"Other text".Italic();

"www.google.de".AsLink("Google")
2019-08-28 17:32:08 +02:00
FlorianDahn 1a76b2b3f8 added some forms to obsolete, cause their use is bad for ram management 2019-08-26 01:34:50 +02:00
FlorianDahn 5893108bd3 Update readme 2019-08-23 14:55:54 +02:00
FlorianDahn d668f57711 Update readme 2019-08-23 14:53:24 +02:00
FlorianDahn 56c7754408 - Added ToggleButton as an easy switch control (i.e. for settings page)
- added control id, for easier separating of controls in one form
- added automatic event selection for specific controls, to not raise an event for other controls who has invoked it
- changed Action method
- added example
2019-08-23 14:02:24 +02:00
FlorianDahn 805ffb9ec7 Update version 2019-07-15 13:33:01 +02:00
FlorianDahn aeddd82ea9 Merge branch 'master' of https://github.com/MajMcCloud/TelegramBotFramework 2019-07-15 13:31:07 +02:00
FlorianDahn 1ec14ce680 Updating nuget packages 2019-07-15 13:31:02 +02:00
Florian Dahn 3a309baeae Update README.md 2019-07-14 23:14:37 +02:00
FlorianDahn e02af0fc76 Merge branch 'master' of https://github.com/MajMcCloud/TelegramBotFramework 2019-07-14 23:13:19 +02:00
FlorianDahn 530e01f971 new images 2019-07-14 23:13:16 +02:00
Florian Dahn dcf3cf804f Update README.md 2019-07-14 23:00:06 +02:00
Florian Dahn a42d3934b5 Update README.md 2019-07-14 22:52:59 +02:00
Florian Dahn 2126b45fed Update README.md 2019-07-14 22:47:04 +02:00
FlorianDahn b6b9d5b6b1 Update images 2019-07-14 22:46:29 +02:00
FlorianDahn eed5f012dc adding images for example 2019-07-14 22:38:10 +02:00
FlorianDahn de4cc138ae - New control: CalendarPicker
- New control: MonthPicker
- New control TreeView
- adding examples for all 3
- small change on Progress Bar Control
- due latest changes on the base it is now easier to create controls which will be rendered (or not)in several forms depending on user context
2019-07-14 22:27:16 +02:00
FlorianDahn e4da70d37d - Update of FormBase for better async event management
- Update of ControlBase for partial rendering options
- Updating serveral base classes to better asyc event management
- separating Enums into different folder
- some small bug fixes
- removed "CustomEventManagement" cause it doesnt make sense now
2019-07-14 22:22:04 +02:00
FlorianDahn cb4a797b12 Updating ButtonBase to enable Url Buttons 2019-07-14 22:13:23 +02:00
FlorianDahn 94d153e141 Merge branch 'master' of https://github.com/MajMcCloud/TelegramBotFramework 2019-06-26 12:48:37 +02:00
FlorianDahn e13cb6d4ef - Updating NavigateTo to set PreviousForm now correctly 2019-06-26 12:48:25 +02:00
Florian Dahn c0e285d39e Update README.md 2019-06-24 13:50:55 +02:00
Florian Dahn 8338c5c066 Update README.md 2019-06-24 13:49:37 +02:00
93 changed files with 3409 additions and 507 deletions
+17
View File
@@ -0,0 +1,17 @@
name: .NET Core
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 2.2.108
- name: Build with dotnet
run: dotnet build --configuration Release
+233 -19
View File
@@ -1,4 +1,5 @@
# .Net Telegram Bot Framework - Context based addon
[![NuGet version (TelegramBotBase)](https://img.shields.io/nuget/v/TelegramBotBase.svg?style=flat-square)](https://www.nuget.org/packages/TelegramBotBase/)
@@ -12,6 +13,25 @@ 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
Thanks !
---
## Index
@@ -36,6 +56,26 @@ Join the Telegram Group: [https://www.t.me/tgbotbase](https://www.t.me/tgbotbase
* [PromptDialog](#prompt-dialog)
* [ConfirmDialog](#confirm-dialog)
- [Controls](#controls)
* [ProgressBar](#progress-bar)
* [CalendarPicker](#calendar-picker)
* [MonthPicker](#month-picker)
* [TreeView](#tree-view)
* [ToggleButton](#toggle-button)
* [ButtonGrid](#button-grid)
- [Groups](#groups)
* [SplitterForm](#splitter-form)
* [GroupForm](#group-form)
---
@@ -219,7 +259,7 @@ 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 : AutoCleanForm
@@ -274,6 +314,7 @@ public class SimpleForm : AutoCleanForm
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
@@ -351,6 +392,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);
@@ -366,6 +409,8 @@ 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
@@ -500,6 +545,14 @@ public override async Task Closed()
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
@@ -618,15 +671,24 @@ For now we have the following:
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 will show a message and then waits for a text input (response).
- [ConfirmDialog](#confirm-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");
AlertDialog ad = new AlertDialog("This is a message", "Ok", fto);
ad.ButtonClicked += async (s, en) =>
{
var fto = new TestForm2();
await this.NavigateTo(fto);
};
await this.NavigateTo(ad);
@@ -635,47 +697,199 @@ await this.NavigateTo(ad);
### AutoCleanForm
No example yet
### Prompt Dialog
#### Without Eventhandler (pre-init of form necessary)
<img src="images/promptdialog.PNG" />
```
PromptDialog pd = new PromptDialog("Please confirm");
PromptDialog pd = new PromptDialog("Please tell me your name ?");
pd.AddButton(new ButtonBase("Ok", "ok"));
pd.AddButton(new ButtonBase("Cancel", "cancel"));
pd.Completed += async (s, en) =>
{
await this.Device.Send("Hello " + pd.Value);
};
var tf = new TestForm2();
pd.ButtonForms.Add("ok", tf);
pd.ButtonForms.Add("cancel", tf);
await this.NavigateTo(pd);
await this.OpenModal(pd);
```
### Confirm Dialog
<img src="images/confirmdialog.PNG" />
#### With Eventhandler (no pre-init of form necessary)
```
PromptDialog pd = new PromptDialog("Please confirm", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
ConfirmDialog cd = new ConfirmDialog("Please confirm", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
pd.ButtonClicked += async (s, en) =>
cd.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 cd.NavigateTo(tf);
};
await this.NavigateTo(pd);
await this.NavigateTo(cd);
```
## 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" />
### Button Grid
<img src="images/buttongrid.gif?raw=true" />
## Groups
For working with groups, there are multiple different tools which helps to work with and allows bot also to manage "Single-User" chats and group chats.
### Splitter Form
An easy way to switch between a "Single-User" form and one for managing a group is the SplitterForm base class.
It calls special methods which you can override and then move from there to the form you need.
The OpenGroup method is the "backup" if OpenChannel or OpenSupergroup is not overridden. Same for Open, it is "backup" if none of the previous methods has been overridden.
```
public class Start : SplitterForm
{
public override async Task<bool> Open(MessageResult e)
{
var st = new Menu();
await this.NavigateTo(st);
return true;
}
public override async Task<bool> OpenGroup(MessageResult e)
{
var st = new Groups.LinkReplaceTest();
await this.NavigateTo(st);
return true;
}
public override Task<bool> OpenChannel(MessageResult e)
{
return base.OpenChannel(e);
}
public override Task<bool> OpenSupergroup(MessageResult e)
{
return base.OpenSupergroup(e);
}
}
```
### Group Form
For managing groups im introducing a new base class called "GroupForm". This one has special events which should make it easier to work with groups and channels.
In the Example project is a simple example for deleting a url written by a user and incrementing an internal counter. At every url he writes he got blocked for a small amount of time and the messages gots deleted. At 3 "failes" the user gets kicked of the group and blocked.
```
public class GroupForm : FormBase
{
public override async Task Load(MessageResult message)
{
switch (message.MessageType)
{
case Telegram.Bot.Types.Enums.MessageType.ChatMembersAdded:
await OnMemberChanges(new MemberChangeEventArgs(Telegram.Bot.Types.Enums.MessageType.ChatMembersAdded, message, message.RawMessageData.Message.NewChatMembers));
break;
case Telegram.Bot.Types.Enums.MessageType.ChatMemberLeft:
await OnMemberChanges(new MemberChangeEventArgs(Telegram.Bot.Types.Enums.MessageType.ChatMemberLeft, message, message.RawMessageData.Message.LeftChatMember));
break;
case Telegram.Bot.Types.Enums.MessageType.ChatPhotoChanged:
case Telegram.Bot.Types.Enums.MessageType.ChatPhotoDeleted:
case Telegram.Bot.Types.Enums.MessageType.ChatTitleChanged:
case Telegram.Bot.Types.Enums.MessageType.MigratedFromGroup:
case Telegram.Bot.Types.Enums.MessageType.MigratedToSupergroup:
case Telegram.Bot.Types.Enums.MessageType.MessagePinned:
case Telegram.Bot.Types.Enums.MessageType.GroupCreated:
case Telegram.Bot.Types.Enums.MessageType.SupergroupCreated:
await OnGroupChanged(new GroupChangedEventArgs(message.MessageType, message));
break;
default:
OnMessage(message);
break;
}
}
public virtual async Task OnMemberChanges(MemberChangeEventArgs e)
{
}
public virtual async Task OnGroupChanged(GroupChangedEventArgs e)
{
}
public virtual async Task OnMessage(MessageResult e)
{
}
}
```
---
I will add more notes to it soon, so stay tuned.
-81
View File
@@ -1,81 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase;
using TelegramBotBase.Form;
using TelegramBaseTest.Tests;
namespace TelegramBaseTest
{
class Program
{
static void Main(string[] args)
{
String APIKey = "{YOUR API KEY}";
BotBase<Start> bb = new BotBase<Start>(APIKey);
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();
await en.Device.ActiveForm.NavigateTo(form1);
break;
case "/form2":
var form2 = new TestForm2();
await en.Device.ActiveForm.NavigateTo(form2);
break;
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);
en.Handled = true;
break;
}
};
bb.Start();
Console.WriteLine("Telegram Bot started...");
Console.WriteLine("Press q to quit application.");
Console.ReadLine();
bb.Stop();
}
}
}
-93
View File
@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5817184C-0D59-4924-AC6C-6B943967811C}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TelegramBaseTest</RootNamespace>
<AssemblyName>TelegramBaseTest</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Telegram.Bot, Version=14.10.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Telegram.Bot.14.10.0\lib\net45\Telegram.Bot.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<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" />
<Compile Include="Tests\Register\Start.cs" />
<Compile Include="Tests\Register\Steps\Data.cs" />
<Compile Include="Tests\Register\Steps\Step3.cs" />
<Compile Include="Tests\Register\Steps\Step2.cs" />
<Compile Include="Tests\Register\Steps\Step1.cs" />
<Compile Include="Tests\SimpleForm.cs" />
<Compile Include="Tests\Start.cs" />
<Compile Include="Tests\TestForm.cs" />
<Compile Include="Tests\TestForm2.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config">
<SubType>Designer</SubType>
</None>
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TelegramBotBase\TelegramBotBase.csproj">
<Project>{a61eda27-cfdf-4bcb-b2d6-184f94904f2d}</Project>
<Name>TelegramBotBase</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+25
View File
@@ -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)));
}
}
+36 -1
View File
@@ -13,8 +13,43 @@ 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 Load(MessageResult result)
{
}
public virtual async Task Action(MessageResult result, String value = null)
{
}
public virtual async Task Render(MessageResult result)
{
}
+253 -15
View File
@@ -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,12 +15,11 @@ 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>
/// has this formular already been disposed ?
/// </summary>
@@ -26,34 +27,120 @@ namespace TelegramBotBase.Form
public List<ControlBase> Controls { get; set; }
public 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;
}
/// <summary>
/// Will get called at the initialization (once per context)
/// </summary>
public virtual async Task Init(params object[] args)
{
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>
/// Gets invoked if gets navigated to this form
/// </summary>
/// <returns></returns>
public virtual async Task Opened()
public event AsyncEventHandler<EventArgs> Opened
{
add
{
this.Events.AddHandler(__evOpened, value);
}
remove
{
this.Events.RemoveHandler(__evOpened, value);
}
}
public virtual async Task Closed()
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);
}
}
/// <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)
{
@@ -66,6 +153,33 @@ namespace TelegramBotBase.Form
}
/// <summary>
/// Gets invoked if a message was sent or an action triggered
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public async Task LoadControls(MessageResult message)
{
//Looking for the control by id, if not listened, raise event for all
if (message.RawData?.StartsWith("#c") ?? false)
{
var c = this.Controls.FirstOrDefault(a => a.ControlID == message.RawData.Split('_')[0]);
if (c != null)
{
await c.Load(message);
return;
}
}
foreach (var b in this.Controls)
{
if (!b.Enabled)
continue;
await b.Load(message);
}
}
/// <summary>
/// Gets invoked if the form gets loaded and on every message belongs to this context
/// </summary>
@@ -76,6 +190,38 @@ namespace TelegramBotBase.Form
}
/// <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);
if (message.Handled)
return;
}
}
/// <summary>
/// Gets invoked if the user has clicked a button.
/// </summary>
@@ -96,6 +242,22 @@ namespace TelegramBotBase.Form
}
/// <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>
@@ -106,6 +268,8 @@ namespace TelegramBotBase.Form
}
/// <summary>
/// Navigates to a new form
/// </summary>
@@ -119,17 +283,91 @@ namespace TelegramBotBase.Form
ds.FormSwitched = true;
ds.PreviousForm = ds.ActiveForm;
ds.ActiveForm = newForm;
newForm.Client = this.Client;
newForm.Device = ds;
ds.PreviousForm = this;
await newForm.OnInit(new InitEventArgs(args));
await newForm.Init(args);
await this.CloseControls();
await this.Closed();
await this.OnClosed(new EventArgs());
await newForm.Opened();
await newForm.OnOpened(new EventArgs());
}
/// <summary>
/// Opens this form modal, but don't closes the original ones
/// </summary>
/// <param name="newForm"></param>
/// <returns></returns>
public async Task OpenModal(ModalDialog newForm, params object[] args)
{
DeviceSession ds = this.Device;
if (ds == null)
return;
var parentForm = this;
ds.FormSwitched = true;
ds.PreviousForm = ds.ActiveForm;
ds.ActiveForm = newForm;
newForm.Client = parentForm.Client;
newForm.Device = ds;
newForm.Closed += async (s, en) =>
{
await CloseModal(newForm, parentForm);
};
await newForm.OnInit(new InitEventArgs(args));
await newForm.OnOpened(new EventArgs());
}
public async Task CloseModal(ModalDialog modalForm, FormBase oldForm)
{
DeviceSession ds = this.Device;
if (ds == null)
return;
if (modalForm == null)
throw new Exception("No modal form");
ds.FormSwitched = true;
ds.PreviousForm = ds.ActiveForm;
ds.ActiveForm = oldForm;
}
/// <summary>
/// Adds a control to the formular and sets its ID and Device.
/// </summary>
/// <param name="control"></param>
public void AddControl(ControlBase control)
{
control.ID = this.Controls.Count + 1;
control.Device = this.Device;
this.Controls.Add(control);
}
/// <summary>
/// Removes control from the formular and runs a cleanup on it.
/// </summary>
/// <param name="control"></param>
public void RemoveControl(ControlBase control)
{
if (!this.Controls.Contains(control))
return;
control.Cleanup().Wait();
this.Controls.Remove(control);
}
/// <summary>
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
using Telegram.Bot.Types.Enums;
namespace TelegramBotBase.Base
{
public class GroupChangedEventArgs : EventArgs
{
public MessageType Type { get; set; }
public MessageResult OriginalMessage { get; set; }
public GroupChangedEventArgs(MessageType type, MessageResult message)
{
this.Type = type;
this.OriginalMessage = message;
}
}
}
+18
View File
@@ -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;
}
}
}
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
namespace TelegramBotBase.Base
{
public class MemberChangeEventArgs : EventArgs
{
public List<User> Members { get; set; }
public MessageType Type { get; set; }
public MessageResult Result { get; set; }
public MemberChangeEventArgs()
{
this.Members = new List<User>();
}
public MemberChangeEventArgs(MessageType type, MessageResult result, params User[] members)
{
this.Type = type;
this.Result = result;
this.Members = members.ToList();
}
}
}
+8
View File
@@ -54,6 +54,14 @@ namespace TelegramBotBase.Base
}
}
public Telegram.Bot.Types.Enums.MessageType MessageType
{
get
{
return this.RawMessageData?.Message?.Type ?? Telegram.Bot.Types.Enums.MessageType.Unknown;
}
}
/// <summary>
/// Is this an action ? (i.e. button click)
/// </summary>
+1 -1
View File
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace TelegramBotBase.Base
{
public class ResultBase
public class ResultBase : EventArgs
{
public MessageClient Client { get; set; }
+23 -8
View File
@@ -175,6 +175,9 @@ namespace TelegramBotBase
if (this.Client == null)
return;
this.Client.Message -= Client_Message;
this.Client.Action -= Client_Action;
this.Client.TelegramClient.StopReceiving();
}
@@ -264,13 +267,12 @@ namespace TelegramBotBase
activeForm = ds.ActiveForm;
//If the form manages the events by itselfs, skip here
if (activeForm.CustomEventManagement)
return;
//Pre Loading Event
await activeForm.PreLoad(e);
//Send Load event to controls
await activeForm.LoadControls(e);
//Loading Event
await activeForm.Load(e);
@@ -283,7 +285,13 @@ namespace TelegramBotBase
//Render Event
if (!ds.FormSwitched)
{
await activeForm.RenderControls(e);
await activeForm.Render(e);
}
} while (ds.FormSwitched && i < NavigationMaximum);
@@ -337,19 +345,22 @@ namespace TelegramBotBase
activeForm = ds.ActiveForm;
//If the form manages the events by itselfs, skip here
if (activeForm.CustomEventManagement)
return;
//Pre Loading Event
await activeForm.PreLoad(e);
//Send Load event to controls
await activeForm.LoadControls(e);
//Loading Event
await activeForm.Load(e);
//Action Event
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)
@@ -374,7 +385,11 @@ namespace TelegramBotBase
//Render Event
if (!ds.FormSwitched)
{
await activeForm.RenderControls(e);
await activeForm.Render(e);
}
} while (ds.FormSwitched && i < NavigationMaximum);
+17
View File
@@ -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;
}
}
+205
View File
@@ -0,0 +1,205 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Telegram.Bot.Types;
using Telegram.Bot.Types.ReplyMarkups;
using TelegramBotBase.Base;
using TelegramBotBase.Enums;
using TelegramBotBase.Form;
namespace TelegramBotBase.Controls
{
public class ButtonGrid : Base.ControlBase
{
public String Title { get; set; } = "Toggle";
private bool RenderNecessary = true;
private static readonly object __evButtonClicked = new object();
private readonly EventHandlerList Events = new EventHandlerList();
public ButtonForm ButtonsForm { get; set; }
public int? MessageId { get; set; }
/// <summary>
/// Defines which type of Button Keyboard should be rendered.
/// </summary>
public eKeyboardType KeyboardType
{
get
{
return m_eKeyboardType;
}
set
{
if(m_eKeyboardType != value)
{
this.RenderNecessary = true;
Cleanup().Wait();
m_eKeyboardType = value;
}
}
}
private eKeyboardType m_eKeyboardType = eKeyboardType.ReplyKeyboard;
private bool m_bVisible = true;
public ButtonGrid()
{
this.ButtonsForm = new ButtonForm();
}
public ButtonGrid(ButtonForm form)
{
this.ButtonsForm = form;
}
public event EventHandler<ButtonClickedEventArgs> ButtonClicked
{
add
{
this.Events.AddHandler(__evButtonClicked, value);
}
remove
{
this.Events.RemoveHandler(__evButtonClicked, value);
}
}
public void OnButtonClicked(ButtonClickedEventArgs e)
{
(this.Events[__evButtonClicked] as EventHandler<ButtonClickedEventArgs>)?.Invoke(this, e);
}
public async override Task Load(MessageResult result)
{
if (this.KeyboardType != eKeyboardType.ReplyKeyboard)
return;
var button = ButtonsForm.ToList().FirstOrDefault(a => a.Text == result.MessageText);
if (button == null)
return;
OnButtonClicked(new ButtonClickedEventArgs(button));
result.Handled = true;
}
public async override Task Action(MessageResult result, string value = null)
{
if (result.Handled)
return;
await result.ConfirmAction();
//Find clicked button depending on Text or Value (depending on markup type)
switch (this.KeyboardType)
{
case eKeyboardType.InlineKeyBoard:
var button = ButtonsForm.ToList().FirstOrDefault(a => a.Value == result.RawData);
if (button == null)
return;
OnButtonClicked(new ButtonClickedEventArgs(button));
result.Handled = true;
break;
}
}
public async override Task Render(MessageResult result)
{
if (!this.RenderNecessary)
return;
Message m = null;
if (this.MessageId != null)
{
switch (this.KeyboardType)
{
//Reply Keyboard could only be updated with a new keyboard.
case eKeyboardType.ReplyKeyboard:
if (this.ButtonsForm.Count == 0)
{
await this.Device.Send("", new ReplyKeyboardRemove());
this.MessageId = null;
}
else
{
m = await this.Device.Send(this.Title, (ReplyKeyboardMarkup)this.ButtonsForm, disableNotification: true);
}
break;
case eKeyboardType.InlineKeyBoard:
m = await this.Device.Edit(this.MessageId.Value, this.Title, (InlineKeyboardMarkup)this.ButtonsForm);
break;
}
}
else
{
switch (this.KeyboardType)
{
case eKeyboardType.ReplyKeyboard:
m = await this.Device.Send(this.Title, (ReplyKeyboardMarkup)this.ButtonsForm, disableNotification: true);
break;
case eKeyboardType.InlineKeyBoard:
m = await this.Device.Send(this.Title, (InlineKeyboardMarkup)this.ButtonsForm, disableNotification: true);
break;
}
if (m != null)
{
this.MessageId = m.MessageId;
}
}
this.RenderNecessary = false;
}
public async override Task Cleanup()
{
if (this.MessageId == null)
return;
await this.Device.DeleteMessage(this.MessageId.Value);
this.MessageId = null;
if (this.KeyboardType == eKeyboardType.ReplyKeyboard)
{
await this.Device.Send("", new ReplyKeyboardRemove());
}
}
}
}
+277
View File
@@ -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);
}
}
}
}
+26
View File
@@ -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;
}
}
}
+2 -1
View File
@@ -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)
{
+145
View File
@@ -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;
}
}
}
+120
View File
@@ -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() ?? "\\");
}
}
}
+65
View File
@@ -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;
}
}
}
+24
View File
@@ -0,0 +1,24 @@
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
}
}
+24
View File
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TelegramBotBase.Enums
{
public enum eDeleteSide
{
/// <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
}
}
+22
View File
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TelegramBotBase.Enums
{
public enum eKeyboardType
{
/// <summary>
/// Uses a ReplyKeyboardMarkup
/// </summary>
ReplyKeyboard = 0,
/// <summary>
/// Uses a InlineKeyboardMakup
/// </summary>
InlineKeyBoard = 1
}
}
+24
View File
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TelegramBotBase.Enums
{
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.")
{
}
}
}
+2 -4
View File
@@ -11,17 +11,15 @@ namespace TelegramBotBase.Form
/// <summary>
/// A simple prompt dialog with one ok Button
/// </summary>
public class AlertDialog : PromptDialog
public class AlertDialog : ConfirmDialog
{
public String ButtonText { get; set; }
public AlertDialog(String Message, String ButtonText, FormBase FormToOpen = null) : base(Message)
public AlertDialog(String Message, String ButtonText) : base(Message)
{
this.Buttons.Add(new ButtonBase(ButtonText, "ok"));
this.ButtonText = ButtonText;
if (FormToOpen != null)
this.ButtonForms.Add("ok", FormToOpen);
}
}
@@ -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();
+12 -37
View File
@@ -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,49 +18,24 @@ namespace TelegramBotBase.Form
public eDeleteMode DeleteMode { get; set; }
public eSide DeleteSide { get; set; }
public eDeleteSide DeleteSide { get; set; }
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 AutoCleanForm()
{
this.OldMessages = new List<Message>();
this.DeleteMode = eDeleteMode.OnEveryCall;
this.DeleteSide = eSide.BotOnly;
this.DeleteSide = eDeleteSide.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;
@@ -72,7 +48,7 @@ namespace TelegramBotBase.Form
private void Device_MessageReceived(object sender, MessageReceivedEventArgs e)
{
if (this.DeleteSide == eSide.BotOnly)
if (this.DeleteSide == eDeleteSide.BotOnly)
return;
this.OldMessages.Add(e.Message);
@@ -80,7 +56,7 @@ namespace TelegramBotBase.Form
private void Device_MessageSent(object sender, MessageSentEventArgs e)
{
if (this.DeleteSide == eSide.UserOnly)
if (this.DeleteSide == eDeleteSide.UserOnly)
return;
this.OldMessages.Add(e.Message);
@@ -127,7 +103,7 @@ 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;
@@ -135,7 +111,6 @@ namespace TelegramBotBase.Form
await MessageCleanup();
}
/// <summary>
/// Cleans up all remembered messages.
/// </summary>
+39 -1
View File
@@ -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,52 @@ 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;
}
/// <summary>
/// Returns an inline Button
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Returns a KeyBoardButton
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
public KeyboardButton ToKeyboardButton(ButtonForm form)
{
return new KeyboardButton(this.Text);
}
}
+50 -6
View File
@@ -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)
@@ -49,6 +60,14 @@ namespace TelegramBotBase.Form
return splitted;
}
public int Count
{
get
{
return this.Buttons.Select(a => a.ToArray()).Aggregate((a, b) => a.Union(b).ToArray()).Length;
}
}
/// <summary>
/// Add buttons splitted in the amount of columns (i.e. 2 per row...)
/// </summary>
@@ -58,22 +77,47 @@ namespace TelegramBotBase.Form
{
var sp = SplitTo<ButtonBase>(buttons, buttonsPerRow);
foreach(var bl in sp)
foreach (var bl in sp)
{
AddButtonRow(bl);
}
}
public InlineKeyboardButton[][] ToArray()
public List<ButtonBase> ToList()
{
var ikb = this.Buttons.Select(a => a.Select(b => InlineKeyboardButton.WithCallbackData(b.Text, b.Value)).ToArray()).ToArray();
return this.Buttons.Aggregate((a, b) => a.Union(b).ToList());
}
public InlineKeyboardButton[][] ToInlineButtonArray()
{
var ikb = this.Buttons.Select(a => a.Select(b => b.ToInlineButton(this)).ToArray()).ToArray();
return ikb;
}
public KeyboardButton[][] ToReplyButtonArray()
{
var ikb = this.Buttons.Select(a => a.Select(b => b.ToKeyboardButton(this)).ToArray()).ToArray();
return ikb;
}
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
{
InlineKeyboardMarkup ikm = new InlineKeyboardMarkup(form.ToArray());
if (form == null)
return null;
InlineKeyboardMarkup ikm = new InlineKeyboardMarkup(form.ToInlineButtonArray());
return ikm;
}
public static implicit operator ReplyKeyboardMarkup(ButtonForm form)
{
if (form == null)
return null;
ReplyKeyboardMarkup ikm = new ReplyKeyboardMarkup(form.ToReplyButtonArray());
return ikm;
}
+100
View File
@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
namespace TelegramBotBase.Form
{
public class ConfirmDialog : ModalDialog
{
public String Message { get; set; }
public List<ButtonBase> Buttons { get; set; }
private EventHandlerList __Events { get; set; } = new EventHandlerList();
private static object __evButtonClicked { get; } = new object();
public ConfirmDialog()
{
}
public ConfirmDialog(String Message)
{
this.Message = Message;
this.Buttons = new List<Form.ButtonBase>();
}
public ConfirmDialog(String Message, params ButtonBase[] Buttons)
{
this.Message = Message;
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>();
if (call == null)
return;
message.Handled = true;
await message.ConfirmAction();
await message.DeleteMessage();
ButtonBase button = this.Buttons.FirstOrDefault(a => a.Value == call.Value);
if (button == null)
{
return;
}
OnButtonClicked(new ButtonClickedEventArgs(button));
}
public override async Task Render(MessageResult message)
{
ButtonForm btn = new ButtonForm();
var buttons = this.Buttons.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList();
btn.AddButtonRow(buttons);
await this.Device.Send(this.Message, btn);
}
public event EventHandler<ButtonClickedEventArgs> ButtonClicked
{
add
{
this.__Events.AddHandler(__evButtonClicked, value);
}
remove
{
this.__Events.RemoveHandler(__evButtonClicked, value);
}
}
public void OnButtonClicked(ButtonClickedEventArgs e)
{
(this.__Events[__evButtonClicked] as EventHandler<ButtonClickedEventArgs>)?.Invoke(this, e);
}
}
}
+76
View File
@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using static TelegramBotBase.Base.Async;
namespace TelegramBotBase.Form
{
public class GroupForm : FormBase
{
public GroupForm()
{
}
public override async Task Load(MessageResult message)
{
switch (message.MessageType)
{
case Telegram.Bot.Types.Enums.MessageType.ChatMembersAdded:
await OnMemberChanges(new MemberChangeEventArgs(Telegram.Bot.Types.Enums.MessageType.ChatMembersAdded, message, message.RawMessageData.Message.NewChatMembers));
break;
case Telegram.Bot.Types.Enums.MessageType.ChatMemberLeft:
await OnMemberChanges(new MemberChangeEventArgs(Telegram.Bot.Types.Enums.MessageType.ChatMemberLeft, message, message.RawMessageData.Message.LeftChatMember));
break;
case Telegram.Bot.Types.Enums.MessageType.ChatPhotoChanged:
case Telegram.Bot.Types.Enums.MessageType.ChatPhotoDeleted:
case Telegram.Bot.Types.Enums.MessageType.ChatTitleChanged:
case Telegram.Bot.Types.Enums.MessageType.MigratedFromGroup:
case Telegram.Bot.Types.Enums.MessageType.MigratedToSupergroup:
case Telegram.Bot.Types.Enums.MessageType.MessagePinned:
case Telegram.Bot.Types.Enums.MessageType.GroupCreated:
case Telegram.Bot.Types.Enums.MessageType.SupergroupCreated:
await OnGroupChanged(new GroupChangedEventArgs(message.MessageType, message));
break;
default:
OnMessage(message);
break;
}
}
public virtual async Task OnMemberChanges(MemberChangeEventArgs e)
{
}
public virtual async Task OnGroupChanged(GroupChangedEventArgs e)
{
}
public virtual async Task OnMessage(MessageResult e)
{
}
}
}
+24
View File
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace TelegramBotBase.Form
{
public class ModalDialog : FormBase
{
/// <summary>
/// This is a modal only function and does everything to close this form.
/// </summary>
public async Task CloseForm()
{
await this.CloseControls();
await this.OnClosed(new EventArgs());
}
}
}
+22 -52
View File
@@ -8,18 +8,16 @@ using TelegramBotBase.Base;
namespace TelegramBotBase.Form
{
public class PromptDialog : FormBase
public class PromptDialog : ModalDialog
{
public String Message { get; set; }
public List<ButtonBase> Buttons { get; set; }
public Dictionary<String, FormBase> ButtonForms { get; set; } = new Dictionary<string, FormBase>();
public String Value { get; set; }
private EventHandlerList __Events { get; set; } = new EventHandlerList();
private static object __evButtonClicked { get; } = new object();
private static object __evCompleted { get; } = new object();
public PromptDialog()
{
@@ -29,80 +27,52 @@ namespace TelegramBotBase.Form
public PromptDialog(String Message)
{
this.Message = Message;
this.Buttons = new List<Form.ButtonBase>();
}
public PromptDialog(String Message, params ButtonBase[] Buttons)
public async override Task Load(MessageResult message)
{
this.Message = Message;
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>();
if (call == null)
if (message.Handled)
return;
message.Handled = true;
await message.ConfirmAction();
await message.DeleteMessage();
ButtonBase button = this.Buttons.FirstOrDefault(a => a.Value == call.Value);
if (button == null)
if (this.Value == null)
{
return;
this.Value = message.MessageText;
}
OnButtonClicked(new ButtonClickedEventArgs(button));
FormBase fb = ButtonForms.ContainsKey(call.Value) ? ButtonForms[call.Value] : null;
if (fb != null)
{
await this.NavigateTo(fb);
}
}
public override async Task Render(MessageResult message)
{
ButtonForm btn = new ButtonForm();
var buttons = this.Buttons.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList();
btn.AddButtonRow(buttons);
if (this.Value == null)
{
await this.Device.Send(this.Message);
return;
}
await this.Device.Send(this.Message, btn);
OnCompleted(new EventArgs());
await this.CloseForm();
}
public event EventHandler<ButtonClickedEventArgs> ButtonClicked
public event EventHandler<EventArgs> Completed
{
add
{
this.__Events.AddHandler(__evButtonClicked, value);
this.__Events.AddHandler(__evCompleted, value);
}
remove
{
this.__Events.RemoveHandler(__evButtonClicked, value);
this.__Events.RemoveHandler(__evCompleted, value);
}
}
public void OnButtonClicked(ButtonClickedEventArgs e)
public void OnCompleted(EventArgs e)
{
(this.__Events[__evButtonClicked] as EventHandler<ButtonClickedEventArgs>)?.Invoke(this, e);
(this.__Events[__evCompleted] as EventHandler<EventArgs>)?.Invoke(this, e);
}
}
+100
View File
@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using static TelegramBotBase.Base.Async;
namespace TelegramBotBase.Form
{
/// <summary>
/// This is used to split incomming requests depending on the chat type.
/// </summary>
public class SplitterForm : FormBase
{
private static object __evOpenSupergroup = new object();
private static object __evOpenGroup = new object();
private static object __evOpenChannel = new object();
private static object __evOpen = new object();
public override async Task Load(MessageResult message)
{
if (message.Message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Channel)
{
if (await OpenChannel(message))
{
return;
}
}
if (message.Message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Supergroup)
{
if (await OpenSupergroup(message))
{
return;
}
if (await OpenGroup(message))
{
return;
}
}
if (message.Message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Group)
{
if (await OpenGroup(message))
{
return;
}
}
await Open(message);
}
public virtual async Task<bool> OpenSupergroup(MessageResult e)
{
return false;
}
public virtual async Task<bool> OpenChannel(MessageResult e)
{
return false;
}
public virtual async Task<bool> Open(MessageResult e)
{
return false;
}
public virtual async Task<bool> OpenGroup(MessageResult e)
{
return false;
}
public override Task Action(MessageResult message)
{
return base.Action(message);
}
public override Task PreLoad(MessageResult message)
{
return base.PreLoad(message);
}
public override Task Render(MessageResult message)
{
return base.Render(message);
}
public override Task SentData(DataResult message)
{
return base.SentData(message);
}
}
}
+112
View File
@@ -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;
}
}
}
+3 -3
View File
@@ -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.4.2.0")]
[assembly: AssemblyFileVersion("1.4.2.0")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
+2 -2
View File
@@ -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;
+148 -22
View File
@@ -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
@@ -127,10 +128,43 @@ 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(int messageId, String text, InlineKeyboardMarkup markup)
{
if (this.ActiveForm == null)
return null;
if (text.Length > Constants.Telegram.MaxMessageLength)
{
throw new MaxLengthException(text.Length);
}
try
@@ -160,10 +194,11 @@ namespace TelegramBotBase.Sessions
if (this.ActiveForm == null)
return null;
InlineKeyboardMarkup markup = null;
if (buttons != null)
InlineKeyboardMarkup markup = buttons;
if (message.Text.Length > Constants.Telegram.MaxMessageLength)
{
markup = buttons;
throw new MaxLengthException(message.Text.Length);
}
try
@@ -189,22 +224,23 @@ 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));
}
@@ -228,16 +264,59 @@ 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 (ApiRequestException ex)
{
return null;
}
catch
{
return null;
}
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, ReplyMarkupBase 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));
}
@@ -261,22 +340,18 @@ 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));
}
@@ -448,6 +523,57 @@ namespace TelegramBotBase.Sessions
return await DeleteMessage(message.MessageId);
}
public virtual async Task ChangeChatPermissions(ChatPermissions permissions)
{
try
{
await this.Client.TelegramClient.SetChatPermissionsAsync(this.DeviceId, permissions);
}
catch
{
}
}
public virtual async Task RestrictUser(int userId, ChatPermissions permissions, DateTime until = default(DateTime))
{
try
{
await this.Client.TelegramClient.RestrictChatMemberAsync(this.DeviceId, userId, permissions, until);
}
catch
{
}
}
public virtual async Task<ChatMember> GetChatUser(int userId)
{
try
{
return await this.Client.TelegramClient.GetChatMemberAsync(this.DeviceId, userId);
}
catch
{
}
return null;
}
public virtual async Task KickUser(int userId, DateTime until = default(DateTime))
{
try
{
await this.Client.TelegramClient.KickChatMemberAsync(this.DeviceId, userId, until);
}
catch
{
}
}
/// <summary>
/// Eventhandler for sent messages
/// </summary>
+47 -70
View File
@@ -1,18 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TelegramBotBase</RootNamespace>
<AssemblyName>TelegramBotBase</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageProjectUrl>https://github.com/MajMcCloud/TelegramBotFramework</PackageProjectUrl>
<RepositoryUrl>https://github.com/MajMcCloud/TelegramBotFramework</RepositoryUrl>
<PackageReleaseNotes>- moving from .Net Framework 4.7.2 to .Net Standard 2.1 for the Library and .Net Core 3.0 for the test project!</PackageReleaseNotes>
<Configurations>Debug;Release;</Configurations>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
<RunAnalyzersDuringLiveAnalysis>false</RunAnalyzersDuringLiveAnalysis>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
@@ -22,6 +23,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
@@ -31,68 +33,43 @@
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\TelegramBotBase.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\TelegramBotBase.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Compile Remove="Archive\**" />
<EmbeddedResource Remove="Archive\**" />
<None Remove="Archive\**" />
</ItemGroup>
<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" />
<Compile Include="Base\MessageSentEventArgs.cs" />
<Compile Include="Base\ResultBase.cs" />
<Compile Include="Base\SessionBeginResult.cs" />
<Compile Include="Base\SystemExceptionEventArgs.cs" />
<Compile Include="Base\UnhandledCallEventArgs.cs" />
<Compile Include="Base\SystemCallEventArgs.cs" />
<Compile Include="BotBase.cs" />
<Compile Include="Controls\ProgressBar.cs" />
<Compile Include="Form\AlertDialog.cs" />
<Compile Include="Form\ArrayPromptDialog.cs" />
<Compile Include="Form\AutoCleanForm.cs" />
<Compile Include="Form\ButtonBase.cs" />
<Compile Include="Form\ButtonForm.cs" />
<Compile Include="Base\FormBase.cs" />
<Compile Include="Form\CallbackData.cs" />
<Compile Include="Form\PromptDialog.cs" />
<Compile Include="SessionBase.cs" />
<Compile Include="Sessions\DeviceSession.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tools\Images.cs" />
<None Remove="cpack.ps1" />
<None Remove="cpush.ps1" />
<None Remove="nuget.exe" />
<None Remove="TelegramBotBase.1.5.0.nupkg" />
<None Remove="TelegramBotBase.1.5.0.zip" />
<None Remove="TelegramBotBase.1.5.1.nupkg" />
<None Remove="TelegramBotBase.1.5.1.zip" />
<None Remove="TelegramBotBase.1.5.2.nupkg" />
<None Remove="TelegramBotBase.1.5.2.zip" />
<None Remove="TelegramBotBase.nuspec" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json">
<Version>11.0.2</Version>
</PackageReference>
<PackageReference Include="System.Net.Requests">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="Telegram.Bot">
<Version>14.10.0</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Drawing.Common" Version="4.6.0" />
<PackageReference Include="Telegram.Bot" Version="15.0.0" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+4 -1
View File
@@ -10,12 +10,15 @@
<projectUrl>https://github.com/MajMcCloud/TelegramBotFramework</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
<releaseNotes>First release on nuget for easier use.</releaseNotes>
<releaseNotes>This is a context based application framework for the C# TelegramBot library.</releaseNotes>
<copyright>Copyright 2019</copyright>
<tags>Telegram Bot Framework C# Addon Context Modules</tags>
<dependencies>
<dependency id="Telegram.Bot" version="14.3.0" />
<dependency id="Newtonsoft.Json" version="11.0.2" />
<dependency id="System.Net.Requests" version="4.3.0" />
</dependencies>
<repository type="git"
url="https://github.com/MajMcCloud/TelegramBotFramework" />
</metadata>
</package>
+22
View File
@@ -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;
}
}
}
+36
View File
@@ -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);
}
}
}
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("TelegramBaseTest")]
[assembly: AssemblyTitle("TelegramBotBaseTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TelegramBaseTest")]
[assembly: AssemblyProduct("TelegramBotBaseTest")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release</Configurations>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\TelegramBotBase\TelegramBotBase.csproj" />
</ItemGroup>
</Project>
@@ -6,12 +6,17 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests
namespace TelegramBotBaseTest.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)");
}
@@ -57,7 +62,7 @@ namespace TelegramBaseTest.Tests
case "back":
var st = new Start();
var st = new Menu();
await this.NavigateTo(st);
@@ -83,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.Controls;
using TelegramBotBase.Form;
namespace TelegramBotBaseTest.Tests.Controls
{
public class ButtonGridForm : AutoCleanForm
{
ButtonGrid m_Buttons = null;
public ButtonGridForm()
{
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
this.Init += ButtonGridForm_Init;
}
private async Task ButtonGridForm_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
{
m_Buttons = new ButtonGrid();
m_Buttons.KeyboardType = TelegramBotBase.Enums.eKeyboardType.InlineKeyBoard;
ButtonForm bf = new ButtonForm();
bf.AddButtonRow(new ButtonBase("Back", "back"), new ButtonBase("Switch Keyboard", "switch"));
bf.AddButtonRow(new ButtonBase("Button1", "b1"), new ButtonBase("Button2", "b2"));
bf.AddButtonRow(new ButtonBase("Button3", "b3"), new ButtonBase("Button4", "b4"));
m_Buttons.ButtonsForm = bf;
m_Buttons.ButtonClicked += Bg_ButtonClicked;
this.AddControl(m_Buttons);
}
private async void Bg_ButtonClicked(object sender, TelegramBotBase.Base.ButtonClickedEventArgs e)
{
if (e.Button == null)
return;
if (e.Button.Value == "back")
{
var start = new Menu();
await this.NavigateTo(start);
}
else if (e.Button.Value == "switch")
{
switch (m_Buttons.KeyboardType)
{
case TelegramBotBase.Enums.eKeyboardType.ReplyKeyboard:
m_Buttons.KeyboardType = TelegramBotBase.Enums.eKeyboardType.InlineKeyBoard;
break;
case TelegramBotBase.Enums.eKeyboardType.InlineKeyBoard:
m_Buttons.KeyboardType = TelegramBotBase.Enums.eKeyboardType.ReplyKeyboard;
break;
}
}
else
{
await this.Device.Send($"Button clicked with Text: {e.Button.Text} and Value {e.Button.Value}");
}
}
}
}
@@ -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 TelegramBotBaseTest.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 Menu();
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 TelegramBotBaseTest.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 Menu();
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 TelegramBotBaseTest.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 TelegramBotBaseTest.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 Menu();
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;
}
}
}
}
@@ -9,7 +9,7 @@ using Telegram.Bot.Types.ReplyMarkups;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests
namespace TelegramBotBaseTest.Tests
{
public class DataForm : AutoCleanForm
{
@@ -110,7 +110,7 @@ namespace TelegramBaseTest.Tests
message.Handled = true;
var start = new Start();
var start = new Menu();
await this.NavigateTo(start);
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBotBaseTest.Tests.Groups
{
public class GroupChange : TelegramBotBase.Form.GroupForm
{
public GroupChange()
{
this.Opened += GroupChange_Opened;
}
private async Task GroupChange_Opened(object sender, EventArgs e)
{
ButtonForm bf = new ButtonForm();
bf.AddButtonRow(new ButtonBase("Open GroupChange Test", "groupchange"));
bf.AddButtonRow(new ButtonBase("Open WelcomeUser Test", "welcomeuser"));
bf.AddButtonRow(new ButtonBase("Open LinkReplace Test", "linkreplace"));
await this.Device.Send("GroupChange started, click to switch", bf);
}
public override async Task Action(MessageResult message)
{
if (message.Handled)
return;
var bn = message.RawData;
await message.ConfirmAction();
message.Handled = true;
switch (bn)
{
case "groupchange":
var gc = new GroupChange();
await this.NavigateTo(gc);
break;
case "welcomeuser":
var wu = new WelcomeUser();
await this.NavigateTo(wu);
break;
case "linkreplace":
var lr = new LinkReplaceTest();
await this.NavigateTo(lr);
break;
}
}
public override async Task OnGroupChanged(GroupChangedEventArgs e)
{
await this.Device.Send("Group has been changed by " + e.OriginalMessage.Message.From.FirstName + " " + e.OriginalMessage.Message.From.LastName);
}
}
}
@@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Telegram.Bot.Types;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBotBaseTest.Tests.Groups
{
public class LinkReplaceTest : TelegramBotBase.Form.GroupForm
{
Dictionary<int, int> Counter { get; set; } = new Dictionary<int, int>();
private const int Maximum = 3;
public LinkReplaceTest()
{
this.Opened += LinkReplaceTest_Opened;
}
private async Task LinkReplaceTest_Opened(object sender, EventArgs e)
{
ButtonForm bf = new ButtonForm();
bf.AddButtonRow(new ButtonBase("Open GroupChange Test", "groupchange"));
bf.AddButtonRow(new ButtonBase("Open WelcomeUser Test", "welcomeuser"));
bf.AddButtonRow(new ButtonBase("Open LinkReplace Test", "linkreplace"));
await this.Device.Send("LinkReplaceTest started, click to switch", bf);
}
public override async Task Action(MessageResult message)
{
if (message.Handled)
return;
var bn = message.RawData;
await message.ConfirmAction();
message.Handled = true;
switch (bn)
{
case "groupchange":
var gc = new GroupChange();
await this.NavigateTo(gc);
break;
case "welcomeuser":
var wu = new WelcomeUser();
await this.NavigateTo(wu);
break;
case "linkreplace":
var lr = new LinkReplaceTest();
await this.NavigateTo(lr);
break;
}
}
public override async Task OnMessage(MessageResult e)
{
var from = e.Message.From.Id;
if (e.Message.From.IsBot)
return;
var u = await Device.GetChatUser(from);
//Don't kick Admins or Creators
if (u.Status == Telegram.Bot.Types.Enums.ChatMemberStatus.Administrator | u.Status == Telegram.Bot.Types.Enums.ChatMemberStatus.Creator)
{
await this.Device.Send("You won't get kicked,...not this time.");
return;
}
//Are urls inside his message ?
if (!HasLinks(e.MessageText))
return;
await e.Device.DeleteMessage(e.MessageId);
var cp = new ChatPermissions();
cp.CanAddWebPagePreviews = false;
cp.CanChangeInfo = false;
cp.CanInviteUsers = false;
cp.CanPinMessages = false;
cp.CanSendMediaMessages = false;
cp.CanSendMessages = false;
cp.CanSendOtherMessages = false;
cp.CanSendPolls = false;
//Collect user "mistakes" with sending url, after 3 he gets kicked out.
if (Counter.ContainsKey(from))
{
Counter[from]++;
}
else
{
Counter[from] = 1;
}
if (Counter[from] >= 3)
{
await e.Device.KickUser(from);
await e.Device.Send(e.Message.From.FirstName + " " + e.Message.From.LastName + " has been removed from the group");
}
else
{
await e.Device.RestrictUser(from, cp, DateTime.UtcNow.AddSeconds(30));
await e.Device.Send(e.Message.From.FirstName + " " + e.Message.From.LastName + " has been blocked for 30 seconds");
}
}
/// <summary>
/// https://stackoverflow.com/a/20651284
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private bool HasLinks(String str)
{
var tmp = str;
var pattern = @"^(http|https|ftp|)\://|[a-zA-Z0-9\-\.]+\.[a-zA-Z](:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&amp;%\$#\=~])*[^\.\,\)\(\s]$";
Regex r = new Regex(pattern);
var matches = r.Matches(tmp);
return (matches.Count > 0);
}
}
}
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBotBaseTest.Tests.Groups
{
public class WelcomeUser : TelegramBotBase.Form.GroupForm
{
public WelcomeUser()
{
this.Opened += WelcomeUser_Opened;
}
private async Task WelcomeUser_Opened(object sender, EventArgs e)
{
ButtonForm bf = new ButtonForm();
bf.AddButtonRow(new ButtonBase("Open GroupChange Test", "groupchange"));
bf.AddButtonRow(new ButtonBase("Open WelcomeUser Test", "welcomeuser"));
bf.AddButtonRow(new ButtonBase("Open LinkReplace Test", "linkreplace"));
await this.Device.Send("WelcomeUser started, click to switch", bf);
}
public override async Task Action(MessageResult message)
{
if (message.Handled)
return;
var bn = message.RawData;
await message.ConfirmAction();
message.Handled = true;
switch (bn)
{
case "groupchange":
var gc = new GroupChange();
await this.NavigateTo(gc);
break;
case "welcomeuser":
var wu = new WelcomeUser();
await this.NavigateTo(wu);
break;
case "linkreplace":
var lr = new LinkReplaceTest();
await this.NavigateTo(lr);
break;
}
}
public override async Task OnMemberChanges(MemberChangeEventArgs e)
{
if (e.Type == Telegram.Bot.Types.Enums.MessageType.ChatMembersAdded)
{
await this.Device.Send("Welcome you new members!\r\n\r\n" + e.Members.Select(a => a.FirstName + " " + a.LastName).Aggregate((a, b) => a + "\r\n" + b));
}
else if (e.Type == Telegram.Bot.Types.Enums.MessageType.ChatMemberLeft)
{
await this.Device.Send(e.Members.Select(a => a.FirstName + " " + a.LastName).Aggregate((a, b) => a + " and " + b) + " has left the group");
}
}
}
}
@@ -6,10 +6,28 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests
namespace TelegramBotBaseTest.Tests
{
public class Start : FormBase
public class Menu : AutoCleanForm
{
public Menu()
{
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
}
public override async Task Load(MessageResult message)
{
if (message.Message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Group | message.Message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Supergroup)
{
var sf = new TelegramBotBaseTest.Tests.Groups.WelcomeUser();
await this.NavigateTo(sf);
}
}
public override async Task Action(MessageResult message)
{
@@ -79,6 +97,55 @@ namespace TelegramBaseTest.Tests
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;
case "buttongrid":
message.Handled = true;
var bg = new Controls.ButtonGridForm();
await this.NavigateTo(bg);
break;
}
@@ -99,6 +166,14 @@ namespace TelegramBaseTest.Tests
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()));
btn.AddButtonRow(new ButtonBase("#12 ButtonGrid", new CallbackData("a", "buttongrid").Serialize()));
await this.Device.Send("Choose your test:", btn);
}
@@ -7,17 +7,20 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests
namespace TelegramBotBaseTest.Tests
{
public class ProgressTest : AutoCleanForm
{
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");
}
@@ -73,7 +76,7 @@ namespace TelegramBaseTest.Tests
case "start":
var sf = new Start();
var sf = new Menu();
await this.NavigateTo(sf);
@@ -87,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);
}
@@ -117,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");
}
}
}
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests.Register
namespace TelegramBotBaseTest.Tests.Register
{
public class PerForm : AutoCleanForm
{
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests.Register
namespace TelegramBotBaseTest.Tests.Register
{
public class PerStep: AutoCleanForm
{
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests.Register
namespace TelegramBotBaseTest.Tests.Register
{
public class Start : AutoCleanForm
{
@@ -43,7 +43,7 @@ namespace TelegramBaseTest.Tests.Register
break;
case "backtodashboard":
var start = new Tests.Start();
var start = new Tests.Menu();
await this.NavigateTo(start);
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TelegramBaseTest.Tests.Register.Steps
namespace TelegramBotBaseTest.Tests.Register.Steps
{
public class Data
{
@@ -6,17 +6,23 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests.Register.Steps
namespace TelegramBotBaseTest.Tests.Register.Steps
{
public class Step1 : AutoCleanForm
{
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)
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests.Register.Steps
namespace TelegramBotBaseTest.Tests.Register.Steps
{
public class Step2 : AutoCleanForm
{
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests.Register.Steps
namespace TelegramBotBaseTest.Tests.Register.Steps
{
public class Step3 : AutoCleanForm
{
@@ -6,23 +6,24 @@ using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests
namespace TelegramBotBaseTest.Tests
{
public class SimpleForm : AutoCleanForm
{
public SimpleForm()
{
this.DeleteSide = eSide.Both;
this.DeleteMode = eDeleteMode.OnLeavingForm;
this.DeleteSide = TelegramBotBase.Enums.eDeleteSide.Both;
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
this.Opened += SimpleForm_Opened;
}
public override async Task 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)
{
//message.MessageText will work also, cause it is a string you could manage a lot different scenerios here
@@ -54,7 +55,7 @@ namespace TelegramBaseTest.Tests
case "back":
var st = new Start();
var st = new Menu();
await this.NavigateTo(st);
+40
View File
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBotBaseTest.Tests
{
public class Start : SplitterForm
{
public override async Task<bool> Open(MessageResult e)
{
var st = new Menu();
await this.NavigateTo(st);
return true;
}
public override async Task<bool> OpenGroup(MessageResult e)
{
var st = new Groups.LinkReplaceTest();
await this.NavigateTo(st);
return true;
}
public override Task<bool> OpenChannel(MessageResult e)
{
return base.OpenChannel(e);
}
public override Task<bool> OpenSupergroup(MessageResult e)
{
return base.OpenSupergroup(e);
}
}
}
@@ -7,7 +7,7 @@ using Telegram.Bot.Types;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests
namespace TelegramBotBaseTest.Tests
{
public class TestForm : FormBase
{
@@ -15,13 +15,18 @@ namespace TelegramBaseTest.Tests
String LastMessage { get; set; }
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");
}
@@ -10,23 +10,31 @@ using Telegram.Bot.Types.ReplyMarkups;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
namespace TelegramBaseTest.Tests
namespace TelegramBotBaseTest.Tests
{
public class TestForm2 : FormBase
{
public override async Task Opened()
public TestForm2()
{
this.Opened += TestForm2_Opened;
this.Closed += TestForm2_Closed;
}
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 Action(MessageResult message)
{
var call = message.GetData<CallbackData>();
@@ -35,6 +43,8 @@ namespace TelegramBaseTest.Tests
await message.DeleteMessage();
message.Handled = true;
if (call.Value == "testform1")
{
@@ -44,29 +54,19 @@ namespace TelegramBaseTest.Tests
}
else if (call.Value == "alert")
{
var fto = new TestForm2();
AlertDialog ad = new AlertDialog("This is a message", "Ok");
AlertDialog ad = new AlertDialog("This is a message", "Ok", fto);
ad.ButtonClicked += async (s, en) =>
{
var fto = new TestForm2();
await this.NavigateTo(fto);
};
await this.NavigateTo(ad);
}
else if (call.Value == "prompt")
else if (call.Value == "confirm")
{
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);
}
else if (call.Value == "promptevt")
{
PromptDialog pd = new PromptDialog("Please confirm", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
ConfirmDialog pd = new ConfirmDialog("Please confirm", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
pd.ButtonClicked += async (s, en) =>
{
@@ -77,6 +77,17 @@ namespace TelegramBaseTest.Tests
await this.NavigateTo(pd);
}
else if (call.Value == "prompt")
{
PromptDialog pd = new PromptDialog("Please tell me your name ?");
pd.Completed += async (s, en) =>
{
await this.Device.Send("Hello " + pd.Value);
};
await this.OpenModal(pd);
}
}
@@ -102,9 +113,9 @@ namespace TelegramBaseTest.Tests
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", "confirm")));
btn.AddButtonRow(new ButtonBase("Confirmation Prompt with event", CallbackData.Create("navigate", "promptevt")));
btn.AddButtonRow(new ButtonBase("Request Prompt", CallbackData.Create("navigate", "prompt")));
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>
+14 -14
View File
@@ -1,13 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.168
# Visual Studio Version 16
VisualStudioVersion = 16.0.29324.140
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramBaseTest", "TelegramBaseTest\TelegramBaseTest.csproj", "{5817184C-0D59-4924-AC6C-6B943967811C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBotBase", "TelegramBotBase\TelegramBotBase.csproj", "{0BD16FB9-7ED4-4CCB-83EB-5CEE538E1B6C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramBotBase", "TelegramBotBase\TelegramBotBase.csproj", "{A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBotBaseTest", "TelegramBotBaseTest\TelegramBotBaseTest.csproj", "{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E9AE1280-C1F3-4960-9D3D-D4F25142E838}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3856B3FB-63E3-444A-9FF0-34171BE7AC5D}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
@@ -18,19 +18,19 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5817184C-0D59-4924-AC6C-6B943967811C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5817184C-0D59-4924-AC6C-6B943967811C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5817184C-0D59-4924-AC6C-6B943967811C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5817184C-0D59-4924-AC6C-6B943967811C}.Release|Any CPU.Build.0 = Release|Any CPU
{A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}.Release|Any CPU.Build.0 = Release|Any CPU
{0BD16FB9-7ED4-4CCB-83EB-5CEE538E1B6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BD16FB9-7ED4-4CCB-83EB-5CEE538E1B6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BD16FB9-7ED4-4CCB-83EB-5CEE538E1B6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BD16FB9-7ED4-4CCB-83EB-5CEE538E1B6C}.Release|Any CPU.Build.0 = Release|Any CPU
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4245F162-E263-45E0-A16A-ED5F411A4AFC}
SolutionGuid = {59CB40E1-9FA7-4867-A56F-4F418286F057}
EndGlobalSection
EndGlobal
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB