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 |
@@ -1,17 +0,0 @@
|
|||||||
name: .NET Core
|
|
||||||
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
- name: Setup .NET Core
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
|
||||||
dotnet-version: 2.2.108
|
|
||||||
- name: Build with dotnet
|
|
||||||
run: dotnet build --configuration Release
|
|
||||||
+12
@@ -240,3 +240,15 @@ ModelManifest.xml
|
|||||||
|
|
||||||
# FAKE - F# Make
|
# FAKE - F# Make
|
||||||
.fake/
|
.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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -76,6 +76,10 @@ Thanks !
|
|||||||
|
|
||||||
* [GroupForm](#group-form)
|
* [GroupForm](#group-form)
|
||||||
|
|
||||||
|
- [State Machine and Session Serialization](#statemachine)
|
||||||
|
|
||||||
|
* In the making, is comming soon.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Button get clicked event
|
/// Button get clicked event
|
||||||
+2
-1
@@ -2,8 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using TelegramBotBase.Base;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
public class GroupChangedEventArgs : EventArgs
|
public class GroupChangedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
public class InitEventArgs : EventArgs
|
public class InitEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -4,8 +4,9 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using TelegramBotBase.Base;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
public class MemberChangeEventArgs : EventArgs
|
public class MemberChangeEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
+2
-2
@@ -7,7 +7,7 @@ using TelegramBotBase.Sessions;
|
|||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Base
|
||||||
{
|
{
|
||||||
public class MessageIncomeResult : EventArgs
|
public class MessageIncomeEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
|
|
||||||
public long DeviceId { get; set; }
|
public long DeviceId { get; set; }
|
||||||
@@ -16,7 +16,7 @@ namespace TelegramBotBase.Base
|
|||||||
|
|
||||||
public MessageResult Message { get; set; }
|
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.DeviceId = DeviceId;
|
||||||
this.Device = Device;
|
this.Device = Device;
|
||||||
+1
-1
@@ -5,7 +5,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
public class MessageReceivedEventArgs
|
public class MessageReceivedEventArgs
|
||||||
{
|
{
|
||||||
+1
-1
@@ -5,7 +5,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
public class MessageSentEventArgs
|
public class MessageSentEventArgs
|
||||||
{
|
{
|
||||||
@@ -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
|
namespace TelegramBotBase.Base
|
||||||
{
|
{
|
||||||
public class SessionBeginResult : EventArgs
|
public class SessionBeginEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public long DeviceId { get; set; }
|
public long DeviceId { get; set; }
|
||||||
|
|
||||||
public DeviceSession Device { get; set; }
|
public DeviceSession Device { get; set; }
|
||||||
|
|
||||||
public SessionBeginResult(long DeviceId, DeviceSession Device)
|
public SessionBeginEventArgs(long DeviceId, DeviceSession Device)
|
||||||
{
|
{
|
||||||
this.DeviceId = DeviceId;
|
this.DeviceId = DeviceId;
|
||||||
this.Device = Device;
|
this.Device = Device;
|
||||||
+1
-1
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using TelegramBotBase.Sessions;
|
using TelegramBotBase.Sessions;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class for given system call results
|
/// Base class for given system call results
|
||||||
+1
-1
@@ -5,7 +5,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TelegramBotBase.Sessions;
|
using TelegramBotBase.Sessions;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
public class SystemExceptionEventArgs : EventArgs
|
public class SystemExceptionEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
+1
-1
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using TelegramBotBase.Sessions;
|
using TelegramBotBase.Sessions;
|
||||||
|
|
||||||
namespace TelegramBotBase.Base
|
namespace TelegramBotBase.Args
|
||||||
{
|
{
|
||||||
public class UnhandledCallEventArgs : EventArgs
|
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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,6 +51,12 @@ namespace TelegramBotBase.Base
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task Hidden(bool FormClose)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task Cleanup()
|
public virtual async Task Cleanup()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -97,7 +98,7 @@ namespace TelegramBotBase.Base
|
|||||||
this.RawMessageData = message.RawMessageData;
|
this.RawMessageData = message.RawMessageData;
|
||||||
this.Message = message.Message;
|
this.Message = message.Message;
|
||||||
|
|
||||||
|
this.Client = message.Client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<InputOnlineFile> DownloadDocument()
|
public async Task<InputOnlineFile> DownloadDocument()
|
||||||
@@ -108,6 +109,15 @@ namespace TelegramBotBase.Base
|
|||||||
return new InputOnlineFile(encryptedContent, this.Document.FileName);
|
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()
|
public async Task<InputOnlineFile> DownloadVideo()
|
||||||
{
|
{
|
||||||
var encryptedContent = new System.IO.MemoryStream(this.Video.FileSize);
|
var encryptedContent = new System.IO.MemoryStream(this.Video.FileSize);
|
||||||
@@ -116,6 +126,32 @@ namespace TelegramBotBase.Base
|
|||||||
return new InputOnlineFile(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)
|
public async Task<InputOnlineFile> DownloadPhoto(int index)
|
||||||
{
|
{
|
||||||
var photo = this.Photos[index];
|
var photo = this.Photos[index];
|
||||||
@@ -125,5 +161,15 @@ namespace TelegramBotBase.Base
|
|||||||
return new InputOnlineFile(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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Sessions;
|
using TelegramBotBase.Sessions;
|
||||||
using static TelegramBotBase.Base.Async;
|
using static TelegramBotBase.Base.Async;
|
||||||
@@ -106,6 +107,8 @@ namespace TelegramBotBase.Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task OnClosed(EventArgs e)
|
public async Task OnClosed(EventArgs e)
|
||||||
{
|
{
|
||||||
if (this.Events[__evClosed] == null)
|
if (this.Events[__evClosed] == null)
|
||||||
@@ -135,6 +138,16 @@ namespace TelegramBotBase.Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pre to form close, cleanup all controls
|
/// Pre to form close, cleanup all controls
|
||||||
@@ -144,7 +157,7 @@ namespace TelegramBotBase.Form
|
|||||||
{
|
{
|
||||||
foreach (var b in this.Controls)
|
foreach (var b in this.Controls)
|
||||||
{
|
{
|
||||||
await b.Cleanup();
|
b.Cleanup().Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +203,15 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets invoked, when a messages has been edited.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual async Task Edited(MessageResult message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -275,7 +297,7 @@ namespace TelegramBotBase.Form
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="newForm"></param>
|
/// <param name="newForm"></param>
|
||||||
/// <returns></returns>
|
/// <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;
|
DeviceSession ds = this.Device;
|
||||||
if (ds == null)
|
if (ds == null)
|
||||||
@@ -289,12 +311,21 @@ namespace TelegramBotBase.Form
|
|||||||
newForm.Client = this.Client;
|
newForm.Client = this.Client;
|
||||||
newForm.Device = ds;
|
newForm.Device = ds;
|
||||||
|
|
||||||
await newForm.OnInit(new InitEventArgs(args));
|
//Notify prior to close
|
||||||
|
foreach (var b in this.Controls)
|
||||||
|
{
|
||||||
|
if (!b.Enabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
await this.CloseControls();
|
await b.Hidden(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.CloseControls().Wait();
|
||||||
|
|
||||||
await this.OnClosed(new EventArgs());
|
await this.OnClosed(new EventArgs());
|
||||||
|
|
||||||
|
await newForm.OnInit(new InitEventArgs(args));
|
||||||
|
|
||||||
await newForm.OnOpened(new EventArgs());
|
await newForm.OnOpened(new EventArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +334,7 @@ namespace TelegramBotBase.Form
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="newForm"></param>
|
/// <param name="newForm"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task OpenModal(ModalDialog newForm, params object[] args)
|
public virtual async Task OpenModal(ModalDialog newForm, params object[] args)
|
||||||
{
|
{
|
||||||
DeviceSession ds = this.Device;
|
DeviceSession ds = this.Device;
|
||||||
if (ds == null)
|
if (ds == null)
|
||||||
@@ -318,12 +349,21 @@ namespace TelegramBotBase.Form
|
|||||||
ds.ActiveForm = newForm;
|
ds.ActiveForm = newForm;
|
||||||
newForm.Client = parentForm.Client;
|
newForm.Client = parentForm.Client;
|
||||||
newForm.Device = ds;
|
newForm.Device = ds;
|
||||||
|
newForm.ParentForm = parentForm;
|
||||||
|
|
||||||
newForm.Closed += async (s, en) =>
|
newForm.Closed += async (s, en) =>
|
||||||
{
|
{
|
||||||
await CloseModal(newForm, parentForm);
|
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.OnInit(new InitEventArgs(args));
|
||||||
|
|
||||||
await newForm.OnOpened(new EventArgs());
|
await newForm.OnOpened(new EventArgs());
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ namespace TelegramBotBase.Base
|
|||||||
|
|
||||||
private static object __evOnMessage = new object();
|
private static object __evOnMessage = new object();
|
||||||
|
|
||||||
|
private static object __evOnMessageEdit = new object();
|
||||||
|
|
||||||
private static object __evCallbackQuery = new object();
|
private static object __evCallbackQuery = new object();
|
||||||
|
|
||||||
|
|
||||||
@@ -84,13 +86,11 @@ namespace TelegramBotBase.Base
|
|||||||
{
|
{
|
||||||
this.TelegramClient.Timeout = new TimeSpan(0, 0, 30);
|
this.TelegramClient.Timeout = new TimeSpan(0, 0, 30);
|
||||||
|
|
||||||
|
|
||||||
this.TelegramClient.OnMessage += TelegramClient_OnMessage;
|
this.TelegramClient.OnMessage += TelegramClient_OnMessage;
|
||||||
|
this.TelegramClient.OnMessageEdited += TelegramClient_OnMessageEdited;
|
||||||
this.TelegramClient.OnCallbackQuery += TelegramClient_OnCallbackQuery;
|
this.TelegramClient.OnCallbackQuery += TelegramClient_OnCallbackQuery;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async void TelegramClient_OnMessage(object sender, Telegram.Bot.Args.MessageEventArgs e)
|
private async void TelegramClient_OnMessage(object sender, Telegram.Bot.Args.MessageEventArgs e)
|
||||||
{
|
{
|
||||||
//Skip empty messages by default
|
//Skip empty messages by default
|
||||||
@@ -109,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)
|
private async void TelegramClient_OnCallbackQuery(object sender, Telegram.Bot.Args.CallbackQueryEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -143,6 +162,23 @@ namespace TelegramBotBase.Base
|
|||||||
(this.__Events[__evOnMessage] as EventHandler<MessageResult>)?.Invoke(this, result);
|
(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
|
public event EventHandler<MessageResult> Action
|
||||||
{
|
{
|
||||||
add
|
add
|
||||||
|
|||||||
@@ -113,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 bool Handled { get; set; } = false;
|
||||||
|
|
||||||
public String RawData
|
public String RawData
|
||||||
|
|||||||
@@ -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>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+93
-14
@@ -5,8 +5,11 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Telegram.Bot;
|
using Telegram.Bot;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
|
using TelegramBotBase.Attributes;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
using TelegramBotBase.Interfaces;
|
||||||
using TelegramBotBase.Sessions;
|
using TelegramBotBase.Sessions;
|
||||||
|
|
||||||
namespace TelegramBotBase
|
namespace TelegramBotBase
|
||||||
@@ -60,6 +63,11 @@ namespace TelegramBotBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool LogAllMessages { get; set; } = false;
|
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>
|
/// <summary>
|
||||||
/// How often could a form navigate to another (within one user action/call/message)
|
/// How often could a form navigate to another (within one user action/call/message)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -74,6 +82,7 @@ namespace TelegramBotBase
|
|||||||
this.APIKey = apiKey;
|
this.APIKey = apiKey;
|
||||||
|
|
||||||
this.Client = new Base.MessageClient(this.APIKey);
|
this.Client = new Base.MessageClient(this.APIKey);
|
||||||
|
this.Client.TelegramClient.Timeout = new TimeSpan(0, 1, 0);
|
||||||
|
|
||||||
this.SystemCalls = new List<string>();
|
this.SystemCalls = new List<string>();
|
||||||
|
|
||||||
@@ -161,12 +170,18 @@ namespace TelegramBotBase
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this.Client.Message += Client_Message;
|
this.Client.Message += Client_Message;
|
||||||
|
this.Client.MessageEdit += Client_MessageEdit;
|
||||||
this.Client.Action += Client_Action;
|
this.Client.Action += Client_Action;
|
||||||
|
|
||||||
|
if (this.StateMachine != null)
|
||||||
|
{
|
||||||
|
this.Sessions.LoadSessionStates(this.StateMachine);
|
||||||
|
}
|
||||||
|
|
||||||
this.Client.TelegramClient.StartReceiving();
|
this.Client.TelegramClient.StartReceiving();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stop your Bot
|
/// Stop your Bot
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -179,6 +194,11 @@ namespace TelegramBotBase
|
|||||||
this.Client.Action -= Client_Action;
|
this.Client.Action -= Client_Action;
|
||||||
|
|
||||||
this.Client.TelegramClient.StopReceiving();
|
this.Client.TelegramClient.StopReceiving();
|
||||||
|
|
||||||
|
if (this.StateMachine != null)
|
||||||
|
{
|
||||||
|
this.Sessions.SaveSessionStates(this.StateMachine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -197,7 +217,7 @@ namespace TelegramBotBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Client_Message(object sender, MessageResult e)
|
private async void Client_Message(object sender, MessageResult e)
|
||||||
{
|
{
|
||||||
if (this.SkipAllMessages)
|
if (this.SkipAllMessages)
|
||||||
return;
|
return;
|
||||||
@@ -209,12 +229,12 @@ namespace TelegramBotBase
|
|||||||
|
|
||||||
if (LogAllMessages)
|
if (LogAllMessages)
|
||||||
{
|
{
|
||||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds, e));
|
OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message));
|
ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message));
|
||||||
|
|
||||||
Client_TryMessage(sender, e);
|
await Client_TryMessage(sender, e);
|
||||||
}
|
}
|
||||||
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
|
||||||
{
|
{
|
||||||
@@ -227,7 +247,7 @@ namespace TelegramBotBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Client_TryMessage(object sender, MessageResult e)
|
private async Task Client_TryMessage(object sender, MessageResult e)
|
||||||
{
|
{
|
||||||
DeviceSession ds = e.Device;
|
DeviceSession ds = e.Device;
|
||||||
if (ds == null)
|
if (ds == null)
|
||||||
@@ -237,9 +257,10 @@ namespace TelegramBotBase
|
|||||||
|
|
||||||
ds.LastMessage = e.Message;
|
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.LastAction = DateTime.Now;
|
||||||
ds.LastMessage = e.Message;
|
ds.LastMessage = e.Message;
|
||||||
|
|
||||||
@@ -286,15 +307,71 @@ namespace TelegramBotBase
|
|||||||
//Render Event
|
//Render Event
|
||||||
if (!ds.FormSwitched)
|
if (!ds.FormSwitched)
|
||||||
{
|
{
|
||||||
|
|
||||||
await activeForm.RenderControls(e);
|
await activeForm.RenderControls(e);
|
||||||
|
|
||||||
await activeForm.Render(e);
|
await activeForm.Render(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e.IsFirstHandler = false;
|
||||||
|
|
||||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Client_Action(object sender, MessageResult e)
|
private void Client_Action(object sender, MessageResult e)
|
||||||
@@ -306,7 +383,7 @@ namespace TelegramBotBase
|
|||||||
|
|
||||||
if (LogAllMessages)
|
if (LogAllMessages)
|
||||||
{
|
{
|
||||||
OnMessage(new MessageIncomeResult(e.DeviceId, ds, e));
|
OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
Client_TryAction(sender, e);
|
Client_TryAction(sender, e);
|
||||||
@@ -327,7 +404,7 @@ namespace TelegramBotBase
|
|||||||
e.Device = ds;
|
e.Device = ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ds.ChatTitle = e.Message.Chat.Username ?? e.Message.Chat.Title;
|
||||||
ds.LastAction = DateTime.Now;
|
ds.LastAction = DateTime.Now;
|
||||||
ds.LastMessage = e.Message;
|
ds.LastMessage = e.Message;
|
||||||
|
|
||||||
@@ -391,6 +468,8 @@ namespace TelegramBotBase
|
|||||||
await activeForm.Render(e);
|
await activeForm.Render(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e.IsFirstHandler = false;
|
||||||
|
|
||||||
} while (ds.FormSwitched && i < NavigationMaximum);
|
} while (ds.FormSwitched && i < NavigationMaximum);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -399,7 +478,7 @@ namespace TelegramBotBase
|
|||||||
/// Will be called if a session/context gets started
|
/// Will be called if a session/context gets started
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public event EventHandler<SessionBeginResult> SessionBegins
|
public event EventHandler<SessionBeginEventArgs> SessionBegins
|
||||||
{
|
{
|
||||||
add
|
add
|
||||||
{
|
{
|
||||||
@@ -411,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>
|
/// <summary>
|
||||||
/// Will be called on incomming message
|
/// Will be called on incomming message
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<MessageIncomeResult> Message
|
public event EventHandler<MessageIncomeEventArgs> Message
|
||||||
{
|
{
|
||||||
add
|
add
|
||||||
{
|
{
|
||||||
@@ -432,9 +511,9 @@ 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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,5 +13,13 @@ namespace TelegramBotBase.Constants
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MaxMessageLength = 4096;
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,12 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
using Telegram.Bot.Types.ReplyMarkups;
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Enums;
|
using TelegramBotBase.Enums;
|
||||||
|
using TelegramBotBase.Exceptions;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
|
||||||
namespace TelegramBotBase.Controls
|
namespace TelegramBotBase.Controls
|
||||||
@@ -17,6 +20,8 @@ namespace TelegramBotBase.Controls
|
|||||||
|
|
||||||
public String Title { get; set; } = "Toggle";
|
public String Title { get; set; } = "Toggle";
|
||||||
|
|
||||||
|
public String ConfirmationText { get; set; } = "";
|
||||||
|
|
||||||
private bool RenderNecessary = true;
|
private bool RenderNecessary = true;
|
||||||
|
|
||||||
private static readonly object __evButtonClicked = new object();
|
private static readonly object __evButtonClicked = new object();
|
||||||
@@ -27,6 +32,21 @@ namespace TelegramBotBase.Controls
|
|||||||
|
|
||||||
public int? MessageId { 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>
|
/// <summary>
|
||||||
/// Defines which type of Button Keyboard should be rendered.
|
/// Defines which type of Button Keyboard should be rendered.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -34,12 +54,11 @@ namespace TelegramBotBase.Controls
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
||||||
return m_eKeyboardType;
|
return m_eKeyboardType;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if(m_eKeyboardType != value)
|
if (m_eKeyboardType != value)
|
||||||
{
|
{
|
||||||
this.RenderNecessary = true;
|
this.RenderNecessary = true;
|
||||||
|
|
||||||
@@ -53,8 +72,6 @@ namespace TelegramBotBase.Controls
|
|||||||
|
|
||||||
private eKeyboardType m_eKeyboardType = eKeyboardType.ReplyKeyboard;
|
private eKeyboardType m_eKeyboardType = eKeyboardType.ReplyKeyboard;
|
||||||
|
|
||||||
private bool m_bVisible = true;
|
|
||||||
|
|
||||||
public ButtonGrid()
|
public ButtonGrid()
|
||||||
{
|
{
|
||||||
this.ButtonsForm = new ButtonForm();
|
this.ButtonsForm = new ButtonForm();
|
||||||
@@ -62,6 +79,12 @@ namespace TelegramBotBase.Controls
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ButtonGrid(eKeyboardType type) : this()
|
||||||
|
{
|
||||||
|
m_eKeyboardType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public ButtonGrid(ButtonForm form)
|
public ButtonGrid(ButtonForm form)
|
||||||
{
|
{
|
||||||
this.ButtonsForm = form;
|
this.ButtonsForm = form;
|
||||||
@@ -90,14 +113,20 @@ namespace TelegramBotBase.Controls
|
|||||||
if (this.KeyboardType != eKeyboardType.ReplyKeyboard)
|
if (this.KeyboardType != eKeyboardType.ReplyKeyboard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!result.IsFirstHandler)
|
||||||
|
return;
|
||||||
|
|
||||||
var button = ButtonsForm.ToList().FirstOrDefault(a => a.Text == result.MessageText);
|
var button = ButtonsForm.ToList().FirstOrDefault(a => a.Text.Trim() == result.MessageText);
|
||||||
|
|
||||||
if (button == null)
|
if (button == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OnButtonClicked(new ButtonClickedEventArgs(button));
|
OnButtonClicked(new ButtonClickedEventArgs(button));
|
||||||
|
|
||||||
|
//Remove button click message
|
||||||
|
if (this.DeletePreviousMessage)
|
||||||
|
await Device.DeleteMessage(result.MessageId);
|
||||||
|
|
||||||
result.Handled = true;
|
result.Handled = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -107,7 +136,10 @@ namespace TelegramBotBase.Controls
|
|||||||
if (result.Handled)
|
if (result.Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await result.ConfirmAction();
|
if (!result.IsFirstHandler)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await result.ConfirmAction(this.ConfirmationText ?? "");
|
||||||
|
|
||||||
//Find clicked button depending on Text or Value (depending on markup type)
|
//Find clicked button depending on Text or Value (depending on markup type)
|
||||||
switch (this.KeyboardType)
|
switch (this.KeyboardType)
|
||||||
@@ -133,6 +165,37 @@ namespace TelegramBotBase.Controls
|
|||||||
if (!this.RenderNecessary)
|
if (!this.RenderNecessary)
|
||||||
return;
|
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;
|
Message m = null;
|
||||||
if (this.MessageId != null)
|
if (this.MessageId != null)
|
||||||
{
|
{
|
||||||
@@ -142,12 +205,18 @@ namespace TelegramBotBase.Controls
|
|||||||
case eKeyboardType.ReplyKeyboard:
|
case eKeyboardType.ReplyKeyboard:
|
||||||
if (this.ButtonsForm.Count == 0)
|
if (this.ButtonsForm.Count == 0)
|
||||||
{
|
{
|
||||||
await this.Device.Send("", new ReplyKeyboardRemove());
|
await this.Device.HideReplyKeyboard();
|
||||||
this.MessageId = null;
|
this.MessageId = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m = await this.Device.Send(this.Title, (ReplyKeyboardMarkup)this.ButtonsForm, disableNotification: true);
|
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;
|
break;
|
||||||
@@ -164,11 +233,14 @@ namespace TelegramBotBase.Controls
|
|||||||
switch (this.KeyboardType)
|
switch (this.KeyboardType)
|
||||||
{
|
{
|
||||||
case eKeyboardType.ReplyKeyboard:
|
case eKeyboardType.ReplyKeyboard:
|
||||||
m = await this.Device.Send(this.Title, (ReplyKeyboardMarkup)this.ButtonsForm, disableNotification: true);
|
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;
|
break;
|
||||||
|
|
||||||
case eKeyboardType.InlineKeyBoard:
|
case eKeyboardType.InlineKeyBoard:
|
||||||
m = await this.Device.Send(this.Title, (InlineKeyboardMarkup)this.ButtonsForm, disableNotification: true);
|
m = await this.Device.Send(this.Title, (InlineKeyboardMarkup)this.ButtonsForm, disableNotification: true, parseMode: MessageParseMode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,21 +254,52 @@ namespace TelegramBotBase.Controls
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
public async override Task Cleanup()
|
||||||
{
|
{
|
||||||
if (this.MessageId == null)
|
if (this.MessageId == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
switch (this.KeyboardType)
|
||||||
|
{
|
||||||
|
case eKeyboardType.InlineKeyBoard:
|
||||||
|
|
||||||
await this.Device.DeleteMessage(this.MessageId.Value);
|
await this.Device.DeleteMessage(this.MessageId.Value);
|
||||||
|
|
||||||
this.MessageId = null;
|
this.MessageId = null;
|
||||||
|
|
||||||
if (this.KeyboardType == eKeyboardType.ReplyKeyboard)
|
break;
|
||||||
|
case eKeyboardType.ReplyKeyboard:
|
||||||
|
|
||||||
|
if (this.HideKeyboardOnCleanup)
|
||||||
{
|
{
|
||||||
await this.Device.Send("", new ReplyKeyboardRemove());
|
await this.Device.HideReplyKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.MessageId = null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
|
|
||||||
namespace TelegramBotBase.Form
|
namespace TelegramBotBase.Form
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Enums;
|
using TelegramBotBase.Enums;
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ namespace TelegramBotBase.Form
|
|||||||
if (this.DeleteMode != eDeleteMode.OnLeavingForm)
|
if (this.DeleteMode != eDeleteMode.OnLeavingForm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await MessageCleanup();
|
MessageCleanup().Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -20,6 +20,28 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
public ControlBase DependencyControl { 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 ButtonForm()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -102,6 +124,16 @@ namespace TelegramBotBase.Form
|
|||||||
return ikb;
|
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)
|
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
|
||||||
{
|
{
|
||||||
if (form == null)
|
if (form == null)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
|
|
||||||
namespace TelegramBotBase.Form
|
namespace TelegramBotBase.Form
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using static TelegramBotBase.Base.Async;
|
using static TelegramBotBase.Base.Async;
|
||||||
|
|
||||||
@@ -48,12 +49,16 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
OnMessage(message);
|
await OnMessage(message);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task Edited(MessageResult message)
|
||||||
|
{
|
||||||
|
await OnMessageEdit(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task OnMemberChanges(MemberChangeEventArgs e)
|
public virtual async Task OnMemberChanges(MemberChangeEventArgs e)
|
||||||
@@ -72,5 +77,10 @@ namespace TelegramBotBase.Form
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual async Task OnMessageEdit(MessageResult e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,22 @@ namespace TelegramBotBase.Form
|
|||||||
{
|
{
|
||||||
public class ModalDialog : FormBase
|
public class ModalDialog : FormBase
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains the parent from where the modal dialog has been opened.
|
||||||
|
/// </summary>
|
||||||
|
public FormBase ParentForm { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is a modal only function and does everything to close this form.
|
/// This is a modal only function and does everything to close this form.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task CloseForm()
|
public async Task CloseForm()
|
||||||
{
|
{
|
||||||
|
|
||||||
await this.CloseControls();
|
await this.CloseControls();
|
||||||
|
|
||||||
await this.OnClosed(new EventArgs());
|
await this.OnClosed(new EventArgs());
|
||||||
|
|
||||||
|
|
||||||
|
this.ParentForm?.ReturnFromModal(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
|
|
||||||
namespace TelegramBotBase.Form
|
namespace TelegramBotBase.Form
|
||||||
@@ -18,6 +19,9 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
private static object __evCompleted { 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()
|
public PromptDialog()
|
||||||
{
|
{
|
||||||
@@ -34,6 +38,13 @@ namespace TelegramBotBase.Form
|
|||||||
if (message.Handled)
|
if (message.Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (this.ShowBackButton && message.MessageText == BackLabel)
|
||||||
|
{
|
||||||
|
await this.CloseForm();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.Value == null)
|
if (this.Value == null)
|
||||||
{
|
{
|
||||||
this.Value = message.MessageText;
|
this.Value = message.MessageText;
|
||||||
@@ -47,6 +58,14 @@ namespace TelegramBotBase.Form
|
|||||||
|
|
||||||
if (this.Value == null)
|
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);
|
await this.Device.Send(this.Message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
|
|
||||||
namespace TelegramBotBase.Markdown
|
namespace TelegramBotBase.Markdown
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// https://core.telegram.org/bots/api#markdownv2-style
|
||||||
|
/// </summary>
|
||||||
public static class Generator
|
public static class Generator
|
||||||
{
|
{
|
||||||
public static ParseMode OutputMode { get; set; } = ParseMode.Markdown;
|
public static ParseMode OutputMode { get; set; } = ParseMode.Markdown;
|
||||||
@@ -36,13 +40,24 @@ namespace TelegramBotBase.Markdown
|
|||||||
/// <param name="userId"></param>
|
/// <param name="userId"></param>
|
||||||
/// <param name="title"></param>
|
/// <param name="title"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static String MentionUser(this long userId, String title = null)
|
public static String MentionUser(this int userId, String title = null)
|
||||||
{
|
{
|
||||||
return Link("tg://user?id=" + userId.ToString(), title);
|
return Link("tg://user?id=" + userId.ToString(), title);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a bold link in Markdown or HTML
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="text"></param>
|
/// <param name="text"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@@ -51,7 +66,7 @@ namespace TelegramBotBase.Markdown
|
|||||||
switch (OutputMode)
|
switch (OutputMode)
|
||||||
{
|
{
|
||||||
case ParseMode.Markdown:
|
case ParseMode.Markdown:
|
||||||
return "**" + text + "**";
|
return "*" + text + "*";
|
||||||
case ParseMode.Html:
|
case ParseMode.Html:
|
||||||
return "<b>" + text + "</b>";
|
return "<b>" + text + "</b>";
|
||||||
}
|
}
|
||||||
@@ -59,7 +74,24 @@ namespace TelegramBotBase.Markdown
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a italic link in Markdown or HTML
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="text"></param>
|
/// <param name="text"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@@ -68,7 +100,7 @@ namespace TelegramBotBase.Markdown
|
|||||||
switch (OutputMode)
|
switch (OutputMode)
|
||||||
{
|
{
|
||||||
case ParseMode.Markdown:
|
case ParseMode.Markdown:
|
||||||
return "__" + text + "__";
|
return "_" + text + "_";
|
||||||
case ParseMode.Html:
|
case ParseMode.Html:
|
||||||
return "<i>" + text + "</i>";
|
return "<i>" + text + "</i>";
|
||||||
}
|
}
|
||||||
@@ -76,7 +108,24 @@ namespace TelegramBotBase.Markdown
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a monospace link in Markdown or HTML
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="text"></param>
|
/// <param name="text"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@@ -93,7 +142,7 @@ namespace TelegramBotBase.Markdown
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a multi monospace link in Markdown or HTML
|
/// Returns a multi monospace text in Markdown or HTML
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text"></param>
|
/// <param name="text"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@@ -108,5 +157,22 @@ namespace TelegramBotBase.Markdown
|
|||||||
}
|
}
|
||||||
return text;
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||||
// übernehmen, indem Sie "*" eingeben:
|
// übernehmen, indem Sie "*" eingeben:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("2.0.0.0")]
|
[assembly: AssemblyVersion("2.1.0.0")]
|
||||||
[assembly: AssemblyFileVersion("2.0.0.0")]
|
[assembly: AssemblyFileVersion("2.1.0.0")]
|
||||||
|
|||||||
@@ -3,8 +3,11 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
|
using TelegramBotBase.Attributes;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
using TelegramBotBase.Interfaces;
|
||||||
using TelegramBotBase.Sessions;
|
using TelegramBotBase.Sessions;
|
||||||
namespace TelegramBotBase
|
namespace TelegramBotBase
|
||||||
{
|
{
|
||||||
@@ -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,9 +12,11 @@ using Telegram.Bot.Types;
|
|||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
using Telegram.Bot.Types.InputFiles;
|
using Telegram.Bot.Types.InputFiles;
|
||||||
using Telegram.Bot.Types.ReplyMarkups;
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Exceptions;
|
using TelegramBotBase.Exceptions;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
using TelegramBotBase.Markdown;
|
||||||
|
|
||||||
namespace TelegramBotBase.Sessions
|
namespace TelegramBotBase.Sessions
|
||||||
{
|
{
|
||||||
@@ -28,6 +30,11 @@ namespace TelegramBotBase.Sessions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public long DeviceId { get; set; }
|
public long DeviceId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Username of user or group
|
||||||
|
/// </summary>
|
||||||
|
public String ChatTitle { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When did any last action happend (message received or button clicked)
|
/// When did any last action happend (message received or button clicked)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -137,9 +144,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var m = await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, messageId, text, replyMarkup: markup);
|
return await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, messageId, text, replyMarkup: markup);
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -169,9 +174,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var m = await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, messageId, text, replyMarkup: markup);
|
return await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, messageId, text, replyMarkup: markup);
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -203,9 +206,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var m = await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, message.MessageId, message.Text, replyMarkup: markup);
|
return await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, message.MessageId, message.Text, replyMarkup: markup);
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -224,7 +225,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
/// <param name="replyTo"></param>
|
/// <param name="replyTo"></param>
|
||||||
/// <param name="disableNotification"></param>
|
/// <param name="disableNotification"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<Message> Send(String text, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
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)
|
if (this.ActiveForm == null)
|
||||||
return null;
|
return null;
|
||||||
@@ -238,13 +239,18 @@ namespace TelegramBotBase.Sessions
|
|||||||
throw new MaxLengthException(text.Length);
|
throw new MaxLengthException(text.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parseMode == ParseMode.MarkdownV2 && MarkdownV2AutoEscape)
|
||||||
|
{
|
||||||
|
text = text.MarkdownV2Escape();
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, 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));
|
OnMessageSent(new MessageSentEventArgs(m));
|
||||||
}
|
}
|
||||||
catch (ApiRequestException ex)
|
catch (ApiRequestException)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -264,7 +270,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
/// <param name="replyTo"></param>
|
/// <param name="replyTo"></param>
|
||||||
/// <param name="disableNotification"></param>
|
/// <param name="disableNotification"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<Message> Send(String text, InlineKeyboardMarkup markup, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
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)
|
if (this.ActiveForm == null)
|
||||||
return null;
|
return null;
|
||||||
@@ -276,13 +282,18 @@ namespace TelegramBotBase.Sessions
|
|||||||
throw new MaxLengthException(text.Length);
|
throw new MaxLengthException(text.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parseMode == ParseMode.MarkdownV2 && MarkdownV2AutoEscape)
|
||||||
|
{
|
||||||
|
text = text.MarkdownV2Escape();
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, 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));
|
OnMessageSent(new MessageSentEventArgs(m));
|
||||||
}
|
}
|
||||||
catch (ApiRequestException ex)
|
catch (ApiRequestException)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -302,7 +313,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
/// <param name="replyTo"></param>
|
/// <param name="replyTo"></param>
|
||||||
/// <param name="disableNotification"></param>
|
/// <param name="disableNotification"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<Message> Send(String text, ReplyMarkupBase markup, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Default)
|
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)
|
if (this.ActiveForm == null)
|
||||||
return null;
|
return null;
|
||||||
@@ -314,13 +325,18 @@ namespace TelegramBotBase.Sessions
|
|||||||
throw new MaxLengthException(text.Length);
|
throw new MaxLengthException(text.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parseMode == ParseMode.MarkdownV2 && MarkdownV2AutoEscape)
|
||||||
|
{
|
||||||
|
text = text.MarkdownV2Escape();
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, parseMode, 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));
|
OnMessageSent(new MessageSentEventArgs(m));
|
||||||
}
|
}
|
||||||
catch (ApiRequestException ex)
|
catch (ApiRequestException)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -355,7 +371,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
|
|
||||||
OnMessageSent(new MessageSentEventArgs(m));
|
OnMessageSent(new MessageSentEventArgs(m));
|
||||||
}
|
}
|
||||||
catch (ApiRequestException ex)
|
catch (ApiRequestException)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -382,9 +398,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
{
|
{
|
||||||
InputOnlineFile fts = new InputOnlineFile(fileStream, name);
|
InputOnlineFile fts = new InputOnlineFile(fileStream, name);
|
||||||
|
|
||||||
var m = await SendPhoto(fts, buttons, replyTo, disableNotification);
|
return await SendPhoto(fts, buttons, replyTo, disableNotification);
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,10 +417,78 @@ namespace TelegramBotBase.Sessions
|
|||||||
{
|
{
|
||||||
InputOnlineFile fts = new InputOnlineFile(fileStream, name);
|
InputOnlineFile fts = new InputOnlineFile(fileStream, name);
|
||||||
|
|
||||||
var m = await SendPhoto(fts, buttons, replyTo, disableNotification);
|
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;
|
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>
|
/// <summary>
|
||||||
@@ -425,9 +507,33 @@ namespace TelegramBotBase.Sessions
|
|||||||
|
|
||||||
InputOnlineFile fts = new InputOnlineFile(ms, filename);
|
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>
|
/// <summary>
|
||||||
@@ -492,6 +598,26 @@ namespace TelegramBotBase.Sessions
|
|||||||
return await this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, requestMessage, replyMarkup: rcl);
|
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>
|
/// <summary>
|
||||||
/// Deletes a message
|
/// Deletes a message
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -505,7 +631,7 @@ namespace TelegramBotBase.Sessions
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (ApiRequestException ex)
|
catch (ApiRequestException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
|
<TargetFrameworks>netstandard2.0;net461;netcoreapp3.1</TargetFrameworks>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
|
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
|
||||||
<RunAnalyzersDuringLiveAnalysis>false</RunAnalyzersDuringLiveAnalysis>
|
<RunAnalyzersDuringLiveAnalysis>false</RunAnalyzersDuringLiveAnalysis>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
@@ -67,9 +68,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="4.6.0" />
|
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
|
||||||
<PackageReference Include="Telegram.Bot" Version="15.0.0" />
|
<PackageReference Include="Telegram.Bot" Version="15.5.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,24 +1,27 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<package >
|
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>$id$</id>
|
<id>TelegramBotBase</id>
|
||||||
<version>$version$</version>
|
<version>2.1.0</version>
|
||||||
<title>$title$</title>
|
<authors>TelegramBotBase</authors>
|
||||||
<authors>$author$</authors>
|
<owners>TelegramBotBase</owners>
|
||||||
<owners>$author$</owners>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/MajMcCloud/TelegramBotFramework</projectUrl>
|
<projectUrl>https://github.com/MajMcCloud/TelegramBotFramework</projectUrl>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<description>Package Description</description>
|
||||||
<description>$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>
|
||||||
<releaseNotes>This is a context based application framework for the C# TelegramBot library.</releaseNotes>
|
<repository url="https://github.com/MajMcCloud/TelegramBotFramework" />
|
||||||
<copyright>Copyright 2019</copyright>
|
|
||||||
<tags>Telegram Bot Framework C# Addon Context Modules</tags>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="Telegram.Bot" version="14.3.0" />
|
<group targetFramework=".NETFramework4.6.1">
|
||||||
<dependency id="Newtonsoft.Json" version="11.0.2" />
|
<dependency id="Newtonsoft.Json" version="12.0.2" exclude="Build,Analyzers" />
|
||||||
<dependency id="System.Net.Requests" version="4.3.0" />
|
<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>
|
</dependencies>
|
||||||
<repository type="git"
|
|
||||||
url="https://github.com/MajMcCloud/TelegramBotFramework" />
|
|
||||||
</metadata>
|
</metadata>
|
||||||
</package>
|
</package>
|
||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Controls;
|
using TelegramBotBase.Controls;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ namespace TelegramBotBaseTest.Tests.Controls
|
|||||||
this.Init += ButtonGridForm_Init;
|
this.Init += ButtonGridForm_Init;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ButtonGridForm_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
|
private async Task ButtonGridForm_Init(object sender, InitEventArgs e)
|
||||||
{
|
{
|
||||||
m_Buttons = new ButtonGrid();
|
m_Buttons = new ButtonGrid();
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ namespace TelegramBotBaseTest.Tests.Controls
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Bg_ButtonClicked(object sender, TelegramBotBase.Base.ButtonClickedEventArgs e)
|
private async void Bg_ButtonClicked(object sender, ButtonClickedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Button == null)
|
if (e.Button == null)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
using TelegramBotBase.Controls;
|
using TelegramBotBase.Controls;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
|
|
||||||
namespace TelegramBotBaseTest.Tests.Controls
|
namespace TelegramBotBaseTest.Tests.Controls
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
using TelegramBotBase.Controls;
|
using TelegramBotBase.Controls;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
|
|
||||||
namespace TelegramBotBaseTest.Tests.Controls
|
namespace TelegramBotBaseTest.Tests.Controls
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Controls;
|
using TelegramBotBase.Controls;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ namespace TelegramBotBaseTest.Tests.Controls
|
|||||||
this.Init += ToggleButtons_Init;
|
this.Init += ToggleButtons_Init;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ToggleButtons_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
|
private async Task ToggleButtons_Init(object sender, InitEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
||||||
var tb = new ToggleButton();
|
var tb = new ToggleButton();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
using TelegramBotBase.Controls;
|
using TelegramBotBase.Controls;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
|
|
||||||
namespace TelegramBotBaseTest.Tests.Controls
|
namespace TelegramBotBaseTest.Tests.Controls
|
||||||
{
|
{
|
||||||
@@ -21,7 +22,7 @@ namespace TelegramBotBaseTest.Tests.Controls
|
|||||||
this.Init += TreeViewForms_Init;
|
this.Init += TreeViewForms_Init;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TreeViewForms_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
|
private async Task TreeViewForms_Init(object sender, InitEventArgs e)
|
||||||
{
|
{
|
||||||
view = new TreeView();
|
view = new TreeView();
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,10 @@ namespace TelegramBotBaseTest.Tests.Groups
|
|||||||
if (e.Message.From.IsBot)
|
if (e.Message.From.IsBot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//Are urls inside his message ?
|
||||||
|
if (!HasLinks(e.MessageText))
|
||||||
|
return;
|
||||||
|
|
||||||
var u = await Device.GetChatUser(from);
|
var u = await Device.GetChatUser(from);
|
||||||
|
|
||||||
//Don't kick Admins or Creators
|
//Don't kick Admins or Creators
|
||||||
@@ -88,11 +92,6 @@ namespace TelegramBotBaseTest.Tests.Groups
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Are urls inside his message ?
|
|
||||||
if (!HasLinks(e.MessageText))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
await e.Device.DeleteMessage(e.MessageId);
|
await e.Device.DeleteMessage(e.MessageId);
|
||||||
|
|
||||||
var cp = new ChatPermissions();
|
var cp = new ChatPermissions();
|
||||||
@@ -133,6 +132,16 @@ namespace TelegramBotBaseTest.Tests.Groups
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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>
|
/// <summary>
|
||||||
/// https://stackoverflow.com/a/20651284
|
/// https://stackoverflow.com/a/20651284
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
|
|
||||||
namespace TelegramBotBaseTest.Tests.Groups
|
namespace TelegramBotBaseTest.Tests.Groups
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TelegramBotBase.Args;
|
||||||
using TelegramBotBase.Base;
|
using TelegramBotBase.Base;
|
||||||
using TelegramBotBase.Form;
|
using TelegramBotBase.Form;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
README.md = README.md
|
README.md = README.md
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{BFA71E3F-31C0-4FC1-A320-4DCF704768C5}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SystemCommandsBot", "Examples\SystemCommandsBot\SystemCommandsBot.csproj", "{FC484952-3060-4F87-9809-4CD66D6961C0}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -26,10 +30,17 @@ Global
|
|||||||
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
{88EC0E02-583D-4B9D-956C-81D63C8CFCFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FC484952-3060-4F87-9809-4CD66D6961C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FC484952-3060-4F87-9809-4CD66D6961C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FC484952-3060-4F87-9809-4CD66D6961C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FC484952-3060-4F87-9809-4CD66D6961C0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{FC484952-3060-4F87-9809-4CD66D6961C0} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
|
||||||
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {59CB40E1-9FA7-4867-A56F-4F418286F057}
|
SolutionGuid = {59CB40E1-9FA7-4867-A56F-4F418286F057}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
|||||||
Reference in New Issue
Block a user