Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb61d40a38 | ||
|
|
2ed030b2fb | ||
|
|
fd6f6fef34 | ||
|
|
54176f9136 | ||
|
|
f80fda8ff9 | ||
|
|
8b66842d34 | ||
|
|
0cdb8c3a1a | ||
|
|
8b9929198a | ||
|
|
7a3e4721bd | ||
|
|
f914920919 | ||
|
|
0435c68281 | ||
|
|
5a1e050aec | ||
|
|
6a62d73fe0 | ||
|
|
519a6fe41c | ||
|
|
201dfd10dd | ||
|
|
78a412c630 | ||
|
|
7a7014cec3 | ||
|
|
64311d0cd9 | ||
|
|
762fb27294 | ||
|
|
164194ac66 | ||
|
|
321bd7c0ff | ||
|
|
37ef30ebee | ||
|
|
9b1461ad78 | ||
|
|
38fa0a4e99 | ||
|
|
fba922049f | ||
|
|
d5a9a5f7a4 | ||
|
|
5126074419 | ||
|
|
aa38492bde | ||
|
|
9c68914e9d | ||
|
|
3fe2779b1e | ||
|
|
8e6de4a0e1 | ||
|
|
382ae2de2d | ||
|
|
77fd3393de | ||
|
|
0f1da77aca | ||
|
|
1561c1dd08 | ||
|
|
5b38f2e1e2 | ||
|
|
2989456fe5 | ||
|
|
7e4174a3be | ||
|
|
73f81cc8a2 | ||
|
|
2071ba2eeb | ||
|
|
a08ba8f512 | ||
|
|
649b94dafe | ||
|
|
7be0f15ca4 | ||
|
|
e29be4f1f4 | ||
|
|
176107300b | ||
|
|
0ceab58059 | ||
|
|
6ebdd9f208 | ||
|
|
595efd2276 | ||
|
|
85a479d826 | ||
|
|
150e9f731d | ||
|
|
0eab45bdbb | ||
|
|
a33cf5b841 | ||
|
|
1f9539a23d | ||
|
|
9cbde4830e | ||
|
|
3bea2783b1 | ||
|
|
038a941d33 | ||
|
|
48c62e57f8 | ||
|
|
b0e6a8b981 | ||
|
|
2e0656dc06 | ||
|
|
d1456d5bd1 | ||
|
|
058539777f | ||
|
|
5c69289198 | ||
|
|
4c8b085655 | ||
|
|
94d22318f8 | ||
|
|
2028e2f9e6 | ||
|
|
394209b303 | ||
|
|
f0fa953819 | ||
|
|
1d44b50883 | ||
|
|
3c21af8f68 | ||
|
|
1b811e1786 | ||
|
|
94195ec5bf | ||
|
|
256cac825f | ||
|
|
69e5a6717b | ||
|
|
a6d22cdd82 | ||
|
|
ee4a3d765c | ||
|
|
703c99eb8d | ||
|
|
138fee9772 | ||
|
|
d60399514f | ||
|
|
ae0fa3b0e3 | ||
|
|
6a2ac7a309 | ||
|
|
1a76b2b3f8 | ||
|
|
5893108bd3 | ||
|
|
d668f57711 | ||
|
|
56c7754408 | ||
|
|
805ffb9ec7 | ||
|
|
aeddd82ea9 | ||
|
|
1ec14ce680 | ||
|
|
3a309baeae | ||
|
|
e02af0fc76 | ||
|
|
530e01f971 | ||
|
|
dcf3cf804f | ||
|
|
a42d3934b5 | ||
|
|
2126b45fed | ||
|
|
b6b9d5b6b1 | ||
|
|
eed5f012dc | ||
|
|
de4cc138ae | ||
|
|
e4da70d37d | ||
|
|
cb4a797b12 | ||
|
|
94d153e141 | ||
|
|
e13cb6d4ef | ||
|
|
c0e285d39e | ||
|
|
8338c5c066 | ||
|
|
52c01b3dfd | ||
|
|
fe1aafc9a5 | ||
|
|
022eee4b57 | ||
|
|
ea971979e2 | ||
|
|
9585a231bd | ||
|
|
c07aca96a4 | ||
|
|
01de9ec932 | ||
|
|
94fe263676 | ||
|
|
4f1eae543d | ||
|
|
1491fc1795 | ||
|
|
b2db44fe4c | ||
|
|
3a78a98b9e | ||
|
|
b14fa2dc87 | ||
|
|
5cd54fc746 | ||
|
|
fb68da6ab1 | ||
|
|
2f7ded8ce5 | ||
|
|
906177a5f9 | ||
|
|
873c91a165 | ||
|
|
46c1acbf99 | ||
|
|
acd06a6948 | ||
|
|
a97305fa35 | ||
|
|
16baef0c45 | ||
|
|
211bc55aff | ||
|
|
19f3c9c195 | ||
|
|
c6666f72bc | ||
|
|
bf7f6f851a | ||
|
|
816bf4cbbe | ||
|
|
da80af86e3 | ||
|
|
929db3ae88 | ||
|
|
582f005b35 | ||
|
|
bbf90deccc | ||
|
|
1d8b367bea |
+12
@@ -240,3 +240,15 @@ ModelManifest.xml
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
MigrationBackup
|
||||
TelegramBotBase/nuget.exe
|
||||
Material
|
||||
TelegramBotBase/cp.ps1
|
||||
TelegramBotBase/TelegramBotBase.nuspec
|
||||
Program.cs
|
||||
TelegramBotBase/Archive
|
||||
/TelegramBotBase/TelegramBotBase.1.5.0.zip
|
||||
/TelegramBotBase/TelegramBotBase.1.5.1.zip
|
||||
/TelegramBotBase/TelegramBotBase.1.5.2.zip
|
||||
/TelegramBotBase/cpush.ps1
|
||||
/TelegramBotBase/cpack.ps1
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\TelegramBotBase\TelegramBotBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace SystemCommandsBot.commands
|
||||
{
|
||||
public class Commando
|
||||
{
|
||||
public int ID { get; set; }
|
||||
|
||||
public String Title { get; set; }
|
||||
|
||||
public String ShellCmd { get; set; }
|
||||
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
public String Action { get; set; }
|
||||
|
||||
public bool UseShell { get; set; } = true;
|
||||
|
||||
|
||||
public int? MaxInstances { get; set; }
|
||||
|
||||
public String ProcName
|
||||
{
|
||||
get;set;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace SystemCommandsBot.config
|
||||
{
|
||||
public class Config
|
||||
{
|
||||
public String Password { get; set; }
|
||||
|
||||
public String ApiKey { get; set; }
|
||||
|
||||
public List<commands.Commando> Commandos { get; set; }
|
||||
|
||||
|
||||
public Config()
|
||||
{
|
||||
this.Commandos = new List<commands.Commando>();
|
||||
}
|
||||
|
||||
public void loadDefaultValues()
|
||||
{
|
||||
this.ApiKey = "";
|
||||
this.Commandos.Add(new commands.Commando() { ID = 0, Enabled = true, Title = "Test Befehl", ShellCmd = "explorer.exe", Action = "start", MaxInstances = 2 });
|
||||
}
|
||||
|
||||
|
||||
public static Config load()
|
||||
{
|
||||
try
|
||||
{
|
||||
return load(AppContext.BaseDirectory + "config\\default.cfg");
|
||||
|
||||
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Config load(String path)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cfg = Newtonsoft.Json.JsonConvert.DeserializeObject<Config>(File.ReadAllText(path)) as Config;
|
||||
return cfg;
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{
|
||||
DirectoryInfo di = new DirectoryInfo(path);
|
||||
|
||||
if (!Directory.Exists(di.Parent.FullName))
|
||||
{
|
||||
Directory.CreateDirectory(di.Parent.FullName);
|
||||
}
|
||||
|
||||
var cfg = new Config();
|
||||
cfg.loadDefaultValues();
|
||||
cfg.save(path);
|
||||
return cfg;
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
var cfg = new Config();
|
||||
cfg.loadDefaultValues();
|
||||
cfg.save(path);
|
||||
return cfg;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void save(String path)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllText(path, Newtonsoft.Json.JsonConvert.SerializeObject(this));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace SystemCommandsBot.forms
|
||||
{
|
||||
public class CmdForm : TelegramBotBase.Form.AutoCleanForm
|
||||
{
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
|
||||
public int? MessageId { get; set; }
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
var btn = message.RawData;
|
||||
|
||||
int id = -1;
|
||||
|
||||
if (!int.TryParse(btn, out id))
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var cmd = Program.BotConfig.Commandos.Where(a => a.Enabled && a.ID == id).FirstOrDefault();
|
||||
if (cmd == null)
|
||||
{
|
||||
await this.Device.Send("Cmd nicht verfügbar.");
|
||||
return;
|
||||
}
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
switch (cmd.Action)
|
||||
{
|
||||
case "start":
|
||||
|
||||
FileInfo fi = new FileInfo(cmd.ShellCmd);
|
||||
|
||||
if (cmd.MaxInstances != null && cmd.MaxInstances >= 0)
|
||||
{
|
||||
|
||||
if (Process.GetProcessesByName(cmd.ProcName).Count() >= cmd.MaxInstances)
|
||||
{
|
||||
await this.Device.Send("Anwendung läuft bereits.");
|
||||
await message.ConfirmAction("Anwendung läuft bereits.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ProcessStartInfo psi = new ProcessStartInfo();
|
||||
psi.FileName = cmd.ShellCmd;
|
||||
psi.WorkingDirectory = fi.DirectoryName;
|
||||
psi.UseShellExecute = cmd.UseShell;
|
||||
|
||||
Process.Start(psi);
|
||||
|
||||
await this.Device.Send(fi.Name + " wurde gestarted.");
|
||||
|
||||
await message.ConfirmAction(fi.Name + " wurde gestarted.");
|
||||
|
||||
break;
|
||||
|
||||
case "kill":
|
||||
|
||||
FileInfo fi2 = new FileInfo(cmd.ShellCmd);
|
||||
|
||||
String pros = fi2.Name.Replace(fi2.Extension, "");
|
||||
|
||||
var proc = Process.GetProcessesByName(pros).ToList();
|
||||
|
||||
foreach (var p in proc)
|
||||
{
|
||||
try
|
||||
{
|
||||
p.Kill();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
await this.Device.Send(fi2.Name + " wurde beendet.");
|
||||
|
||||
await message.ConfirmAction(fi2.Name + " wurde beendet.");
|
||||
|
||||
break;
|
||||
|
||||
case "restart":
|
||||
|
||||
FileInfo fi3 = new FileInfo(cmd.ShellCmd);
|
||||
|
||||
String pros2 = fi3.Name.Replace(fi3.Extension, "");
|
||||
|
||||
var proc2 = Process.GetProcessesByName(pros2).ToList();
|
||||
|
||||
foreach (var p in proc2)
|
||||
{
|
||||
try
|
||||
{
|
||||
p.Kill();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
FileInfo fi4 = new FileInfo(cmd.ShellCmd);
|
||||
|
||||
ProcessStartInfo psi2 = new ProcessStartInfo();
|
||||
psi2.FileName = cmd.ShellCmd;
|
||||
psi2.WorkingDirectory = fi4.DirectoryName;
|
||||
psi2.FileName = cmd.ShellCmd;
|
||||
psi2.UseShellExecute = cmd.UseShell;
|
||||
|
||||
Process.Start(psi2);
|
||||
|
||||
await this.Device.Send(fi3.Name + " wurde neugestarted.");
|
||||
await message.ConfirmAction(fi3.Name + " wurde neugestarted.");
|
||||
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
await message.ConfirmAction();
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
if (this.MessageId == null)
|
||||
{
|
||||
var buttons = Program.BotConfig.Commandos.Where(a => a.Enabled).Select(a => new ButtonBase(a.Title, a.ID.ToString()));
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddSplitted(buttons, 1);
|
||||
await this.Device.Send("Deine Optionen", bf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace SystemCommandsBot.forms
|
||||
{
|
||||
public class StartForm : TelegramBotBase.Form.FormBase
|
||||
{
|
||||
public String Password { get; set; }
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
var inp = message.MessageText;
|
||||
if (Program.BotConfig.Password == inp)
|
||||
{
|
||||
this.Password = inp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
if (this.Password == null || this.Password.Trim() == "")
|
||||
{
|
||||
await this.Device.Send("Bitte gib dein Passwort an.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var cmd = new forms.CmdForm();
|
||||
cmd.ExpiresAt = DateTime.Now.AddDays(14);
|
||||
|
||||
await this.NavigateTo(cmd);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,73 +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 "/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.LastMessage);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
bb.Start();
|
||||
|
||||
|
||||
|
||||
Console.WriteLine("Telegram Bot started...");
|
||||
|
||||
Console.WriteLine("Press q to quit application.");
|
||||
|
||||
|
||||
Console.ReadLine();
|
||||
|
||||
bb.Stop();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,92 +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\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>
|
||||
@@ -1,76 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests
|
||||
{
|
||||
public class Start : FormBase
|
||||
{
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
|
||||
await message.ConfirmAction();
|
||||
|
||||
|
||||
if (call == null)
|
||||
return;
|
||||
|
||||
switch(call.Value)
|
||||
{
|
||||
case "text":
|
||||
|
||||
var sf = new SimpleForm();
|
||||
|
||||
await this.NavigateTo(sf);
|
||||
|
||||
break;
|
||||
|
||||
case "buttons":
|
||||
|
||||
var bf = new ButtonTestForm();
|
||||
|
||||
await this.NavigateTo(bf);
|
||||
|
||||
break;
|
||||
|
||||
case "progress":
|
||||
|
||||
var pf = new ProgressTest();
|
||||
|
||||
await this.NavigateTo(pf);
|
||||
|
||||
break;
|
||||
|
||||
case "registration":
|
||||
|
||||
var reg = new Register.Start();
|
||||
|
||||
await this.NavigateTo(reg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
|
||||
ButtonForm btn = new ButtonForm();
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#1 Simple Text", new CallbackData("a", "text").Serialize()), new ButtonBase("#2 Button Test", new CallbackData("a", "buttons").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#3 Progress Bar", new CallbackData("a", "progress").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#4 Registration Example", new CallbackData("a", "registration").Serialize()));
|
||||
|
||||
await this.Device.Send("Choose your test:", btn);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
/// <summary>
|
||||
/// Button get clicked event
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
public class InitEventArgs : EventArgs
|
||||
{
|
||||
public object[] Args { get; set; }
|
||||
|
||||
public InitEventArgs(params object[] args)
|
||||
{
|
||||
this.Args = args;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
public class LoadStateEventArgs
|
||||
{
|
||||
public Dictionary<String,object> Values { get; set; }
|
||||
|
||||
public LoadStateEventArgs()
|
||||
{
|
||||
Values = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public List<String> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
return Values.Keys.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public String Get(String key)
|
||||
{
|
||||
return Values[key].ToString();
|
||||
}
|
||||
|
||||
public int GetInt(String key)
|
||||
{
|
||||
int i = 0;
|
||||
if (int.TryParse(Values[key].ToString(), out i))
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double GetDouble(String key)
|
||||
{
|
||||
double d = 0;
|
||||
if (double.TryParse(Values[key].ToString(), out d))
|
||||
return d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool GetBool(String key)
|
||||
{
|
||||
bool b = false;
|
||||
if (bool.TryParse(Values[key].ToString(), out b))
|
||||
return b;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,7 +7,7 @@ using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public class MessageIncomeResult : EventArgs
|
||||
public class MessageIncomeEventArgs : EventArgs
|
||||
{
|
||||
|
||||
public long DeviceId { get; set; }
|
||||
@@ -16,7 +16,7 @@ namespace TelegramBotBase.Base
|
||||
|
||||
public MessageResult Message { get; set; }
|
||||
|
||||
public MessageIncomeResult(long DeviceId, DeviceSession Device, MessageResult message)
|
||||
public MessageIncomeEventArgs(long DeviceId, DeviceSession Device, MessageResult message)
|
||||
{
|
||||
this.DeviceId = DeviceId;
|
||||
this.Device = Device;
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
public class MessageReceivedEventArgs
|
||||
{
|
||||
public int MessageId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public Message Message { get; set; }
|
||||
|
||||
public MessageReceivedEventArgs(Message m)
|
||||
{
|
||||
this.Message = m;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -5,22 +5,22 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
public class MessageSentEventArgs
|
||||
{
|
||||
public int MessageId { get; set; }
|
||||
public int MessageId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public Message Message { get; set; }
|
||||
|
||||
public MessageSentEventArgs()
|
||||
public MessageSentEventArgs(Message message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MessageSentEventArgs(int MessageId, Message message)
|
||||
{
|
||||
this.MessageId = MessageId;
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
public class SaveStateEventArgs
|
||||
{
|
||||
public Dictionary<String, object> Values { get; set; }
|
||||
|
||||
public SaveStateEventArgs()
|
||||
{
|
||||
Values = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public void Set(String key, String value)
|
||||
{
|
||||
Values[key] = value;
|
||||
}
|
||||
|
||||
public void SetInt(String key, int value)
|
||||
{
|
||||
Values[key] = value;
|
||||
}
|
||||
|
||||
public void SetBool(String key, bool value)
|
||||
{
|
||||
Values[key] = value;
|
||||
}
|
||||
|
||||
public void SetDouble(String key, double value)
|
||||
{
|
||||
Values[key] = value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
public class SaveStatesEventArgs
|
||||
{
|
||||
public StateContainer States { get; set; }
|
||||
|
||||
|
||||
public SaveStatesEventArgs(StateContainer states)
|
||||
{
|
||||
this.States = states;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,13 +7,13 @@ using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public class SessionBeginResult : EventArgs
|
||||
public class SessionBeginEventArgs : EventArgs
|
||||
{
|
||||
public long DeviceId { get; set; }
|
||||
|
||||
public DeviceSession Device { get; set; }
|
||||
|
||||
public SessionBeginResult(long DeviceId, DeviceSession Device)
|
||||
public SessionBeginEventArgs(long DeviceId, DeviceSession Device)
|
||||
{
|
||||
this.DeviceId = DeviceId;
|
||||
this.Device = Device;
|
||||
+6
-2
@@ -3,9 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for given system call results
|
||||
@@ -22,6 +23,8 @@ namespace TelegramBotBase.Base
|
||||
|
||||
public bool Handled { get; set; } = false;
|
||||
|
||||
public Message OriginalMessage { get; set; }
|
||||
|
||||
|
||||
public SystemCallEventArgs()
|
||||
{
|
||||
@@ -29,10 +32,11 @@ namespace TelegramBotBase.Base
|
||||
|
||||
}
|
||||
|
||||
public SystemCallEventArgs(String Command, List<String> Parameters, long DeviceId, DeviceSession Device)
|
||||
public SystemCallEventArgs(String Command, List<String> Parameters, Message Message, long DeviceId, DeviceSession Device)
|
||||
{
|
||||
this.Command = Command;
|
||||
this.Parameters = Parameters;
|
||||
this.OriginalMessage = Message;
|
||||
this.DeviceId = DeviceId;
|
||||
this.Device = Device;
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
public class SystemExceptionEventArgs : EventArgs
|
||||
{
|
||||
+1
-1
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
namespace TelegramBotBase.Args
|
||||
{
|
||||
public class UnhandledCallEventArgs : EventArgs
|
||||
{
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TelegramBotBase.Attributes
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Declares that this class should not be getting serialized
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class IgnoreState : Attribute
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TelegramBotBase.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Declares that the field or property should be save and recovered an restart.
|
||||
/// </summary>
|
||||
public class SaveState : Attribute
|
||||
{
|
||||
public String Key { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public static class Async
|
||||
{
|
||||
public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;
|
||||
|
||||
public static IEnumerable<AsyncEventHandler<TEventArgs>> GetHandlers<TEventArgs>(
|
||||
this AsyncEventHandler<TEventArgs> handler)
|
||||
where TEventArgs : EventArgs
|
||||
=> handler.GetInvocationList().Cast<AsyncEventHandler<TEventArgs>>();
|
||||
|
||||
public static Task InvokeAllAsync<TEventArgs>(this AsyncEventHandler<TEventArgs> handler, object sender, TEventArgs e)
|
||||
where TEventArgs : EventArgs
|
||||
=> Task.WhenAll(
|
||||
handler.GetHandlers()
|
||||
.Select(handleAsync => handleAsync(sender, e)));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,49 @@ 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)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public virtual async Task Hidden(bool FormClose)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.InputFiles;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a class to manage attachments within messages.
|
||||
/// </summary>
|
||||
public class DataResult : ResultBase
|
||||
{
|
||||
public Telegram.Bot.Args.MessageEventArgs RawMessageData { get; set; }
|
||||
|
||||
public Contact Contact
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Contact;
|
||||
}
|
||||
}
|
||||
|
||||
public Location Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Location;
|
||||
}
|
||||
}
|
||||
|
||||
public Document Document
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Document;
|
||||
}
|
||||
}
|
||||
|
||||
public Audio Audio
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Audio;
|
||||
}
|
||||
}
|
||||
|
||||
public Video Video
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Video;
|
||||
}
|
||||
}
|
||||
|
||||
public PhotoSize[] Photos
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Message.Photo;
|
||||
}
|
||||
}
|
||||
|
||||
public Telegram.Bot.Types.Enums.MessageType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.RawMessageData?.Message?.Type ?? Telegram.Bot.Types.Enums.MessageType.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the FileId of the first reachable element.
|
||||
/// </summary>
|
||||
public String FileId
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.Document?.FileId ??
|
||||
this.Audio?.FileId ??
|
||||
this.Video?.FileId ??
|
||||
this.Photos.FirstOrDefault()?.FileId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DataResult(Telegram.Bot.Args.MessageEventArgs rawdata)
|
||||
{
|
||||
this.RawMessageData = rawdata;
|
||||
this.Message = rawdata.Message;
|
||||
}
|
||||
|
||||
public DataResult(MessageResult message)
|
||||
{
|
||||
this.RawMessageData = message.RawMessageData;
|
||||
this.Message = message.Message;
|
||||
|
||||
this.Client = message.Client;
|
||||
}
|
||||
|
||||
public async Task<InputOnlineFile> DownloadDocument()
|
||||
{
|
||||
var encryptedContent = new System.IO.MemoryStream(this.Document.FileSize);
|
||||
var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, encryptedContent);
|
||||
|
||||
return new InputOnlineFile(encryptedContent, this.Document.FileName);
|
||||
}
|
||||
|
||||
public async Task DownloadDocument(String path)
|
||||
{
|
||||
var file = await this.Client.TelegramClient.GetFileAsync(this.Document.FileId);
|
||||
FileStream fs = new FileStream(path, FileMode.Create);
|
||||
await this.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
|
||||
fs.Close();
|
||||
fs.Dispose();
|
||||
}
|
||||
|
||||
public async Task<InputOnlineFile> DownloadVideo()
|
||||
{
|
||||
var encryptedContent = new System.IO.MemoryStream(this.Video.FileSize);
|
||||
var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Video.FileId, encryptedContent);
|
||||
|
||||
return new InputOnlineFile(encryptedContent, "");
|
||||
}
|
||||
|
||||
public async Task DownloadVideo(String path)
|
||||
{
|
||||
var file = await this.Client.TelegramClient.GetFileAsync(this.Video.FileId);
|
||||
FileStream fs = new FileStream(path, FileMode.Create);
|
||||
await this.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
|
||||
fs.Close();
|
||||
fs.Dispose();
|
||||
}
|
||||
|
||||
public async Task<InputOnlineFile> DownloadAudio()
|
||||
{
|
||||
var encryptedContent = new System.IO.MemoryStream(this.Audio.FileSize);
|
||||
var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Audio.FileId, encryptedContent);
|
||||
|
||||
return new InputOnlineFile(encryptedContent, "");
|
||||
}
|
||||
|
||||
public async Task DownloadAudio(String path)
|
||||
{
|
||||
var file = await this.Client.TelegramClient.GetFileAsync(this.Audio.FileId);
|
||||
FileStream fs = new FileStream(path, FileMode.Create);
|
||||
await this.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
|
||||
fs.Close();
|
||||
fs.Dispose();
|
||||
}
|
||||
|
||||
public async Task<InputOnlineFile> DownloadPhoto(int index)
|
||||
{
|
||||
var photo = this.Photos[index];
|
||||
var encryptedContent = new System.IO.MemoryStream(photo.FileSize);
|
||||
var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(photo.FileId, encryptedContent);
|
||||
|
||||
return new InputOnlineFile(encryptedContent, "");
|
||||
}
|
||||
|
||||
public async Task DownloadPhoto(int index, String path)
|
||||
{
|
||||
var photo = this.Photos[index];
|
||||
var file = await this.Client.TelegramClient.GetFileAsync(photo.FileId);
|
||||
FileStream fs = new FileStream(path, FileMode.Create);
|
||||
await this.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
|
||||
fs.Close();
|
||||
fs.Dispose();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Sessions;
|
||||
using static TelegramBotBase.Base.Async;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -13,47 +16,148 @@ namespace TelegramBotBase.Form
|
||||
/// </summary>
|
||||
public class FormBase : IDisposable
|
||||
{
|
||||
|
||||
public DeviceSession Device { get; set; }
|
||||
|
||||
public MessageClient Client { get; set; }
|
||||
|
||||
public bool CustomEventManagement { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// contains if the form has been switched (navigated)
|
||||
/// has this formular already been disposed ?
|
||||
/// </summary>
|
||||
public bool FormSwitched { get; set; } = false;
|
||||
public bool IsDisposed { get; set; } = false;
|
||||
|
||||
public List<ControlBase> Controls { get; set; }
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
public async Task OnInit(InitEventArgs e)
|
||||
{
|
||||
if (this.Events[__evInit] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evInit].GetInvocationList().Cast<AsyncEventHandler<InitEventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<InitEventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Will get called at the initialization (once per context)
|
||||
///// </summary>
|
||||
public event AsyncEventHandler<InitEventArgs> Init
|
||||
{
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evInit, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evInit, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task OnOpened(EventArgs e)
|
||||
{
|
||||
if (this.Events[__evOpened] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evOpened].GetInvocationList().Cast<AsyncEventHandler<EventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<EventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will get called at the initialization (once per context)
|
||||
/// Gets invoked if gets navigated to this form
|
||||
/// </summary>
|
||||
public virtual async Task Init(params object[] args)
|
||||
/// <returns></returns>
|
||||
public event AsyncEventHandler<EventArgs> Opened
|
||||
{
|
||||
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evOpened, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evOpened, value);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task Opened()
|
||||
|
||||
|
||||
public async Task OnClosed(EventArgs e)
|
||||
{
|
||||
if (this.Events[__evClosed] == null)
|
||||
return;
|
||||
|
||||
var handler = this.Events[__evClosed].GetInvocationList().Cast<AsyncEventHandler<EventArgs>>();
|
||||
foreach (var h in handler)
|
||||
{
|
||||
await Async.InvokeAllAsync<EventArgs>(h, this, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <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>
|
||||
/// Get invoked when a modal child from has been closed.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task ReturnFromModal(ModalDialog modal)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual async Task Closed()
|
||||
|
||||
/// <summary>
|
||||
/// Pre to form close, cleanup all controls
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task CloseControls()
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
await b.Cleanup();
|
||||
b.Cleanup().Wait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,44 +166,248 @@ 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>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked, when a messages has been edited.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task Edited(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the user clicked a button.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task ActionControls(MessageResult message)
|
||||
{
|
||||
//Looking for the control by id, if not listened, raise event for all
|
||||
if (message.RawData.StartsWith("#c"))
|
||||
{
|
||||
var c = this.Controls.FirstOrDefault(a => a.ControlID == message.RawData.Split('_')[0]);
|
||||
if (c != null)
|
||||
{
|
||||
await c.Action(message, message.RawData.Split('_')[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
if (!b.Enabled)
|
||||
continue;
|
||||
|
||||
await b.Action(message);
|
||||
|
||||
if (message.Handled)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the user has clicked a button.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task Action(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked if the user has sent some media (Photo, Audio, Video, Contact, Location, Document)
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task SentData(DataResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked at the end of the cycle to "Render" text, images, buttons, etc...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task RenderControls(MessageResult message)
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
if (!b.Enabled)
|
||||
continue;
|
||||
|
||||
await b.Render(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets invoked at the end of the cycle to "Render" text, images, buttons, etc...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task Render(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Navigates to a new form
|
||||
/// </summary>
|
||||
/// <param name="newForm"></param>
|
||||
/// <returns></returns>
|
||||
public async Task NavigateTo(FormBase newForm, params object[] args)
|
||||
public virtual async Task NavigateTo(FormBase newForm, params object[] args)
|
||||
{
|
||||
DeviceSession ds = this.Device;
|
||||
if (ds == null)
|
||||
return;
|
||||
|
||||
this.FormSwitched = true;
|
||||
ds.FormSwitched = true;
|
||||
|
||||
ds.PreviousForm = ds.ActiveForm;
|
||||
|
||||
ds.ActiveForm = newForm;
|
||||
newForm.Client = this.Client;
|
||||
newForm.Device = ds;
|
||||
|
||||
await newForm.Init(args);
|
||||
//Notify prior to close
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
if (!b.Enabled)
|
||||
continue;
|
||||
|
||||
await this.Closed();
|
||||
await b.Hidden(true);
|
||||
}
|
||||
|
||||
await newForm.Opened();
|
||||
this.CloseControls().Wait();
|
||||
|
||||
await this.OnClosed(new EventArgs());
|
||||
|
||||
await newForm.OnInit(new InitEventArgs(args));
|
||||
|
||||
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 virtual 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.ParentForm = parentForm;
|
||||
|
||||
newForm.Closed += async (s, en) =>
|
||||
{
|
||||
await CloseModal(newForm, parentForm);
|
||||
};
|
||||
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
if (!b.Enabled)
|
||||
continue;
|
||||
|
||||
await b.Hidden(false);
|
||||
}
|
||||
|
||||
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>
|
||||
@@ -109,7 +417,7 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
this.Client = null;
|
||||
this.Device = null;
|
||||
this.FormSwitched = false;
|
||||
this.IsDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -21,6 +23,8 @@ namespace TelegramBotBase.Base
|
||||
|
||||
private static object __evOnMessage = new object();
|
||||
|
||||
private static object __evOnMessageEdit = new object();
|
||||
|
||||
private static object __evCallbackQuery = new object();
|
||||
|
||||
|
||||
@@ -32,6 +36,43 @@ namespace TelegramBotBase.Base
|
||||
Prepare();
|
||||
}
|
||||
|
||||
public MessageClient(String APIKey, HttpClient proxy)
|
||||
{
|
||||
this.APIKey = APIKey;
|
||||
this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, proxy);
|
||||
|
||||
|
||||
Prepare();
|
||||
}
|
||||
|
||||
public MessageClient(String APIKey, Uri proxyUrl)
|
||||
{
|
||||
this.APIKey = APIKey;
|
||||
|
||||
var proxy = new WebProxy(proxyUrl);
|
||||
|
||||
this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, proxy);
|
||||
|
||||
Prepare();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the client with a proxy
|
||||
/// </summary>
|
||||
/// <param name="APIKey"></param>
|
||||
/// <param name="proxyHost">i.e. 127.0.0.1</param>
|
||||
/// <param name="proxyPort">i.e. 10000</param>
|
||||
public MessageClient(String APIKey, String proxyHost, int proxyPort)
|
||||
{
|
||||
this.APIKey = APIKey;
|
||||
|
||||
var proxy = new WebProxy(proxyHost, proxyPort);
|
||||
|
||||
this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, proxy);
|
||||
|
||||
Prepare();
|
||||
}
|
||||
|
||||
public MessageClient(String APIKey, Telegram.Bot.TelegramBotClient Client)
|
||||
{
|
||||
this.APIKey = APIKey;
|
||||
@@ -45,13 +86,11 @@ namespace TelegramBotBase.Base
|
||||
{
|
||||
this.TelegramClient.Timeout = new TimeSpan(0, 0, 30);
|
||||
|
||||
|
||||
this.TelegramClient.OnMessage += TelegramClient_OnMessage;
|
||||
this.TelegramClient.OnMessageEdited += TelegramClient_OnMessageEdited;
|
||||
this.TelegramClient.OnCallbackQuery += TelegramClient_OnCallbackQuery;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private async void TelegramClient_OnMessage(object sender, Telegram.Bot.Args.MessageEventArgs e)
|
||||
{
|
||||
//Skip empty messages by default
|
||||
@@ -70,6 +109,25 @@ namespace TelegramBotBase.Base
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async void TelegramClient_OnMessageEdited(object sender, Telegram.Bot.Args.MessageEventArgs e)
|
||||
{
|
||||
//Skip empty messages by default
|
||||
if (e.Message == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var mr = new MessageResult(e);
|
||||
mr.Client = this;
|
||||
OnMessageEdit(mr);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private async void TelegramClient_OnCallbackQuery(object sender, Telegram.Bot.Args.CallbackQueryEventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -104,6 +162,23 @@ namespace TelegramBotBase.Base
|
||||
(this.__Events[__evOnMessage] as EventHandler<MessageResult>)?.Invoke(this, result);
|
||||
}
|
||||
|
||||
public event EventHandler<MessageResult> MessageEdit
|
||||
{
|
||||
add
|
||||
{
|
||||
this.__Events.AddHandler(__evOnMessageEdit, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.__Events.RemoveHandler(__evOnMessageEdit, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMessageEdit(MessageResult result)
|
||||
{
|
||||
(this.__Events[__evOnMessageEdit] as EventHandler<MessageResult>)?.Invoke(this, result);
|
||||
}
|
||||
|
||||
public event EventHandler<MessageResult> Action
|
||||
{
|
||||
add
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
@@ -23,6 +24,9 @@ namespace TelegramBotBase.Base
|
||||
}
|
||||
}
|
||||
|
||||
public DeviceSession Device
|
||||
{ get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The message id
|
||||
/// </summary>
|
||||
@@ -50,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>
|
||||
@@ -62,7 +74,7 @@ namespace TelegramBotBase.Base
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this a system call ? Starts with a slash and command
|
||||
/// Is this a system call ? Starts with a slash '/' and a command
|
||||
/// </summary>
|
||||
public bool IsSystemCall
|
||||
{
|
||||
@@ -101,6 +113,11 @@ namespace TelegramBotBase.Base
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if this message will be used on the first form or not.
|
||||
/// </summary>
|
||||
public bool IsFirstHandler { get; set; } = true;
|
||||
|
||||
public bool Handled { get; set; } = false;
|
||||
|
||||
public String RawData
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public class ResultBase
|
||||
public class ResultBase : EventArgs
|
||||
{
|
||||
public MessageClient Client { get; set; }
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
public partial class StateContainer
|
||||
{
|
||||
public List<StateEntry> States { get; set; }
|
||||
|
||||
public List<long> ChatIds
|
||||
{
|
||||
get
|
||||
{
|
||||
return States.Where(a => a.DeviceId > 0).Select(a => a.DeviceId).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public List<long> GroupIds
|
||||
{
|
||||
get
|
||||
{
|
||||
return States.Where(a => a.DeviceId < 0).Select(a => a.DeviceId).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public StateContainer()
|
||||
{
|
||||
this.States = new List<StateEntry>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace TelegramBotBase.Base
|
||||
{
|
||||
|
||||
[DebuggerDisplay("Device: {DeviceId}, {FormUri}")]
|
||||
public class StateEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the DeviceId of the entry.
|
||||
/// </summary>
|
||||
public long DeviceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the Username (on privat chats) or Group title on groups/channels.
|
||||
/// </summary>
|
||||
public String ChatTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains additional values to save.
|
||||
/// </summary>
|
||||
public Dictionary<String, object> Values { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the full qualified namespace of the form to used for reload it via reflection.
|
||||
/// </summary>
|
||||
public String FormUri {get;set;}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the assembly, where to find that form.
|
||||
/// </summary>
|
||||
public String QualifiedName { get; set; }
|
||||
|
||||
public StateEntry()
|
||||
{
|
||||
this.Values = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+238
-51
@@ -4,8 +4,12 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Attributes;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Interfaces;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase
|
||||
@@ -42,6 +46,8 @@ namespace TelegramBotBase
|
||||
|
||||
private static object __evSystemCall = new object();
|
||||
|
||||
public delegate Task SystemCallEventHandler(object sender, SystemCallEventArgs e);
|
||||
|
||||
private static object __evException = new object();
|
||||
|
||||
private static object __evUnhandledCall = new object();
|
||||
@@ -57,6 +63,11 @@ namespace TelegramBotBase
|
||||
/// </summary>
|
||||
public bool LogAllMessages { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enable the SessionState (you need to implement on call forms the IStateForm interface)
|
||||
/// </summary>
|
||||
public IStateMachine StateMachine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How often could a form navigate to another (within one user action/call/message)
|
||||
/// </summary>
|
||||
@@ -71,6 +82,78 @@ namespace TelegramBotBase
|
||||
this.APIKey = apiKey;
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey);
|
||||
this.Client.TelegramClient.Timeout = new TimeSpan(0, 1, 0);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
this.Sessions = new SessionBase();
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple start of your Bot with the APIKey and a proxyAdress
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="proxyBaseAddress">i.e. https://127.0.0.1:10000</param>
|
||||
public BotBase(String apiKey, System.Net.Http.HttpClient proxy)
|
||||
{
|
||||
this.APIKey = apiKey;
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey, proxy);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
this.Sessions = new SessionBase();
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple start of your Bot with the APIKey and a TelegramBotClient instance.
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="client"></param>
|
||||
public BotBase(String apiKey, TelegramBotClient client)
|
||||
{
|
||||
this.APIKey = apiKey;
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey, client);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
this.Sessions = new SessionBase();
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple start of your Bot with the APIKey and a proxyAdress
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="proxyBaseAddress">i.e. https://127.0.0.1:10000</param>
|
||||
public BotBase(String apiKey, String proxyBaseAddress)
|
||||
{
|
||||
this.APIKey = apiKey;
|
||||
|
||||
var url = new Uri(proxyBaseAddress);
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey, url);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
this.Sessions = new SessionBase();
|
||||
this.Sessions.Client = this.Client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple start of your Bot with the APIKey and a proxyAdress
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="proxyHost">i.e. 127.0.0.1</param>
|
||||
/// <param name="proxyPort">i.e. 10000</param>
|
||||
public BotBase(String apiKey, String proxyHost, int proxyPort)
|
||||
{
|
||||
this.APIKey = apiKey;
|
||||
|
||||
this.Client = new Base.MessageClient(this.APIKey, proxyHost, proxyPort);
|
||||
|
||||
this.SystemCalls = new List<string>();
|
||||
|
||||
@@ -87,12 +170,18 @@ namespace TelegramBotBase
|
||||
return;
|
||||
|
||||
this.Client.Message += Client_Message;
|
||||
this.Client.MessageEdit += Client_MessageEdit;
|
||||
this.Client.Action += Client_Action;
|
||||
|
||||
if (this.StateMachine != null)
|
||||
{
|
||||
this.Sessions.LoadSessionStates(this.StateMachine);
|
||||
}
|
||||
|
||||
this.Client.TelegramClient.StartReceiving();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Stop your Bot
|
||||
/// </summary>
|
||||
@@ -101,7 +190,15 @@ namespace TelegramBotBase
|
||||
if (this.Client == null)
|
||||
return;
|
||||
|
||||
this.Client.Message -= Client_Message;
|
||||
this.Client.Action -= Client_Action;
|
||||
|
||||
this.Client.TelegramClient.StopReceiving();
|
||||
|
||||
if (this.StateMachine != null)
|
||||
{
|
||||
this.Sessions.SaveSessionStates(this.StateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -120,21 +217,24 @@ namespace TelegramBotBase
|
||||
}
|
||||
}
|
||||
|
||||
private void Client_Message(object sender, MessageResult e)
|
||||
private async void Client_Message(object sender, MessageResult e)
|
||||
{
|
||||
if (this.SkipAllMessages)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
if (LogAllMessages)
|
||||
{
|
||||
DeviceSession ds2 = this.Sessions.GetSession(e.DeviceId);
|
||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds2, e));
|
||||
OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e));
|
||||
}
|
||||
|
||||
ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message));
|
||||
|
||||
Client_TryMessage(sender, e);
|
||||
await Client_TryMessage(sender, e);
|
||||
}
|
||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||
{
|
||||
@@ -147,28 +247,31 @@ namespace TelegramBotBase
|
||||
}
|
||||
}
|
||||
|
||||
private async void Client_TryMessage(object sender, MessageResult e)
|
||||
private async Task Client_TryMessage(object sender, MessageResult e)
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
DeviceSession ds = e.Device;
|
||||
if (ds == null)
|
||||
{
|
||||
ds = await this.Sessions.StartSession<T>(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
ds.LastMessage = e.MessageId;
|
||||
ds.LastMessage = e.Message;
|
||||
|
||||
OnSessionBegins(new SessionBeginResult(e.DeviceId, ds));
|
||||
OnSessionBegins(new SessionBeginEventArgs(e.DeviceId, ds));
|
||||
}
|
||||
|
||||
ds.ChatTitle = e.Message.Chat.Username ?? e.Message.Chat.Title;
|
||||
ds.LastAction = DateTime.Now;
|
||||
ds.LastMessage = e.MessageId;
|
||||
ds.LastMessage = e.Message;
|
||||
|
||||
//Is this a systemcall ?
|
||||
if (e.IsSystemCall && this.SystemCalls.Contains(e.SystemCommand))
|
||||
{
|
||||
var sce = new SystemCallEventArgs(e.SystemCommand, e.SystemCallParameters, ds.DeviceId, ds);
|
||||
OnSystemCall(sce);
|
||||
var sce = new SystemCallEventArgs(e.SystemCommand, e.SystemCallParameters, e.Message, ds.DeviceId, ds);
|
||||
await OnSystemCall(sce);
|
||||
|
||||
return;
|
||||
if (sce.Handled)
|
||||
return;
|
||||
}
|
||||
|
||||
FormBase activeForm = null;
|
||||
@@ -180,23 +283,94 @@ namespace TelegramBotBase
|
||||
{
|
||||
i++;
|
||||
|
||||
activeForm = ds.ActiveForm;
|
||||
//Reset navigation
|
||||
ds.FormSwitched = false;
|
||||
|
||||
//If the form manages the events by itselfs, skip here
|
||||
if (activeForm.CustomEventManagement)
|
||||
return;
|
||||
activeForm = ds.ActiveForm;
|
||||
|
||||
//Pre Loading Event
|
||||
await activeForm.PreLoad(e);
|
||||
|
||||
//Send Load event to controls
|
||||
await activeForm.LoadControls(e);
|
||||
|
||||
//Loading Event
|
||||
await activeForm.Load(e);
|
||||
|
||||
//Render Event
|
||||
if (!activeForm.FormSwitched)
|
||||
await activeForm.Render(e);
|
||||
//Is Attachment ? (Photo, Audio, Video, Contact, Location, Document)
|
||||
if (e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Contact | e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Document | e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Location |
|
||||
e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Photo | e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Video | e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Audio)
|
||||
{
|
||||
await activeForm.SentData(new DataResult(e));
|
||||
}
|
||||
|
||||
} while (activeForm.FormSwitched && i < NavigationMaximum);
|
||||
//Render Event
|
||||
if (!ds.FormSwitched)
|
||||
{
|
||||
await activeForm.RenderControls(e);
|
||||
|
||||
await activeForm.Render(e);
|
||||
}
|
||||
|
||||
e.IsFirstHandler = false;
|
||||
|
||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private async void Client_MessageEdit(object sender, MessageResult e)
|
||||
{
|
||||
if (this.SkipAllMessages)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
if (LogAllMessages)
|
||||
{
|
||||
OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e));
|
||||
}
|
||||
|
||||
//Call same, to handle received liked edited
|
||||
ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message));
|
||||
|
||||
await Client_TryMessageEdit(sender, e);
|
||||
}
|
||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Client_TryMessageEdit(object sender, MessageResult e)
|
||||
{
|
||||
DeviceSession ds = e.Device;
|
||||
if (ds == null)
|
||||
{
|
||||
ds = await this.Sessions.StartSession<T>(e.DeviceId);
|
||||
e.Device = ds;
|
||||
}
|
||||
|
||||
ds.ChatTitle = e.Message.Chat.Username ?? e.Message.Chat.Title;
|
||||
ds.LastAction = DateTime.Now;
|
||||
ds.LastMessage = e.Message;
|
||||
|
||||
//Pre Loading Event
|
||||
await ds.ActiveForm.Edited(e);
|
||||
|
||||
//When form has been switched due navigation within the edit method, reopen Client_Message
|
||||
if (ds.FormSwitched)
|
||||
{
|
||||
await Client_TryMessage(sender, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -204,6 +378,14 @@ namespace TelegramBotBase
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
e.Device = ds;
|
||||
|
||||
if (LogAllMessages)
|
||||
{
|
||||
OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e));
|
||||
}
|
||||
|
||||
Client_TryAction(sender, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -215,15 +397,16 @@ namespace TelegramBotBase
|
||||
|
||||
private async void Client_TryAction(object sender, MessageResult e)
|
||||
{
|
||||
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
|
||||
DeviceSession ds = e.Device;
|
||||
if (ds == null)
|
||||
{
|
||||
ds = await this.Sessions.StartSession<T>(e.DeviceId);
|
||||
e.Device = ds;
|
||||
}
|
||||
|
||||
|
||||
ds.ChatTitle = e.Message.Chat.Username ?? e.Message.Chat.Title;
|
||||
ds.LastAction = DateTime.Now;
|
||||
ds.LastMessage = e.MessageId;
|
||||
ds.LastMessage = e.Message;
|
||||
|
||||
FormBase activeForm = null;
|
||||
|
||||
@@ -234,21 +417,27 @@ namespace TelegramBotBase
|
||||
{
|
||||
i++;
|
||||
|
||||
activeForm = ds.ActiveForm;
|
||||
//Reset navigation
|
||||
ds.FormSwitched = false;
|
||||
|
||||
//If the form manages the events by itselfs, skip here
|
||||
if (activeForm.CustomEventManagement)
|
||||
return;
|
||||
activeForm = ds.ActiveForm;
|
||||
|
||||
//Pre Loading Event
|
||||
await activeForm.PreLoad(e);
|
||||
|
||||
//Send Load event to controls
|
||||
await activeForm.LoadControls(e);
|
||||
|
||||
//Loading Event
|
||||
await activeForm.Load(e);
|
||||
|
||||
//Action Event
|
||||
if (!activeForm.FormSwitched)
|
||||
if (!ds.FormSwitched)
|
||||
{
|
||||
//Send Action event to controls
|
||||
await activeForm.ActionControls(e);
|
||||
|
||||
//Send Action event to form itself
|
||||
await activeForm.Action(e);
|
||||
|
||||
if (!e.Handled)
|
||||
@@ -258,7 +447,7 @@ namespace TelegramBotBase
|
||||
|
||||
if (uhc.Handled)
|
||||
{
|
||||
if (activeForm.FormSwitched)
|
||||
if (ds.FormSwitched)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -272,10 +461,16 @@ namespace TelegramBotBase
|
||||
}
|
||||
|
||||
//Render Event
|
||||
if (!activeForm.FormSwitched)
|
||||
await activeForm.Render(e);
|
||||
if (!ds.FormSwitched)
|
||||
{
|
||||
await activeForm.RenderControls(e);
|
||||
|
||||
} while (activeForm.FormSwitched && i < NavigationMaximum);
|
||||
await activeForm.Render(e);
|
||||
}
|
||||
|
||||
e.IsFirstHandler = false;
|
||||
|
||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
||||
|
||||
}
|
||||
|
||||
@@ -283,7 +478,7 @@ namespace TelegramBotBase
|
||||
/// Will be called if a session/context gets started
|
||||
/// </summary>
|
||||
|
||||
public event EventHandler<SessionBeginResult> SessionBegins
|
||||
public event EventHandler<SessionBeginEventArgs> SessionBegins
|
||||
{
|
||||
add
|
||||
{
|
||||
@@ -295,16 +490,16 @@ namespace TelegramBotBase
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSessionBegins(SessionBeginResult e)
|
||||
public void OnSessionBegins(SessionBeginEventArgs e)
|
||||
{
|
||||
(this.__Events[__evSessionBegins] as EventHandler<SessionBeginResult>)?.Invoke(this, e);
|
||||
(this.__Events[__evSessionBegins] as EventHandler<SessionBeginEventArgs>)?.Invoke(this, e);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will be called on incomming message
|
||||
/// </summary>
|
||||
public event EventHandler<MessageIncomeResult> Message
|
||||
public event EventHandler<MessageIncomeEventArgs> Message
|
||||
{
|
||||
add
|
||||
{
|
||||
@@ -316,30 +511,22 @@ namespace TelegramBotBase
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMessage(MessageIncomeResult e)
|
||||
public void OnMessage(MessageIncomeEventArgs e)
|
||||
{
|
||||
(this.__Events[__evMessage] as EventHandler<MessageIncomeResult>)?.Invoke(this, e);
|
||||
(this.__Events[__evMessage] as EventHandler<MessageIncomeEventArgs>)?.Invoke(this, e);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will be called if a system call gets raised
|
||||
/// </summary>
|
||||
public event EventHandler<SystemCallEventArgs> SystemCall
|
||||
{
|
||||
add
|
||||
{
|
||||
this.__Events.AddHandler(__evSystemCall, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.__Events.RemoveHandler(__evSystemCall, value);
|
||||
}
|
||||
}
|
||||
public event SystemCallEventHandler SystemCall;
|
||||
|
||||
public void OnSystemCall(SystemCallEventArgs e)
|
||||
|
||||
public async Task OnSystemCall(SystemCallEventArgs e)
|
||||
{
|
||||
(this.__Events[__evSystemCall] as EventHandler<SystemCallEventArgs>)?.Invoke(this, e);
|
||||
if (this.SystemCall != null)
|
||||
await SystemCall(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
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;
|
||||
|
||||
public const int MaxInlineKeyBoardRows = 13;
|
||||
|
||||
public const int MaxInlineKeyBoardCols = 8;
|
||||
|
||||
public const int MaxReplyKeyboardRows = 25;
|
||||
|
||||
public const int MaxReplyKeyboardCols = 12;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
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.Enums;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Exceptions;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class ButtonGrid : Base.ControlBase
|
||||
{
|
||||
|
||||
public String Title { get; set; } = "Toggle";
|
||||
|
||||
public String ConfirmationText { get; set; } = "";
|
||||
|
||||
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>
|
||||
/// Optional. Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). Defaults to false, in which case the custom keyboard is always of the same height as the app's standard keyboard.
|
||||
/// Source: https://core.telegram.org/bots/api#replykeyboardmarkup
|
||||
/// </summary>
|
||||
public bool ResizeKeyboard { get; set; } = false;
|
||||
|
||||
public bool OneTimeKeyboard { get; set; } = false;
|
||||
|
||||
public bool HideKeyboardOnCleanup { get; set; } = true;
|
||||
|
||||
public bool DeletePreviousMessage { get; set; } = true;
|
||||
|
||||
public ParseMode MessageParseMode { get; set; } = ParseMode.Default;
|
||||
|
||||
/// <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;
|
||||
|
||||
public ButtonGrid()
|
||||
{
|
||||
this.ButtonsForm = new ButtonForm();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ButtonGrid(eKeyboardType type) : this()
|
||||
{
|
||||
m_eKeyboardType = type;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (!result.IsFirstHandler)
|
||||
return;
|
||||
|
||||
var button = ButtonsForm.ToList().FirstOrDefault(a => a.Text.Trim() == result.MessageText);
|
||||
|
||||
if (button == null)
|
||||
return;
|
||||
|
||||
OnButtonClicked(new ButtonClickedEventArgs(button));
|
||||
|
||||
//Remove button click message
|
||||
if (this.DeletePreviousMessage)
|
||||
await Device.DeleteMessage(result.MessageId);
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
}
|
||||
|
||||
public async override Task Action(MessageResult result, string value = null)
|
||||
{
|
||||
if (result.Handled)
|
||||
return;
|
||||
|
||||
if (!result.IsFirstHandler)
|
||||
return;
|
||||
|
||||
await result.ConfirmAction(this.ConfirmationText ?? "");
|
||||
|
||||
//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;
|
||||
|
||||
|
||||
switch (m_eKeyboardType)
|
||||
{
|
||||
case eKeyboardType.InlineKeyBoard:
|
||||
|
||||
if (ButtonsForm.Rows > Constants.Telegram.MaxInlineKeyBoardRows)
|
||||
{
|
||||
throw new MaximumRowsReachedException() { Value = ButtonsForm.Rows, Maximum = Constants.Telegram.MaxInlineKeyBoardRows };
|
||||
}
|
||||
|
||||
if (ButtonsForm.Cols > Constants.Telegram.MaxInlineKeyBoardCols)
|
||||
{
|
||||
throw new MaximumColsException() { Value = ButtonsForm.Rows, Maximum = Constants.Telegram.MaxInlineKeyBoardCols };
|
||||
}
|
||||
|
||||
break;
|
||||
case eKeyboardType.ReplyKeyboard:
|
||||
|
||||
if (ButtonsForm.Rows > Constants.Telegram.MaxReplyKeyboardRows)
|
||||
{
|
||||
throw new MaximumRowsReachedException() { Value = ButtonsForm.Rows, Maximum = Constants.Telegram.MaxReplyKeyboardRows };
|
||||
}
|
||||
|
||||
if (ButtonsForm.Cols > Constants.Telegram.MaxReplyKeyboardCols)
|
||||
{
|
||||
throw new MaximumColsException() { Value = ButtonsForm.Rows, Maximum = Constants.Telegram.MaxReplyKeyboardCols };
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
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.HideReplyKeyboard();
|
||||
this.MessageId = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.DeletePreviousMessage)
|
||||
await this.Device.DeleteMessage(this.MessageId.Value);
|
||||
|
||||
var rkm = (ReplyKeyboardMarkup)this.ButtonsForm;
|
||||
rkm.ResizeKeyboard = this.ResizeKeyboard;
|
||||
rkm.OneTimeKeyboard = this.OneTimeKeyboard;
|
||||
m = await this.Device.Send(this.Title, rkm, disableNotification: true, parseMode: MessageParseMode);
|
||||
}
|
||||
|
||||
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:
|
||||
var rkm = (ReplyKeyboardMarkup)this.ButtonsForm;
|
||||
rkm.ResizeKeyboard = this.ResizeKeyboard;
|
||||
rkm.OneTimeKeyboard = this.OneTimeKeyboard;
|
||||
m = await this.Device.Send(this.Title, rkm, disableNotification: true, parseMode: MessageParseMode);
|
||||
break;
|
||||
|
||||
case eKeyboardType.InlineKeyBoard:
|
||||
m = await this.Device.Send(this.Title, (InlineKeyboardMarkup)this.ButtonsForm, disableNotification: true, parseMode: MessageParseMode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m != null)
|
||||
{
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
this.RenderNecessary = false;
|
||||
|
||||
}
|
||||
|
||||
public override async Task Hidden(bool FormClose)
|
||||
{
|
||||
//Prepare for opening Modal, and comming back
|
||||
if (!FormClose)
|
||||
{
|
||||
this.Updated();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the control that it has been updated.
|
||||
/// </summary>
|
||||
public void Updated()
|
||||
{
|
||||
this.RenderNecessary = true;
|
||||
}
|
||||
|
||||
public async override Task Cleanup()
|
||||
{
|
||||
if (this.MessageId == null)
|
||||
return;
|
||||
|
||||
switch (this.KeyboardType)
|
||||
{
|
||||
case eKeyboardType.InlineKeyBoard:
|
||||
|
||||
await this.Device.DeleteMessage(this.MessageId.Value);
|
||||
|
||||
this.MessageId = null;
|
||||
|
||||
break;
|
||||
case eKeyboardType.ReplyKeyboard:
|
||||
|
||||
if (this.HideKeyboardOnCleanup)
|
||||
{
|
||||
await this.Device.HideReplyKeyboard();
|
||||
}
|
||||
|
||||
this.MessageId = null;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
using static TelegramBotBase.Tools.Arrays;
|
||||
using static TelegramBotBase.Tools.Time;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class CalendarPicker : Base.ControlBase
|
||||
{
|
||||
|
||||
public DateTime SelectedDate { get; set; }
|
||||
|
||||
public DateTime VisibleMonth { get; set; }
|
||||
|
||||
public DayOfWeek FirstDayOfWeek { get; set; }
|
||||
|
||||
public CultureInfo Culture { get; set; }
|
||||
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public String Title { get; set; } = "Pick Date";
|
||||
|
||||
public eMonthPickerMode PickerMode { get; set; }
|
||||
|
||||
public bool EnableDayView { get; set; } = true;
|
||||
|
||||
public bool EnableMonthView { get; set; } = true;
|
||||
|
||||
public bool EnableYearView { get; set; } = true;
|
||||
|
||||
public CalendarPicker()
|
||||
{
|
||||
this.SelectedDate = DateTime.Today;
|
||||
this.VisibleMonth = DateTime.Today;
|
||||
this.FirstDayOfWeek = DayOfWeek.Monday;
|
||||
this.Culture = new CultureInfo("de-de");
|
||||
this.PickerMode = eMonthPickerMode.day;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
await result.ConfirmAction();
|
||||
|
||||
switch (result.RawData)
|
||||
{
|
||||
case "next":
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
this.VisibleMonth = this.VisibleMonth.AddMonths(1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(10);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case "prev":
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
this.VisibleMonth = this.VisibleMonth.AddMonths(-1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(-1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(-10);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "monthtitle":
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "yeartitle":
|
||||
|
||||
if (this.EnableYearView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.year;
|
||||
}
|
||||
|
||||
break;
|
||||
case "yearstitle":
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
int day = 0;
|
||||
if (result.RawData.StartsWith("d-") && int.TryParse(result.RawData.Split('-')[1], out day))
|
||||
{
|
||||
this.SelectedDate = new DateTime(this.VisibleMonth.Year, this.VisibleMonth.Month, day);
|
||||
}
|
||||
|
||||
int month = 0;
|
||||
if (result.RawData.StartsWith("m-") && int.TryParse(result.RawData.Split('-')[1], out month))
|
||||
{
|
||||
this.SelectedDate = new DateTime(this.VisibleMonth.Year, month, 1);
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
if (this.EnableDayView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.day;
|
||||
}
|
||||
}
|
||||
|
||||
int year = 0;
|
||||
if (result.RawData.StartsWith("y-") && int.TryParse(result.RawData.Split('-')[1], out year))
|
||||
{
|
||||
this.SelectedDate = new DateTime(year, SelectedDate.Month, SelectedDate.Day);
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
|
||||
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
|
||||
var month = this.VisibleMonth;
|
||||
|
||||
string[] dayNamesNormal = this.Culture.DateTimeFormat.ShortestDayNames;
|
||||
string[] dayNamesShifted = Shift(dayNamesNormal, (int)this.FirstDayOfWeek);
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase(this.Culture.DateTimeFormat.MonthNames[month.Month - 1] + " " + month.Year.ToString(), "monthtitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
bf.AddButtonRow(dayNamesShifted.Select(a => new ButtonBase(a, a)).ToList());
|
||||
|
||||
//First Day of month
|
||||
var firstDay = new DateTime(month.Year, month.Month, 1);
|
||||
|
||||
//Last Day of month
|
||||
var lastDay = firstDay.LastDayOfMonth();
|
||||
|
||||
//Start of Week where first day of month is (left border)
|
||||
var start = firstDay.StartOfWeek(this.FirstDayOfWeek);
|
||||
|
||||
//End of week where last day of month is (right border)
|
||||
var end = lastDay.EndOfWeek(this.FirstDayOfWeek);
|
||||
|
||||
for (int i = 0; i <= ((end - start).Days / 7); i++)
|
||||
{
|
||||
var lst = new List<ButtonBase>();
|
||||
for (int id = 0; id < 7; id++)
|
||||
{
|
||||
var d = start.AddDays((i * 7) + id);
|
||||
if (d < firstDay | d > lastDay)
|
||||
{
|
||||
lst.Add(new ButtonBase("-", "m-" + d.Day.ToString()));
|
||||
continue;
|
||||
}
|
||||
|
||||
var day = d.Day.ToString();
|
||||
|
||||
if (d == DateTime.Today)
|
||||
{
|
||||
day = "(" + day + ")";
|
||||
}
|
||||
|
||||
lst.Add(new ButtonBase((this.SelectedDate == d ? "[" + day + "]" : day), "d-" + d.Day.ToString()));
|
||||
}
|
||||
bf.AddButtonRow(lst);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase(this.VisibleMonth.Year.ToString("0000"), "yeartitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
var months = this.Culture.DateTimeFormat.MonthNames;
|
||||
|
||||
var buttons = months.Select((a, b) => new ButtonBase((b == this.SelectedDate.Month - 1 && this.SelectedDate.Year == this.VisibleMonth.Year ? "[ " + a + " ]" : a), "m-" + (b + 1).ToString()));
|
||||
|
||||
bf.AddSplitted(buttons, 2);
|
||||
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("<<", "prev"), new ButtonBase("Year", "yearstitle"), new ButtonBase(">>", "next"));
|
||||
|
||||
var starti = Math.Floor(this.VisibleMonth.Year / 10f) * 10;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var m = starti + (i * 2);
|
||||
bf.AddButtonRow(new ButtonBase((this.SelectedDate.Year == m ? "[ " + m.ToString() + " ]" : m.ToString()), "y-" + m.ToString()), new ButtonBase((this.SelectedDate.Year == (m + 1) ? "[ " + (m + 1).ToString() + " ]" : (m + 1).ToString()), "y-" + (m + 1).ToString()));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Cleanup()
|
||||
{
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
await this.Device.DeleteMessage(this.MessageId.Value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class MonthPicker : CalendarPicker
|
||||
{
|
||||
|
||||
|
||||
|
||||
public MonthPicker()
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
this.EnableDayView = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
@@ -220,7 +221,7 @@ namespace TelegramBotBase.Controls
|
||||
|
||||
}
|
||||
|
||||
public async override Task Render()
|
||||
public async override Task Render(MessageResult result)
|
||||
{
|
||||
if (!this.RenderNecessary)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class ToggleButton : ControlBase
|
||||
{
|
||||
|
||||
public String UncheckedIcon { get; set; } = "⚪";
|
||||
|
||||
public String CheckedIcon { get; set; } = "⚫";
|
||||
|
||||
public String CheckedString { get; set; } = "On";
|
||||
|
||||
public String UncheckedString { get; set; } = "Off";
|
||||
|
||||
public String Title { get; set; } = "Toggle";
|
||||
|
||||
public int? MessageId { get; set; }
|
||||
|
||||
public bool Checked { get; set; }
|
||||
|
||||
private bool RenderNecessary = true;
|
||||
|
||||
private static readonly object __evToggled = new object();
|
||||
|
||||
private readonly EventHandlerList Events = new EventHandlerList();
|
||||
|
||||
|
||||
public ToggleButton()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ToggleButton(String CheckedString, String UncheckedString)
|
||||
{
|
||||
this.CheckedString = CheckedString;
|
||||
this.UncheckedString = UncheckedString;
|
||||
}
|
||||
|
||||
public event EventHandler Toggled
|
||||
{
|
||||
add
|
||||
{
|
||||
this.Events.AddHandler(__evToggled, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.Events.RemoveHandler(__evToggled, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnToggled(EventArgs e)
|
||||
{
|
||||
(this.Events[__evToggled] as EventHandler)?.Invoke(this, e);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
|
||||
if (result.Handled)
|
||||
return;
|
||||
|
||||
await result.ConfirmAction();
|
||||
|
||||
switch (value ?? "unknown")
|
||||
{
|
||||
case "on":
|
||||
|
||||
if (this.Checked)
|
||||
return;
|
||||
|
||||
RenderNecessary = true;
|
||||
|
||||
this.Checked = true;
|
||||
|
||||
OnToggled(new EventArgs());
|
||||
|
||||
break;
|
||||
|
||||
case "off":
|
||||
|
||||
if (!this.Checked)
|
||||
return;
|
||||
|
||||
RenderNecessary = true;
|
||||
|
||||
this.Checked = false;
|
||||
|
||||
OnToggled(new EventArgs());
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
RenderNecessary = false;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
if (!RenderNecessary)
|
||||
return;
|
||||
|
||||
var bf = new ButtonForm(this);
|
||||
|
||||
ButtonBase bOn = new ButtonBase((this.Checked ? CheckedIcon : UncheckedIcon) + " " + CheckedString, "on");
|
||||
|
||||
ButtonBase bOff = new ButtonBase((!this.Checked ? CheckedIcon : UncheckedIcon) + " " + UncheckedString, "off");
|
||||
|
||||
bf.AddButtonRow(bOn, bOff);
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf, disableNotification: true);
|
||||
if (m != null)
|
||||
{
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
this.RenderNecessary = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class TreeView : ControlBase
|
||||
{
|
||||
public List<TreeViewNode> Nodes { get; set; }
|
||||
|
||||
public TreeViewNode SelectedNode { get; set; }
|
||||
|
||||
public TreeViewNode VisibleNode { get; set; }
|
||||
|
||||
public String Title { get; set; }
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public String MoveUpIcon { get; set; } = "🔼 up";
|
||||
|
||||
public TreeView()
|
||||
{
|
||||
this.Nodes = new List<TreeViewNode>();
|
||||
this.Title = "Select node";
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
await result.ConfirmAction();
|
||||
|
||||
if (result.Handled)
|
||||
return;
|
||||
|
||||
var val = result.RawData;
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case "up":
|
||||
case "parent":
|
||||
|
||||
this.VisibleNode = (this.VisibleNode?.ParentNode);
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
var n = (this.VisibleNode != null ? this.VisibleNode.FindNodeByValue(val) : this.Nodes.FirstOrDefault(a => a.Value == val));
|
||||
|
||||
if (n != null)
|
||||
{
|
||||
if (n.ChildNodes.Count > 0)
|
||||
{
|
||||
this.VisibleNode = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.SelectedNode = (this.SelectedNode != n ? n : null);
|
||||
}
|
||||
|
||||
result.Handled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
var startnode = this.VisibleNode;
|
||||
|
||||
var nodes = (startnode?.ChildNodes ?? this.Nodes);
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
if (startnode != null)
|
||||
{
|
||||
bf.AddButtonRow(new ButtonBase(this.MoveUpIcon, "up"), new ButtonBase(startnode.Text, "parent"));
|
||||
}
|
||||
|
||||
foreach (var n in nodes)
|
||||
{
|
||||
var s = n.Text;
|
||||
if (this.SelectedNode == n)
|
||||
{
|
||||
s = "[ " + s + " ]";
|
||||
}
|
||||
|
||||
bf.AddButtonRow(new ButtonBase(s, n.Value, n.Url));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
var m = await this.Device.Send(this.Title, bf);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public String GetPath()
|
||||
{
|
||||
return (this.VisibleNode?.GetPath() ?? "\\");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Controls
|
||||
{
|
||||
public class TreeViewNode
|
||||
{
|
||||
public String Text { get; set; }
|
||||
|
||||
public String Value { get; set; }
|
||||
|
||||
public String Url { get; set; }
|
||||
|
||||
public List<TreeViewNode> ChildNodes { get; set; } = new List<TreeViewNode>();
|
||||
|
||||
public TreeViewNode ParentNode { get; set; }
|
||||
|
||||
public TreeViewNode(String Text, String Value)
|
||||
{
|
||||
this.Text = Text;
|
||||
this.Value = Value;
|
||||
}
|
||||
|
||||
public TreeViewNode(String Text, String Value, String Url) : this(Text, Value)
|
||||
{
|
||||
this.Url = Url;
|
||||
}
|
||||
|
||||
public TreeViewNode(String Text, String Value, params TreeViewNode[] childnodes) : this(Text, Value)
|
||||
{
|
||||
foreach(var c in childnodes)
|
||||
{
|
||||
AddNode(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddNode(TreeViewNode node)
|
||||
{
|
||||
node.ParentNode = this;
|
||||
ChildNodes.Add(node);
|
||||
}
|
||||
|
||||
public TreeViewNode FindNodeByValue(String Value)
|
||||
{
|
||||
return this.ChildNodes.FirstOrDefault(a => a.Value == Value);
|
||||
}
|
||||
|
||||
public String GetPath()
|
||||
{
|
||||
String s = "\\" + this.Value;
|
||||
var p = this;
|
||||
while (p.ParentNode != null)
|
||||
{
|
||||
s = "\\" + p.ParentNode.Value + s;
|
||||
p = p.ParentNode;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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.")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TelegramBotBase.Exceptions
|
||||
{
|
||||
public class MaximumColsException : Exception
|
||||
{
|
||||
public int Value { get; set; }
|
||||
|
||||
public int Maximum { get; set; }
|
||||
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"You have exceeded the maximum of columns by {Value.ToString()} / {Maximum.ToString()}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TelegramBotBase.Exceptions
|
||||
{
|
||||
public class MaximumRowsReachedException : Exception
|
||||
{
|
||||
public int Value { get; set; }
|
||||
|
||||
public int Maximum { get; set; }
|
||||
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"You have exceeded the maximum of rows by {Value.ToString()} / {Maximum.ToString()}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
@@ -18,6 +19,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();
|
||||
|
||||
@@ -4,7 +4,9 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -17,30 +19,47 @@ namespace TelegramBotBase.Form
|
||||
|
||||
public eDeleteMode DeleteMode { get; set; }
|
||||
|
||||
public enum eDeleteMode
|
||||
{
|
||||
None = 0,
|
||||
OnEveryCall = 1,
|
||||
OnLeavingForm = 2
|
||||
}
|
||||
public eDeleteSide DeleteSide { get; set; }
|
||||
|
||||
|
||||
|
||||
public AutoCleanForm()
|
||||
{
|
||||
this.OldMessages = new List<Message>();
|
||||
this.DeleteMode = eDeleteMode.OnEveryCall;
|
||||
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;
|
||||
|
||||
this.Device.MessageSent += Device_MessageSent;
|
||||
|
||||
this.Device.MessageReceived += Device_MessageReceived;
|
||||
}
|
||||
|
||||
|
||||
private void Device_MessageReceived(object sender, MessageReceivedEventArgs e)
|
||||
{
|
||||
if (this.DeleteSide == eDeleteSide.BotOnly)
|
||||
return;
|
||||
|
||||
this.OldMessages.Add(e.Message);
|
||||
}
|
||||
|
||||
private void Device_MessageSent(object sender, MessageSentEventArgs e)
|
||||
{
|
||||
if (this.DeleteSide == eDeleteSide.UserOnly)
|
||||
return;
|
||||
|
||||
this.OldMessages.Add(e.Message);
|
||||
}
|
||||
|
||||
@@ -49,19 +68,11 @@ namespace TelegramBotBase.Form
|
||||
if (this.DeleteMode != eDeleteMode.OnEveryCall)
|
||||
return;
|
||||
|
||||
while (this.OldMessages.Count > 0)
|
||||
{
|
||||
if (!await this.Device.DeleteMessage(this.OldMessages[0].MessageId))
|
||||
{
|
||||
//Nachricht konnte nicht gelöscht werden, vermutlich existiert diese nicht mehr
|
||||
if (this.OldMessages.Count > 0)
|
||||
this.OldMessages.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
await MessageCleanup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fügt eine Nachricht zu der Liste der löschenden hinzu.
|
||||
/// Adds a message to this of removable ones
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void AddMessage(Message m)
|
||||
@@ -70,7 +81,7 @@ namespace TelegramBotBase.Form
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Behält die Nachricht mit der angegebenen Id.
|
||||
/// Keeps the message by removing it from the list
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
public void LeaveMessage(int Id)
|
||||
@@ -83,7 +94,7 @@ namespace TelegramBotBase.Form
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Behält die zuletzt gesendete Nachricht.
|
||||
/// Keeps the last sent message
|
||||
/// </summary>
|
||||
public void LeaveLastMessage()
|
||||
{
|
||||
@@ -93,14 +104,28 @@ namespace TelegramBotBase.Form
|
||||
this.OldMessages.RemoveAt(this.OldMessages.Count - 1);
|
||||
}
|
||||
|
||||
public async override Task Closed()
|
||||
private async Task AutoCleanForm_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (this.DeleteMode != eDeleteMode.OnLeavingForm)
|
||||
return;
|
||||
|
||||
foreach (var m in this.OldMessages)
|
||||
MessageCleanup().Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up all remembered messages.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task MessageCleanup()
|
||||
{
|
||||
while (this.OldMessages.Count > 0)
|
||||
{
|
||||
await this.Device.DeleteMessage(m.MessageId);
|
||||
if (!await this.Device.DeleteMessage(this.OldMessages[0].MessageId))
|
||||
{
|
||||
//Message can't be deleted cause it seems not to exist anymore
|
||||
if (this.OldMessages.Count > 0)
|
||||
this.OldMessages.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
@@ -15,15 +16,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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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,46 @@ namespace TelegramBotBase.Form
|
||||
{
|
||||
List<List<ButtonBase>> Buttons = new List<List<ButtonBase>>();
|
||||
|
||||
|
||||
public IReplyMarkup Markup { get; set; }
|
||||
|
||||
public ControlBase DependencyControl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the number of rows.
|
||||
/// </summary>
|
||||
public int Rows
|
||||
{
|
||||
get
|
||||
{
|
||||
return Buttons.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the highest number of columns in an row.
|
||||
/// </summary>
|
||||
public int Cols
|
||||
{
|
||||
get
|
||||
{
|
||||
return Buttons.Select(a => a.Count).OrderByDescending(a => a).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
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 +82,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 +99,57 @@ 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first Button with the given value.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public ButtonBase GetButtonByValue(String value)
|
||||
{
|
||||
return this.ToList().Where(a => a.Value == value).FirstOrDefault();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
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:
|
||||
|
||||
await OnMessage(message);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Edited(MessageResult message)
|
||||
{
|
||||
await OnMessageEdit(message);
|
||||
}
|
||||
|
||||
public virtual async Task OnMemberChanges(MemberChangeEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task OnGroupChanged(GroupChangedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task OnMessage(MessageResult e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual async Task OnMessageEdit(MessageResult e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Form
|
||||
{
|
||||
public class ModalDialog : FormBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the parent from where the modal dialog has been opened.
|
||||
/// </summary>
|
||||
public FormBase ParentForm { get; set; }
|
||||
|
||||
/// <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());
|
||||
|
||||
|
||||
this.ParentForm?.ReturnFromModal(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,22 +4,24 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
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 bool ShowBackButton { get; set; } = false;
|
||||
|
||||
public String BackLabel { get; set; } = "Zurück";
|
||||
|
||||
public PromptDialog()
|
||||
{
|
||||
@@ -29,73 +31,67 @@ 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();
|
||||
}
|
||||
|
||||
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.ShowBackButton && message.MessageText == BackLabel)
|
||||
{
|
||||
await this.CloseForm();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OnButtonClicked(new ButtonClickedEventArgs(button));
|
||||
|
||||
FormBase fb = ButtonForms.ContainsKey(call.Value) ? ButtonForms[call.Value] : null;
|
||||
|
||||
if (fb != null)
|
||||
if (this.Value == null)
|
||||
{
|
||||
await this.NavigateTo(fb);
|
||||
this.Value = message.MessageText;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
ButtonForm btn = new ButtonForm();
|
||||
|
||||
if (this.Value == null)
|
||||
{
|
||||
if (this.ShowBackButton)
|
||||
{
|
||||
ButtonForm bf = new ButtonForm();
|
||||
bf.AddButtonRow(new ButtonBase(BackLabel, "back"));
|
||||
await this.Device.Send(this.Message, (ReplyMarkupBase)bf);
|
||||
return;
|
||||
}
|
||||
|
||||
await this.Device.Send(this.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var buttons = this.Buttons.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList();
|
||||
btn.AddButtonRow(buttons);
|
||||
OnCompleted(new EventArgs());
|
||||
|
||||
await this.Device.Send(this.Message, btn);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Is used to save specific fields into a session state to survive restarts or unhandled exceptions and crashes.
|
||||
/// </summary>
|
||||
public interface IStateForm
|
||||
{
|
||||
|
||||
void LoadState(LoadStateEventArgs e);
|
||||
|
||||
void SaveState(SaveStateEventArgs e);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Interfaces
|
||||
{
|
||||
public interface IStateMachine
|
||||
{
|
||||
void SaveFormStates(SaveStatesEventArgs e);
|
||||
|
||||
StateContainer LoadFormStates();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
|
||||
namespace TelegramBotBase.Markdown
|
||||
{
|
||||
/// <summary>
|
||||
/// https://core.telegram.org/bots/api#markdownv2-style
|
||||
/// </summary>
|
||||
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 int userId, String title = null)
|
||||
{
|
||||
return Link("tg://user?id=" + userId.ToString(), title);
|
||||
}
|
||||
|
||||
/// <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 String username, String title = null)
|
||||
{
|
||||
return Link("tg://user?id=" + username, title);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a bold text 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 strike through in Markdown or HTML
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static String Strikesthrough(this String text)
|
||||
{
|
||||
switch (OutputMode)
|
||||
{
|
||||
case ParseMode.Markdown:
|
||||
return "~" + text + "~";
|
||||
case ParseMode.Html:
|
||||
return "<s>" + text + "</s>";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a italic text 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 underline text in Markdown or HTML
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static String Underline(this String text)
|
||||
{
|
||||
switch (OutputMode)
|
||||
{
|
||||
case ParseMode.Markdown:
|
||||
return "__" + text + "__";
|
||||
case ParseMode.Html:
|
||||
return "<u>" + text + "</u>";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a monospace text 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 text 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Escapes all characters as stated in the documentation: https://core.telegram.org/bots/api#markdownv2-style
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static String MarkdownV2Escape(this String text, params char[] toKeep)
|
||||
{
|
||||
char[] toEscape = new char[] { '_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!' };
|
||||
|
||||
return text.EscapeAll(toEscape.Where(a => !toKeep.Contains(a)).Select(a => a.ToString()).ToArray());
|
||||
}
|
||||
|
||||
public static string EscapeAll(this string seed, String[] chars, char escapeCharacter = '\\')
|
||||
{
|
||||
return chars.Aggregate(seed, (str, cItem) => str.Replace(cItem, escapeCharacter + cItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("TelegramBotBase Framework")]
|
||||
[assembly: AssemblyDescription("A simple addon for the original C# Telegram Bot library.")]
|
||||
[assembly: AssemblyDescription("This is a context based application framework for the C# TelegramBot library.")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Florian Dahn")]
|
||||
[assembly: AssemblyProduct("TelegramBotBase Framework")]
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.3.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.3.0.0")]
|
||||
[assembly: AssemblyVersion("2.1.0.0")]
|
||||
[assembly: AssemblyFileVersion("2.1.0.0")]
|
||||
|
||||
@@ -3,8 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Attributes;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Interfaces;
|
||||
using TelegramBotBase.Sessions;
|
||||
namespace TelegramBotBase
|
||||
{
|
||||
@@ -67,9 +70,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;
|
||||
@@ -89,5 +92,174 @@ namespace TelegramBotBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all active User Sessions.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<DeviceSession> GetUserSessions()
|
||||
{
|
||||
return this.SessionList.Where(a => a.Key > 0).Select(a => a.Value).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all active Group Sessions.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<DeviceSession> GetGroupSessions()
|
||||
{
|
||||
return this.SessionList.Where(a => a.Key < 0).Select(a => a.Value).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the previously saved states from the machine.
|
||||
/// </summary>
|
||||
public async void LoadSessionStates(IStateMachine statemachine)
|
||||
{
|
||||
if (statemachine == null)
|
||||
{
|
||||
throw new ArgumentNullException("StateMachine", "No StateMachine defined. Please set one to property BotBase.StateMachine");
|
||||
}
|
||||
|
||||
var container = statemachine.LoadFormStates();
|
||||
|
||||
foreach (var s in container.States)
|
||||
{
|
||||
Type t = Type.GetType(s.QualifiedName);
|
||||
if (t == null || !t.IsSubclassOf(typeof(FormBase)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var form = t.GetConstructor(new Type[] { }).Invoke(new object[] { }) as FormBase;
|
||||
|
||||
if (s.Values != null && s.Values.Count > 0)
|
||||
{
|
||||
var properties = s.Values.Where(a => a.Key.StartsWith("$"));
|
||||
var fields = form.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
|
||||
|
||||
foreach (var p in properties)
|
||||
{
|
||||
var f = fields.FirstOrDefault(a => a.Name == p.Key.Substring(1));
|
||||
if (f == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
f.SetValue(form, p.Value);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Is Subclass of IStateForm
|
||||
var iform = form as IStateForm;
|
||||
if (iform != null)
|
||||
{
|
||||
var ls = new LoadStateEventArgs();
|
||||
ls.Values = s.Values;
|
||||
iform.LoadState(ls);
|
||||
}
|
||||
|
||||
|
||||
form.Client = Client;
|
||||
var device = new DeviceSession(s.DeviceId, form);
|
||||
|
||||
device.ChatTitle = s.ChatTitle;
|
||||
|
||||
this.SessionList.Add(s.DeviceId, device);
|
||||
|
||||
try
|
||||
{
|
||||
await form.OnInit(new InitEventArgs());
|
||||
|
||||
await form.OnOpened(new EventArgs());
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Skip on exception
|
||||
this.SessionList.Remove(s.DeviceId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves all open states into the machine.
|
||||
/// </summary>
|
||||
public void SaveSessionStates(IStateMachine statemachine)
|
||||
{
|
||||
if (statemachine == null)
|
||||
{
|
||||
throw new ArgumentNullException("StateMachine", "No StateMachine defined. Please set one to property BotBase.StateMachine");
|
||||
}
|
||||
|
||||
var states = new List<StateEntry>();
|
||||
|
||||
foreach (var s in this.SessionList)
|
||||
{
|
||||
if (s.Value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var form = s.Value.ActiveForm;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var se = new StateEntry();
|
||||
se.DeviceId = s.Key;
|
||||
se.ChatTitle = s.Value.ChatTitle;
|
||||
se.FormUri = form.GetType().FullName;
|
||||
se.QualifiedName = form.GetType().AssemblyQualifiedName;
|
||||
|
||||
//Skip classes where IgnoreState attribute is existing
|
||||
if (form.GetType().GetCustomAttributes(typeof(IgnoreState), true).Length != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Is Subclass of IStateForm
|
||||
var iform = form as IStateForm;
|
||||
if (iform != null)
|
||||
{
|
||||
//Loading Session states
|
||||
SaveStateEventArgs ssea = new SaveStateEventArgs();
|
||||
iform.SaveState(ssea);
|
||||
|
||||
se.Values = ssea.Values;
|
||||
}
|
||||
|
||||
//Search for public properties with SaveState attribute
|
||||
var fields = form.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Where(a => a.GetCustomAttributes(typeof(SaveState), true).Length != 0).ToList();
|
||||
|
||||
foreach (var f in fields)
|
||||
{
|
||||
var val = f.GetValue(form);
|
||||
|
||||
se.Values.Add("$" + f.Name, val);
|
||||
}
|
||||
|
||||
states.Add(se);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Continue on error (skip this form)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var sc = new StateContainer();
|
||||
sc.States = states;
|
||||
|
||||
statemachine.SaveFormStates(new SaveStatesEventArgs(sc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,11 @@ using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using Telegram.Bot.Types.InputFiles;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Exceptions;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Markdown;
|
||||
|
||||
namespace TelegramBotBase.Sessions
|
||||
{
|
||||
@@ -27,11 +30,46 @@ namespace TelegramBotBase.Sessions
|
||||
/// </summary>
|
||||
public long DeviceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Username of user or group
|
||||
/// </summary>
|
||||
public String ChatTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When did any last action happend (message received or button clicked)
|
||||
/// </summary>
|
||||
public DateTime LastAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the form where the user/group is at the moment.
|
||||
/// </summary>
|
||||
public FormBase ActiveForm { get; set; }
|
||||
|
||||
public int LastMessage { get; set; }
|
||||
/// <summary>
|
||||
/// Returns the previous shown form
|
||||
/// </summary>
|
||||
public FormBase PreviousForm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// contains if the form has been switched (navigated)
|
||||
/// </summary>
|
||||
public bool FormSwitched { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ID of the last received message.
|
||||
/// </summary>
|
||||
public int LastMessageId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.LastMessage?.MessageId ?? -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the last received message.
|
||||
/// </summary>
|
||||
public Message LastMessage { get; set; }
|
||||
|
||||
private MessageClient Client
|
||||
{
|
||||
@@ -41,13 +79,36 @@ namespace TelegramBotBase.Sessions
|
||||
}
|
||||
}
|
||||
|
||||
public EventHandlerList __Events = new EventHandlerList();
|
||||
/// <summary>
|
||||
/// Returns if the messages is posted within a group.
|
||||
/// </summary>
|
||||
public bool IsGroup
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.LastMessage != null && (this.LastMessage.Chat.Type == ChatType.Group | this.LastMessage.Chat.Type == ChatType.Supergroup);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if the messages is posted within a channel.
|
||||
/// </summary>
|
||||
public bool IsChannel
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.LastMessage != null && this.LastMessage.Chat.Type == ChatType.Channel;
|
||||
}
|
||||
}
|
||||
|
||||
private EventHandlerList __Events = new EventHandlerList();
|
||||
|
||||
private static object __evMessageSent = new object();
|
||||
private static object __evMessageReceived = new object();
|
||||
|
||||
public DeviceSession()
|
||||
{
|
||||
this.LastMessage = 0;
|
||||
|
||||
}
|
||||
|
||||
public DeviceSession(long DeviceId)
|
||||
@@ -74,20 +135,82 @@ 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;
|
||||
return await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, messageId, text, replyMarkup: markup);
|
||||
}
|
||||
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
|
||||
{
|
||||
return await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, messageId, text, replyMarkup: markup);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Edits the text message
|
||||
/// </summary>
|
||||
/// <param name="messageId"></param>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="buttons"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> Edit(Message message, ButtonForm buttons = null)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
if (message.Text.Length > Constants.Telegram.MaxMessageLength)
|
||||
{
|
||||
throw new MaxLengthException(message.Text.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, message.MessageId, message.Text, replyMarkup: markup);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -102,24 +225,32 @@ 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, bool MarkdownV2AutoEscape = true)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
if (parseMode == ParseMode.MarkdownV2 && MarkdownV2AutoEscape)
|
||||
{
|
||||
text = text.MarkdownV2Escape();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||
catch (ApiRequestException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -128,9 +259,6 @@ namespace TelegramBotBase.Sessions
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -142,18 +270,30 @@ 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, bool MarkdownV2AutoEscape = true)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
Message m = null;
|
||||
|
||||
if (text.Length > Constants.Telegram.MaxMessageLength)
|
||||
{
|
||||
throw new MaxLengthException(text.Length);
|
||||
}
|
||||
|
||||
if (parseMode == ParseMode.MarkdownV2 && MarkdownV2AutoEscape)
|
||||
{
|
||||
text = text.MarkdownV2Escape();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||
catch (ApiRequestException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -162,7 +302,48 @@ namespace TelegramBotBase.Sessions
|
||||
return null;
|
||||
}
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a simple text message
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="markup"></param>
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> Send(String text, ReplyMarkupBase markup, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default, bool MarkdownV2AutoEscape = true)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
Message m = null;
|
||||
|
||||
if (text.Length > Constants.Telegram.MaxMessageLength)
|
||||
{
|
||||
throw new MaxLengthException(text.Length);
|
||||
}
|
||||
|
||||
if (parseMode == ParseMode.MarkdownV2 && MarkdownV2AutoEscape)
|
||||
{
|
||||
text = text.MarkdownV2Escape();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (ApiRequestException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -175,24 +356,22 @@ namespace TelegramBotBase.Sessions
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> SendPhoto(InputOnlineFile file, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
|
||||
public async Task<Message> SendPhoto(InputOnlineFile file, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = null;
|
||||
if (buttons != null)
|
||||
{
|
||||
markup = buttons;
|
||||
}
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
Message m = null;
|
||||
|
||||
try
|
||||
{
|
||||
m = await this.Client.TelegramClient.SendPhotoAsync(this.DeviceId, file, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification);
|
||||
m = await this.Client.TelegramClient.SendPhotoAsync(this.DeviceId, file, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification);
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||
catch (ApiRequestException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -201,8 +380,6 @@ namespace TelegramBotBase.Sessions
|
||||
return null;
|
||||
}
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -221,9 +398,7 @@ namespace TelegramBotBase.Sessions
|
||||
{
|
||||
InputOnlineFile fts = new InputOnlineFile(fileStream, name);
|
||||
|
||||
var m = await SendPhoto(fts, buttons, replyTo, disableNotification);
|
||||
|
||||
return m;
|
||||
return await SendPhoto(fts, buttons, replyTo, disableNotification);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,12 +417,80 @@ namespace TelegramBotBase.Sessions
|
||||
{
|
||||
InputOnlineFile fts = new InputOnlineFile(fileStream, name);
|
||||
|
||||
var m = await SendPhoto(fts, buttons, replyTo, disableNotification);
|
||||
|
||||
return m;
|
||||
return await SendPhoto(fts, buttons, replyTo, disableNotification);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends an video
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="buttons"></param>
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> SendVideo(InputOnlineFile file, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
Message m = null;
|
||||
|
||||
try
|
||||
{
|
||||
m = await this.Client.TelegramClient.SendVideoAsync(this.DeviceId, file, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification);
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (ApiRequestException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends an video
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="buttons"></param>
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> SendVideo(String url, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
||||
{
|
||||
if (this.ActiveForm == null)
|
||||
return null;
|
||||
|
||||
InlineKeyboardMarkup markup = buttons;
|
||||
|
||||
Message m = null;
|
||||
|
||||
try
|
||||
{
|
||||
m = await this.Client.TelegramClient.SendVideoAsync(this.DeviceId, new InputOnlineFile(url), parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification);
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
}
|
||||
catch (ApiRequestException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends an document
|
||||
/// </summary>
|
||||
@@ -264,9 +507,33 @@ namespace TelegramBotBase.Sessions
|
||||
|
||||
InputOnlineFile fts = new InputOnlineFile(ms, filename);
|
||||
|
||||
var m = await SendDocument(fts, caption, buttons, replyTo, disableNotification);
|
||||
return await SendDocument(fts, caption, buttons, replyTo, disableNotification);
|
||||
}
|
||||
|
||||
return m;
|
||||
/// <summary>
|
||||
/// Generates a Textfile from scratch with the specified encoding. (Default is UTF8)
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
/// <param name="textcontent"></param>
|
||||
/// <param name="encoding">Default is UTF8</param>
|
||||
/// <param name="caption"></param>
|
||||
/// <param name="buttons"></param>
|
||||
/// <param name="replyTo"></param>
|
||||
/// <param name="disableNotification"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> SendTextFile(String filename, String textcontent, Encoding encoding = null, String caption = "", ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
|
||||
{
|
||||
encoding = encoding ?? Encoding.UTF8;
|
||||
|
||||
var ms = new MemoryStream();
|
||||
var sw = new StreamWriter(ms, encoding);
|
||||
|
||||
sw.Write(textcontent);
|
||||
sw.Flush();
|
||||
|
||||
var content = ms.ToArray();
|
||||
|
||||
return await SendDocument(filename, content, caption, buttons, replyTo, disableNotification);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -288,7 +555,7 @@ namespace TelegramBotBase.Sessions
|
||||
|
||||
var m = await this.Client.TelegramClient.SendDocumentAsync(this.DeviceId, document, caption, replyMarkup: markup, disableNotification: disableNotification, replyToMessageId: replyTo);
|
||||
|
||||
OnMessageSent(new MessageSentEventArgs(m.MessageId, m));
|
||||
OnMessageSent(new MessageSentEventArgs(m));
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -303,6 +570,54 @@ namespace TelegramBotBase.Sessions
|
||||
await this.Client.TelegramClient.SendChatActionAsync(this.DeviceId, action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the contact from the user.
|
||||
/// </summary>
|
||||
/// <param name="buttonText"></param>
|
||||
/// <param name="requestMessage"></param>
|
||||
/// <param name="OneTimeOnly"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> RequestContact(String buttonText = "Send your contact", String requestMessage = "Give me your phone number!", bool OneTimeOnly = true)
|
||||
{
|
||||
var rck = new ReplyKeyboardMarkup(KeyboardButton.WithRequestContact(buttonText));
|
||||
rck.OneTimeKeyboard = OneTimeOnly;
|
||||
return await this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, requestMessage, replyMarkup: rck);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the location from the user.
|
||||
/// </summary>
|
||||
/// <param name="buttonText"></param>
|
||||
/// <param name="requestMessage"></param>
|
||||
/// <param name="OneTimeOnly"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Message> RequestLocation(String buttonText = "Send your location", String requestMessage = "Give me your location!", bool OneTimeOnly = true)
|
||||
{
|
||||
var rcl = new ReplyKeyboardMarkup(KeyboardButton.WithRequestLocation(buttonText));
|
||||
rcl.OneTimeKeyboard = OneTimeOnly;
|
||||
return await this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, requestMessage, replyMarkup: rcl);
|
||||
}
|
||||
|
||||
public async Task<Message> HideReplyKeyboard(String closedMsg = "Closed", bool autoDeleteResponse = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var m = await this.Send(closedMsg, new ReplyKeyboardRemove());
|
||||
|
||||
if (autoDeleteResponse && m != null)
|
||||
{
|
||||
await this.DeleteMessage(m);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a message
|
||||
/// </summary>
|
||||
@@ -316,7 +631,7 @@ namespace TelegramBotBase.Sessions
|
||||
|
||||
return true;
|
||||
}
|
||||
catch(ApiRequestException ex)
|
||||
catch (ApiRequestException)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -334,6 +649,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>
|
||||
@@ -355,5 +721,25 @@ namespace TelegramBotBase.Sessions
|
||||
(this.__Events[__evMessageSent] as EventHandler<MessageSentEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eventhandler for received messages
|
||||
/// </summary>
|
||||
public event EventHandler<MessageReceivedEventArgs> MessageReceived
|
||||
{
|
||||
add
|
||||
{
|
||||
this.__Events.AddHandler(__evMessageReceived, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
this.__Events.RemoveHandler(__evMessageReceived, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnMessageReceived(MessageReceivedEventArgs e)
|
||||
{
|
||||
(this.__Events[__evMessageReceived] as EventHandler<MessageReceivedEventArgs>)?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Text;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Interfaces;
|
||||
|
||||
namespace TelegramBotBase.States
|
||||
{
|
||||
/// <summary>
|
||||
/// Is used for all complex data types. Use if other default machines are not working.
|
||||
/// </summary>
|
||||
public class JSONStateMachine : IStateMachine
|
||||
{
|
||||
public String FilePath { get; set; }
|
||||
|
||||
public bool Overwrite { get; set; }
|
||||
|
||||
public JSONStateMachine(String file, bool overwrite = true)
|
||||
{
|
||||
if (file is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(file));
|
||||
}
|
||||
|
||||
this.FilePath = file;
|
||||
this.Overwrite = overwrite;
|
||||
}
|
||||
|
||||
public StateContainer LoadFormStates()
|
||||
{
|
||||
try
|
||||
{
|
||||
var content = System.IO.File.ReadAllText(FilePath);
|
||||
|
||||
var sc = Newtonsoft.Json.JsonConvert.DeserializeObject<StateContainer>(content, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.All,
|
||||
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
|
||||
}) as StateContainer;
|
||||
|
||||
return sc;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return new StateContainer();
|
||||
}
|
||||
|
||||
public void SaveFormStates(SaveStatesEventArgs e)
|
||||
{
|
||||
if (System.IO.File.Exists(FilePath))
|
||||
{
|
||||
if (!this.Overwrite)
|
||||
{
|
||||
throw new Exception("File exists already.");
|
||||
}
|
||||
|
||||
System.IO.File.Delete(FilePath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var content = Newtonsoft.Json.JsonConvert.SerializeObject(e.States, Formatting.Indented, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.All,
|
||||
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
|
||||
});
|
||||
|
||||
System.IO.File.WriteAllText(FilePath, content);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Text;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Interfaces;
|
||||
|
||||
namespace TelegramBotBase.States
|
||||
{
|
||||
/// <summary>
|
||||
/// Is used for simple object structures like classes, lists or basic datatypes without generics and other compiler based data types.
|
||||
/// </summary>
|
||||
public class SimpleJSONStateMachine : IStateMachine
|
||||
{
|
||||
public String FilePath { get; set; }
|
||||
|
||||
public bool Overwrite { get; set; }
|
||||
|
||||
public SimpleJSONStateMachine(String file, bool overwrite = true)
|
||||
{
|
||||
if (file is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(file));
|
||||
}
|
||||
|
||||
this.FilePath = file;
|
||||
this.Overwrite = overwrite;
|
||||
}
|
||||
|
||||
public StateContainer LoadFormStates()
|
||||
{
|
||||
try
|
||||
{
|
||||
var content = System.IO.File.ReadAllText(FilePath);
|
||||
|
||||
var sc = Newtonsoft.Json.JsonConvert.DeserializeObject<StateContainer>(content) as StateContainer;
|
||||
|
||||
return sc;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return new StateContainer();
|
||||
}
|
||||
|
||||
public void SaveFormStates(SaveStatesEventArgs e)
|
||||
{
|
||||
if (System.IO.File.Exists(FilePath))
|
||||
{
|
||||
if (!this.Overwrite)
|
||||
{
|
||||
throw new Exception("File exists already.");
|
||||
}
|
||||
|
||||
System.IO.File.Delete(FilePath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var content = Newtonsoft.Json.JsonConvert.SerializeObject(e.States, Formatting.Indented);
|
||||
|
||||
System.IO.File.WriteAllText(FilePath, content);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Interfaces;
|
||||
|
||||
namespace TelegramBotBase.States
|
||||
{
|
||||
public class XMLStateMachine : IStateMachine
|
||||
{
|
||||
public String FilePath { get; set; }
|
||||
|
||||
public bool Overwrite { get; set; }
|
||||
|
||||
public XMLStateMachine(String file, bool overwrite = true)
|
||||
{
|
||||
if (file is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(file));
|
||||
}
|
||||
|
||||
this.FilePath = file;
|
||||
this.Overwrite = overwrite;
|
||||
}
|
||||
|
||||
public StateContainer LoadFormStates()
|
||||
{
|
||||
try
|
||||
{
|
||||
DataContractSerializer serializer = new DataContractSerializer(typeof(StateContainer));
|
||||
|
||||
using (var reader = new StreamReader(FilePath))
|
||||
{
|
||||
using (var xml = new XmlTextReader(reader))
|
||||
{
|
||||
StateContainer sc = serializer.ReadObject(xml) as StateContainer;
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return new StateContainer();
|
||||
}
|
||||
|
||||
public void SaveFormStates(SaveStatesEventArgs e)
|
||||
{
|
||||
if (System.IO.File.Exists(FilePath))
|
||||
{
|
||||
if (!this.Overwrite)
|
||||
{
|
||||
throw new Exception("File exists already.");
|
||||
}
|
||||
|
||||
System.IO.File.Delete(FilePath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
DataContractSerializer serializer = new DataContractSerializer(typeof(StateContainer));
|
||||
|
||||
using (var sw = new StreamWriter(this.FilePath))
|
||||
{
|
||||
using (var writer = new XmlTextWriter(sw))
|
||||
{
|
||||
writer.Formatting = Formatting.Indented; // indent the Xml so it’s human readable
|
||||
serializer.WriteObject(writer, e.States);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +1,20 @@
|
||||
<?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;netcoreapp3.1</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>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
@@ -22,6 +24,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
@@ -31,67 +34,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\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.3" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
|
||||
<PackageReference Include="Telegram.Bot" Version="15.5.1" />
|
||||
</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>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
<?xml version="1.0"?>
|
||||
<package >
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$version$</version>
|
||||
<title>$title$</title>
|
||||
<authors>$author$</authors>
|
||||
<owners>$author$</owners>
|
||||
<id>TelegramBotBase</id>
|
||||
<version>2.1.0</version>
|
||||
<authors>TelegramBotBase</authors>
|
||||
<owners>TelegramBotBase</owners>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/MajMcCloud/TelegramBotFramework</projectUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>$description$</description>
|
||||
<releaseNotes>First release on nuget for easier use.</releaseNotes>
|
||||
<copyright>Copyright 2019</copyright>
|
||||
<tags>Telegram Bot Framework C# Addon Context Modules</tags>
|
||||
<description>Package Description</description>
|
||||
<releaseNotes>- moving from .Net Framework 4.7.2 to .Net Standard 2.1 for the Library and .Net Core 3.0 for the test project!</releaseNotes>
|
||||
<repository url="https://github.com/MajMcCloud/TelegramBotFramework" />
|
||||
<dependencies>
|
||||
<dependency id="Telegram.Bot" version="14.3.0" />
|
||||
<dependency id="Newtonsoft.Json" version="11.0.2" />
|
||||
<group targetFramework=".NETFramework4.6.1">
|
||||
<dependency id="Newtonsoft.Json" version="12.0.2" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Drawing.Common" version="4.6.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Telegram.Bot" version="15.0.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
<group targetFramework=".NETStandard2.0">
|
||||
<dependency id="Newtonsoft.Json" version="12.0.2" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Drawing.Common" version="4.6.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Telegram.Bot" version="15.0.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
</package>
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Tools
|
||||
{
|
||||
public static class Arrays
|
||||
{
|
||||
public static T[] Shift<T>(T[] array, int positions)
|
||||
{
|
||||
T[] copy = new T[array.Length];
|
||||
Array.Copy(array, 0, copy, array.Length - positions, positions);
|
||||
Array.Copy(array, positions, copy, 0, array.Length - positions);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Tools
|
||||
{
|
||||
public static class Time
|
||||
{
|
||||
public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
|
||||
{
|
||||
int diff = dt.DayOfWeek - startOfWeek;
|
||||
if (diff < 0)
|
||||
{
|
||||
diff += 7;
|
||||
}
|
||||
return dt.AddDays(-1 * diff).Date;
|
||||
}
|
||||
|
||||
public static DateTime EndOfWeek(this DateTime dt, DayOfWeek startOfWeek)
|
||||
{
|
||||
return StartOfWeek(dt, startOfWeek).AddDays(6);
|
||||
}
|
||||
|
||||
public static DateTime FirstDayOfMonth(this DateTime date)
|
||||
{
|
||||
return new DateTime(date.Year, date.Month, 1);
|
||||
}
|
||||
|
||||
public static DateTime LastDayOfMonth(this DateTime date)
|
||||
{
|
||||
return FirstDayOfMonth(date).AddMonths(1).AddDays(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
<?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>
|
||||
</configuration>
|
||||
</configuration>
|
||||
+2
-2
@@ -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>
|
||||
+10
-5
@@ -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,9 +62,7 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
case "back":
|
||||
|
||||
var st = new Start();
|
||||
|
||||
await st.Init();
|
||||
var st = new Menu();
|
||||
|
||||
await this.NavigateTo(st);
|
||||
|
||||
@@ -85,6 +88,8 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Button 3", new CallbackData("a", "button3").Serialize()), new ButtonBase("Button 4", new CallbackData("a", "button4").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Google.com", "google", "https://www.google.com"), new ButtonBase("Telegram", "telegram", "https://telegram.org/"));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Back", new CallbackData("a", "back").Serialize()));
|
||||
|
||||
await this.Device.Send("Click a button", btn);
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
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, 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, 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,80 @@
|
||||
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;
|
||||
using TelegramBotBase.Args;
|
||||
|
||||
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,78 @@
|
||||
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;
|
||||
using TelegramBotBase.Args;
|
||||
|
||||
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,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
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, 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,100 @@
|
||||
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;
|
||||
using TelegramBotBase.Args;
|
||||
|
||||
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, 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.InputFiles;
|
||||
using Telegram.Bot.Types.ReplyMarkups;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBaseTest.Tests
|
||||
{
|
||||
public class DataForm : AutoCleanForm
|
||||
{
|
||||
|
||||
|
||||
public override async Task SentData(DataResult data)
|
||||
{
|
||||
String tmp = "";
|
||||
InputOnlineFile file;
|
||||
|
||||
switch (data.Type)
|
||||
{
|
||||
case Telegram.Bot.Types.Enums.MessageType.Contact:
|
||||
|
||||
tmp += "Firstname: " + data.Contact.FirstName + "\r\n";
|
||||
tmp += "Lastname: " + data.Contact.LastName + "\r\n";
|
||||
tmp += "Phonenumber: " + data.Contact.PhoneNumber + "\r\n";
|
||||
tmp += "UserId: " + data.Contact.UserId + "\r\n";
|
||||
|
||||
await this.Device.Send("Your contact: \r\n" + tmp, replyTo: data.MessageId);
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Document:
|
||||
|
||||
file = new InputOnlineFile(data.Document.FileId);
|
||||
|
||||
await this.Device.SendDocument(file, "Your uploaded document");
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Video:
|
||||
|
||||
file = new InputOnlineFile(data.Document.FileId);
|
||||
|
||||
await this.Device.SendDocument(file, "Your uploaded video");
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Audio:
|
||||
|
||||
file = new InputOnlineFile(data.Document.FileId);
|
||||
|
||||
await this.Device.SendDocument(file, "Your uploaded audio");
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Location:
|
||||
|
||||
tmp += "Lat: " + data.Location.Latitude + "\r\n";
|
||||
tmp += "Lng: " + data.Location.Longitude + "\r\n";
|
||||
|
||||
await this.Device.Send("Your location: \r\n" + tmp, replyTo: data.MessageId);
|
||||
|
||||
break;
|
||||
|
||||
case Telegram.Bot.Types.Enums.MessageType.Photo:
|
||||
|
||||
InputOnlineFile photo = new InputOnlineFile(data.Photos.Last().FileId);
|
||||
|
||||
await this.Device.Send("Your image: ", replyTo: data.MessageId);
|
||||
await this.Client.TelegramClient.SendPhotoAsync(this.Device.DeviceId, photo);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
await this.Device.Send("Unknown response");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
await message.ConfirmAction();
|
||||
|
||||
if (message.Handled)
|
||||
return;
|
||||
|
||||
switch (message.RawData)
|
||||
{
|
||||
case "contact":
|
||||
|
||||
await this.Device.RequestContact();
|
||||
|
||||
break;
|
||||
|
||||
case "location":
|
||||
|
||||
await this.Device.RequestLocation();
|
||||
|
||||
break;
|
||||
|
||||
case "back":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var start = new Menu();
|
||||
|
||||
await this.NavigateTo(start);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("Request User contact", "contact"));
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("Request User location", "location"));
|
||||
|
||||
bf.AddButtonRow(new ButtonBase("Back", "back"));
|
||||
|
||||
InlineKeyboardMarkup ikv = bf;
|
||||
|
||||
await this.Device.Send("Please upload a contact, photo, video, audio, document or location.", bf);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
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,164 @@
|
||||
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;
|
||||
|
||||
//Are urls inside his message ?
|
||||
if (!HasLinks(e.MessageText))
|
||||
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;
|
||||
}
|
||||
|
||||
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>
|
||||
/// Call onmessage also on edited message, if someone want to spoof a failed message and insert a link.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task OnMessageEdit(MessageResult message)
|
||||
{
|
||||
await OnMessage(message);
|
||||
}
|
||||
|
||||
/// <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\-\._\?\,\'/\\\+&%\$#\=~])*[^\.\,\)\(\s]$";
|
||||
Regex r = new Regex(pattern);
|
||||
|
||||
var matches = r.Matches(tmp);
|
||||
|
||||
return (matches.Count > 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
using TelegramBotBase.Args;
|
||||
|
||||
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");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBaseTest.Tests
|
||||
{
|
||||
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)
|
||||
{
|
||||
var call = message.GetData<CallbackData>();
|
||||
|
||||
await message.ConfirmAction();
|
||||
|
||||
|
||||
if (call == null)
|
||||
return;
|
||||
|
||||
switch(call.Value)
|
||||
{
|
||||
case "text":
|
||||
|
||||
var sf = new SimpleForm();
|
||||
|
||||
await this.NavigateTo(sf);
|
||||
|
||||
break;
|
||||
|
||||
case "buttons":
|
||||
|
||||
var bf = new ButtonTestForm();
|
||||
|
||||
await this.NavigateTo(bf);
|
||||
|
||||
break;
|
||||
|
||||
case "progress":
|
||||
|
||||
var pf = new ProgressTest();
|
||||
|
||||
await this.NavigateTo(pf);
|
||||
|
||||
break;
|
||||
|
||||
case "registration":
|
||||
|
||||
var reg = new Register.Start();
|
||||
|
||||
await this.NavigateTo(reg);
|
||||
|
||||
break;
|
||||
|
||||
case "form1":
|
||||
|
||||
var form1 = new TestForm();
|
||||
|
||||
await this.NavigateTo(form1);
|
||||
|
||||
break;
|
||||
|
||||
case "form2":
|
||||
|
||||
var form2 = new TestForm2();
|
||||
|
||||
await this.NavigateTo(form2);
|
||||
|
||||
break;
|
||||
|
||||
case "data":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var data = new DataForm();
|
||||
|
||||
await this.NavigateTo(data);
|
||||
|
||||
break;
|
||||
|
||||
case "calendar":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var calendar = new Controls.CalendarPickerForm();
|
||||
|
||||
await this.NavigateTo(calendar);
|
||||
|
||||
break;
|
||||
|
||||
case "month":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var month = new Controls.MonthPickerForm();
|
||||
|
||||
await this.NavigateTo(month);
|
||||
|
||||
break;
|
||||
|
||||
case "treeview":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var tree = new Controls.TreeViewForms();
|
||||
|
||||
await this.NavigateTo(tree);
|
||||
|
||||
break;
|
||||
|
||||
case "togglebuttons":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var tb = new Controls.ToggleButtons();
|
||||
|
||||
await this.NavigateTo(tb);
|
||||
|
||||
break;
|
||||
case "buttongrid":
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
var bg = new Controls.ButtonGridForm();
|
||||
|
||||
await this.NavigateTo(bg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
|
||||
ButtonForm btn = new ButtonForm();
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#1 Simple Text", new CallbackData("a", "text").Serialize()), new ButtonBase("#2 Button Test", new CallbackData("a", "buttons").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#3 Progress Bar", new CallbackData("a", "progress").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#4 Registration Example", new CallbackData("a", "registration").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#5 Form1 Command", new CallbackData("a", "form1").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#6 Form2 Command", new CallbackData("a", "form2").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#7 Data Handling", new CallbackData("a", "data").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#8 Calendar Picker", new CallbackData("a", "calendar").Serialize()));
|
||||
btn.AddButtonRow(new ButtonBase("#9 Month Picker", new CallbackData("a", "month").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#10 TreeView", new CallbackData("a", "treeview").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#11 ToggleButtons", new CallbackData("a", "togglebuttons").Serialize()));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("#12 ButtonGrid", new CallbackData("a", "buttongrid").Serialize()));
|
||||
|
||||
await this.Device.Send("Choose your test:", btn);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+10
-16
@@ -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,9 +76,7 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
case "start":
|
||||
|
||||
var sf = new Start();
|
||||
|
||||
await sf.Init();
|
||||
var sf = new Menu();
|
||||
|
||||
await this.NavigateTo(sf);
|
||||
|
||||
@@ -89,14 +90,14 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
|
||||
//Render Progress bar and show some "example" progress
|
||||
await Bar.Render();
|
||||
await Bar.Render(message);
|
||||
|
||||
this.Controls.Add(Bar);
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
Bar.Value++;
|
||||
await Bar.Render();
|
||||
await Bar.Render(message);
|
||||
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
@@ -119,17 +120,10 @@ namespace TelegramBaseTest.Tests
|
||||
await this.Device.Send("Choose your progress bar:", btn);
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task ProgressTest_Closed(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var b in this.Controls)
|
||||
{
|
||||
await b.Cleanup();
|
||||
}
|
||||
|
||||
await this.Device.Send("Ciao from ProgressTest");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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
|
||||
{
|
||||
+1
-1
@@ -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
|
||||
{
|
||||
+2
-2
@@ -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);
|
||||
|
||||
+1
-1
@@ -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
|
||||
{
|
||||
+9
-2
@@ -3,20 +3,27 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
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)
|
||||
+1
-1
@@ -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
|
||||
{
|
||||
+1
-1
@@ -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,16 +6,23 @@ using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBaseTest.Tests
|
||||
namespace TelegramBotBaseTest.Tests
|
||||
{
|
||||
public class SimpleForm : FormBase
|
||||
public class SimpleForm : AutoCleanForm
|
||||
{
|
||||
|
||||
public override async Task Opened()
|
||||
public SimpleForm()
|
||||
{
|
||||
await this.Device.Send("Hello world! (send 'back' to get back to Start)");
|
||||
this.DeleteSide = TelegramBotBase.Enums.eDeleteSide.Both;
|
||||
this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
|
||||
|
||||
this.Opened += SimpleForm_Opened;
|
||||
}
|
||||
|
||||
private async Task SimpleForm_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Hello world! (send 'back' to get back to Start)\r\nOr\r\nhi, hello, maybe, bye and ciao");
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
@@ -48,9 +55,7 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
case "back":
|
||||
|
||||
var st = new Start();
|
||||
|
||||
await st.Init();
|
||||
var st = new Menu();
|
||||
|
||||
await this.NavigateTo(st);
|
||||
|
||||
@@ -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,27 +15,22 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
String LastMessage { get; set; }
|
||||
|
||||
public override async Task Init(params object[] param)
|
||||
public TestForm()
|
||||
{
|
||||
|
||||
this.Opened += TestForm_Opened;
|
||||
this.Closed += TestForm_Closed;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
private async Task TestForm_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Welcome to Form 1");
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task TestForm_Closed(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Ciao from Form 1");
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
@@ -51,8 +46,6 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
var tf = new TestForm2();
|
||||
|
||||
await tf.Init();
|
||||
|
||||
await this.NavigateTo(tf);
|
||||
|
||||
break;
|
||||
@@ -10,30 +10,30 @@ 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 Init(params object[] param)
|
||||
{
|
||||
|
||||
public TestForm2()
|
||||
{
|
||||
this.Opened += TestForm2_Opened;
|
||||
this.Closed += TestForm2_Closed;
|
||||
}
|
||||
|
||||
public override async Task Opened()
|
||||
private async Task TestForm2_Opened(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Welcome to Form 2");
|
||||
}
|
||||
|
||||
public override async Task Closed()
|
||||
private async Task TestForm2_Closed(object sender, EventArgs e)
|
||||
{
|
||||
await this.Device.Send("Ciao from Form 2");
|
||||
}
|
||||
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
@@ -43,38 +43,51 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
await message.DeleteMessage();
|
||||
|
||||
message.Handled = true;
|
||||
|
||||
if (call.Value == "testform1")
|
||||
{
|
||||
|
||||
var tf = new TestForm();
|
||||
|
||||
await tf.Init();
|
||||
|
||||
await this.NavigateTo(tf);
|
||||
}
|
||||
else if (call.Value == "alert")
|
||||
{
|
||||
var fto = new TestForm2();
|
||||
await fto.Init();
|
||||
|
||||
AlertDialog ad = new AlertDialog("This is a message", "Ok", fto);
|
||||
AlertDialog ad = new AlertDialog("This is a message", "Ok");
|
||||
|
||||
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", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
|
||||
ConfirmDialog pd = new ConfirmDialog("Please confirm", new ButtonBase("Ok", "ok"), new ButtonBase("Cancel", "cancel"));
|
||||
|
||||
var tf = new TestForm2();
|
||||
pd.ButtonClicked += async (s, en) =>
|
||||
{
|
||||
var tf = new TestForm2();
|
||||
|
||||
await tf.Init();
|
||||
|
||||
pd.ButtonForms.Add("ok", tf);
|
||||
pd.ButtonForms.Add("cancel", tf);
|
||||
await pd.NavigateTo(tf);
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -98,7 +111,11 @@ namespace TelegramBaseTest.Tests
|
||||
|
||||
//btn.AddButtonRow(new ButtonBase("Zum Testformular 1", CallbackData.Create("navigate", "testform1")), new ButtonBase("Zum Testformular 1", CallbackData.Create("navigate", "testform1")));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Information Prompt", CallbackData.Create("navigate", "alert")), new ButtonBase("Confirmation Prompt", CallbackData.Create("navigate", "prompt")));
|
||||
btn.AddButtonRow(new ButtonBase("Information Prompt", CallbackData.Create("navigate", "alert")));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Confirmation Prompt with event", CallbackData.Create("navigate", "confirm")));
|
||||
|
||||
btn.AddButtonRow(new ButtonBase("Request Prompt", CallbackData.Create("navigate", "prompt")));
|
||||
|
||||
|
||||
await this.Device.SendPhoto(bmp, "Test", btn);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user