diff --git a/.gitignore b/.gitignore
index e49c333..91d25bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -252,3 +252,8 @@ TelegramBotBase/Archive
/TelegramBotBase/TelegramBotBase.1.5.2.zip
/TelegramBotBase/cpush.ps1
/TelegramBotBase/cpack.ps1
+*.ps1
+*.exe
+*.snupkg
+*.zip
+*.nuspec
diff --git a/Examples/AsyncFormUpdates/App.config b/Examples/AsyncFormUpdates/App.config
index 56efbc7..8ffc026 100644
--- a/Examples/AsyncFormUpdates/App.config
+++ b/Examples/AsyncFormUpdates/App.config
@@ -1,6 +1,378 @@
-
+
-
-
+
+
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Examples/AsyncFormUpdates/Program.cs b/Examples/AsyncFormUpdates/Program.cs
index f249391..b12cb83 100644
--- a/Examples/AsyncFormUpdates/Program.cs
+++ b/Examples/AsyncFormUpdates/Program.cs
@@ -4,18 +4,21 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
+using TelegramBotBase.Builder;
namespace AsyncFormUpdates
{
class Program
{
- static TelegramBotBase.BotBase bot = null;
+ static TelegramBotBase.BotBase bot = null;
static void Main(string[] args)
{
String apiKey = "APIKey";
- bot = new TelegramBotBase.BotBase(apiKey);
+ bot = BotBaseBuilder.Create()
+ .QuickStart(apiKey)
+ .Build();
bot.Start();
diff --git a/Examples/EFCoreBot/Database/BotDbContext.cs b/Examples/EFCoreBot/Database/BotDbContext.cs
new file mode 100644
index 0000000..18a3c4a
--- /dev/null
+++ b/Examples/EFCoreBot/Database/BotDbContext.cs
@@ -0,0 +1,12 @@
+using Microsoft.EntityFrameworkCore;
+
+namespace EFCoreBot.Database;
+
+public class BotDbContext : DbContext
+{
+ public BotDbContext(DbContextOptions options) : base(options)
+ {
+ }
+
+ public DbSet Users { get; set; }
+}
diff --git a/Examples/EFCoreBot/Database/User.cs b/Examples/EFCoreBot/Database/User.cs
new file mode 100644
index 0000000..e106815
--- /dev/null
+++ b/Examples/EFCoreBot/Database/User.cs
@@ -0,0 +1,7 @@
+namespace EFCoreBot.Database;
+
+public class User
+{
+ public long Id { get; set; }
+ public string LastMessage { get; set; }
+}
diff --git a/Examples/EFCoreBot/EFCoreBot.csproj b/Examples/EFCoreBot/EFCoreBot.csproj
new file mode 100644
index 0000000..7421594
--- /dev/null
+++ b/Examples/EFCoreBot/EFCoreBot.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ disable
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Examples/EFCoreBot/Program.cs b/Examples/EFCoreBot/Program.cs
new file mode 100644
index 0000000..fa427ee
--- /dev/null
+++ b/Examples/EFCoreBot/Program.cs
@@ -0,0 +1,23 @@
+using EFCoreBot;
+using EFCoreBot.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using TelegramBotBase.Builder;
+
+var serviceCollection = new ServiceCollection()
+ .AddDbContext(x => x.UseInMemoryDatabase("TelegramBotBase"));
+
+var serviceProvider = serviceCollection.BuildServiceProvider();
+
+var bot = BotBaseBuilder.Create()
+ .WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? throw new Exception("API_KEY is not set"))
+ .DefaultMessageLoop()
+ .WithServiceProvider(serviceProvider)
+ .NoProxy()
+ .NoCommands()
+ .NoSerialization()
+ .DefaultLanguage()
+ .Build();
+
+bot.Start();
+await Task.Delay(-1);
diff --git a/Examples/EFCoreBot/StartForm.cs b/Examples/EFCoreBot/StartForm.cs
new file mode 100644
index 0000000..1bfee77
--- /dev/null
+++ b/Examples/EFCoreBot/StartForm.cs
@@ -0,0 +1,36 @@
+using EFCoreBot.Database;
+using TelegramBotBase.Base;
+using TelegramBotBase.Form;
+
+namespace EFCoreBot;
+
+public class StartForm : FormBase
+{
+ private readonly BotDbContext _dbContext;
+
+ public StartForm(BotDbContext dbContext)
+ {
+ _dbContext = dbContext;
+ }
+
+ public override async Task Load(MessageResult message)
+ {
+ var user = await _dbContext.Users.FindAsync(Device.DeviceId);
+ if (user is null)
+ {
+ user = new User
+ {
+ Id = Device.DeviceId,
+ LastMessage = ""
+ };
+
+ _dbContext.Users.Add(user);
+ await _dbContext.SaveChangesAsync();
+ }
+
+ await Device.Send($"Your last message's text was: `{user.LastMessage}`");
+
+ user.LastMessage = string.IsNullOrWhiteSpace(message.MessageText) ? "" : message.MessageText;
+ await _dbContext.SaveChangesAsync();
+ }
+}
diff --git a/Examples/JoinHiderBot/JoinHiderBot.csproj b/Examples/JoinHiderBot/JoinHiderBot.csproj
index 1c137aa..aa8f8d7 100644
--- a/Examples/JoinHiderBot/JoinHiderBot.csproj
+++ b/Examples/JoinHiderBot/JoinHiderBot.csproj
@@ -2,11 +2,11 @@
Exe
- netcoreapp3.1
+ net6.0
-
+
diff --git a/Examples/JoinHiderBot/Program.cs b/Examples/JoinHiderBot/Program.cs
index e3c2ec5..d2d05fe 100644
--- a/Examples/JoinHiderBot/Program.cs
+++ b/Examples/JoinHiderBot/Program.cs
@@ -1,4 +1,5 @@
using System;
+using TelegramBotBase.Builder;
namespace JoinHiderBot
{
@@ -9,7 +10,9 @@ namespace JoinHiderBot
String apiKey = "";
- var bot = new TelegramBotBase.BotBase(apiKey);
+ var bot = BotBaseBuilder.Create()
+ .QuickStart(apiKey)
+ .Build();
bot.Start();
diff --git a/Examples/SystemCommandsBot/Program.cs b/Examples/SystemCommandsBot/Program.cs
index efe0e93..17ff8b7 100644
--- a/Examples/SystemCommandsBot/Program.cs
+++ b/Examples/SystemCommandsBot/Program.cs
@@ -1,4 +1,5 @@
using System;
+using TelegramBotBase.Builder;
namespace SystemCommandsBot
{
@@ -19,7 +20,9 @@ namespace SystemCommandsBot
return;
}
- var bot = new TelegramBotBase.BotBase(BotConfig.ApiKey);
+ var bot = BotBaseBuilder.Create()
+ .QuickStart(BotConfig.ApiKey)
+ .Build();
bot.Start();
diff --git a/TelegramBotBase.Extensions.Images/README.md b/TelegramBotBase.Extensions.Images/README.md
index cdef1e3..2611a85 100644
--- a/TelegramBotBase.Extensions.Images/README.md
+++ b/TelegramBotBase.Extensions.Images/README.md
@@ -1,8 +1,8 @@
# TelegramBotBase.Extensions.Images
[](https://www.nuget.org/packages/TelegramBotBase.Extensions.Images/)
-[](https://www.t.me/tgbotbase)
+[](https://www.t.me/tgbotbase)
-[](https://raw.githubusercontent.com/MajMcCloud/TelegramBotFramework/master/LICENCE.md)
-[](https://www.nuget.org/packages/TelegramBotBase.Extensions.Images)
+[](https://raw.githubusercontent.com/MajMcCloud/TelegramBotFramework/master/LICENCE.md)
+[](https://www.nuget.org/packages/TelegramBotBase.Extensions.Images)
diff --git a/TelegramBotBase.Extensions.Images/TelegramBotBase.Extensions.Images.csproj b/TelegramBotBase.Extensions.Images/TelegramBotBase.Extensions.Images.csproj
index 4b974c8..0b84053 100644
--- a/TelegramBotBase.Extensions.Images/TelegramBotBase.Extensions.Images.csproj
+++ b/TelegramBotBase.Extensions.Images/TelegramBotBase.Extensions.Images.csproj
@@ -15,11 +15,10 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
\ No newline at end of file
+
diff --git a/TelegramBotBase.Extensions.Serializer.Database.MSSQL/BotBaseBuilderExtensions.cs b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/BotBaseBuilderExtensions.cs
new file mode 100644
index 0000000..fbf22db
--- /dev/null
+++ b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/BotBaseBuilderExtensions.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Builder;
+using TelegramBotBase.Builder.Interfaces;
+
+namespace TelegramBotBase.Extensions.Serializer.Database.MSSQL
+{
+ public static class BotBaseBuilderExtensions
+ {
+
+ ///
+ /// Uses an Microsoft SQL Server Database to save and restore sessions.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static ILanguageSelectionStage UseSQLDatabase(this ISessionSerializationStage builder, String ConnectionString, Type fallbackForm = null, String tablePrefix = "tgb_")
+ {
+ var serializer = new MSSQLSerializer(ConnectionString, tablePrefix, fallbackForm);
+
+ builder.UseSerialization(serializer);
+
+ return builder as BotBaseBuilder;
+ }
+
+
+ ///
+ /// Uses an Microsoft SQL Server Database to save and restore sessions.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static ILanguageSelectionStage UseSQLDatabase(this ISessionSerializationStage builder, String HostOrIP, String DatabaseName, String UserId, String Password, Type fallbackForm = null, String tablePrefix = "tgb_")
+ {
+ var connectionString = $"Server={HostOrIP}; Database={DatabaseName}; User Id={UserId}; Password={Password}; TrustServerCertificate=true;";
+
+ var serializer = new MSSQLSerializer(connectionString, tablePrefix, fallbackForm);
+
+ builder.UseSerialization(serializer);
+
+ return builder as BotBaseBuilder;
+ }
+
+ ///
+ /// Uses an Microsoft SQL Server Database with Windows Authentication to save and restore sessions.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static ILanguageSelectionStage UseSQLDatabase(this ISessionSerializationStage builder, String HostOrIP, String DatabaseName, bool IntegratedSecurity = true, Type fallbackForm = null, String tablePrefix = "tgb_")
+ {
+ if (!IntegratedSecurity)
+ throw new ArgumentOutOfRangeException();
+
+ var connectionString = $"Server={HostOrIP}; Database={DatabaseName}; Integrated Security=true; TrustServerCertificate=true;";
+
+ var serializer = new MSSQLSerializer(connectionString, tablePrefix, fallbackForm);
+
+ builder.UseSerialization(serializer);
+
+ return builder as BotBaseBuilder;
+ }
+ }
+}
diff --git a/TelegramBotBase.Extensions.Serializer.Database.MSSQL/MSSQLSerializer.cs b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/MSSQLSerializer.cs
new file mode 100644
index 0000000..5aca6e4
--- /dev/null
+++ b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/MSSQLSerializer.cs
@@ -0,0 +1,186 @@
+using TelegramBotBase.Interfaces;
+using TelegramBotBase.Builder.Interfaces;
+using System;
+using TelegramBotBase.Base;
+using TelegramBotBase.Args;
+using TelegramBotBase.Form;
+using Microsoft.Data.SqlClient;
+using System.Data;
+
+namespace TelegramBotBase.Extensions.Serializer.Database.MSSQL
+{
+ public class MSSQLSerializer : IStateMachine
+ {
+ public Type FallbackStateForm { get; set; }
+ public string ConnectionString { get; }
+ public String TablePrefix { get; set; }
+
+ ///
+ /// Will initialize the state machine.
+ ///
+ /// Path of the file and name where to save the session details.
+ /// Type of Form which will be saved instead of Form which has attribute declared. Needs to be subclass of .
+ /// Declares of the file could be overwritten.
+ public MSSQLSerializer(String ConnectionString, String tablePrefix = "tgb_", Type fallbackStateForm = null)
+ {
+ if (ConnectionString is null)
+ {
+ throw new ArgumentNullException(nameof(ConnectionString));
+ }
+
+ this.ConnectionString = ConnectionString;
+
+ this.TablePrefix = tablePrefix;
+
+ this.FallbackStateForm = fallbackStateForm;
+
+ if (this.FallbackStateForm != null && !this.FallbackStateForm.IsSubclassOf(typeof(FormBase)))
+ {
+ throw new ArgumentException("FallbackStateForm is not a subclass of FormBase");
+ }
+ }
+
+ public StateContainer LoadFormStates()
+ {
+ var sc = new StateContainer();
+
+ using (var connection = new SqlConnection(ConnectionString))
+ {
+ connection.Open();
+
+ var command = connection.CreateCommand();
+ command.CommandText = "SELECT deviceId, deviceTitle, FormUri, QualifiedName FROM " + TablePrefix + "devices_sessions";
+
+ var dataTable = new DataTable();
+ using (var dataAdapter = new SqlDataAdapter(command))
+ {
+ dataAdapter.Fill(dataTable);
+
+ foreach (DataRow r in dataTable.Rows)
+ {
+ var se = new StateEntry()
+ {
+ DeviceId = (long)r["deviceId"],
+ ChatTitle = r["deviceTitle"].ToString(),
+ FormUri = r["FormUri"].ToString(),
+ QualifiedName = r["QualifiedName"].ToString()
+ };
+
+ sc.States.Add(se);
+
+ if (se.DeviceId > 0)
+ {
+ sc.ChatIds.Add(se.DeviceId);
+ }
+ else
+ {
+ sc.GroupIds.Add(se.DeviceId);
+ }
+
+ var data_command = connection.CreateCommand();
+ data_command.CommandText = "SELECT [key], value, type FROM " + TablePrefix + "devices_sessions_data WHERE deviceId = @deviceId";
+ data_command.Parameters.Add(new SqlParameter("@deviceId", r["deviceId"]));
+
+ var data_table = new DataTable();
+ using (var dataAdapter2 = new SqlDataAdapter(data_command))
+ {
+ dataAdapter2.Fill(data_table);
+
+ foreach (DataRow r2 in data_table.Rows)
+ {
+ var key = r2["key"].ToString();
+ var type = Type.GetType(r2["type"].ToString());
+
+ var value = Newtonsoft.Json.JsonConvert.DeserializeObject(r2["value"].ToString(), type);
+
+ se.Values.Add(key, value);
+ }
+ }
+
+ }
+
+ }
+
+
+
+ connection.Close();
+ }
+
+ return sc;
+ }
+
+ public void SaveFormStates(SaveStatesEventArgs e)
+ {
+ var container = e.States;
+
+ using (var connection = new SqlConnection(ConnectionString))
+ {
+ connection.Open();
+
+ //Cleanup old Session data
+ var clear_command = connection.CreateCommand();
+
+ clear_command.CommandText = $"DELETE FROM {TablePrefix}devices_sessions_data";
+
+ clear_command.ExecuteNonQuery();
+
+ clear_command.CommandText = $"DELETE FROM {TablePrefix}devices_sessions";
+
+ clear_command.ExecuteNonQuery();
+
+ //Prepare new session commands
+ var session_command = connection.CreateCommand();
+ var data_command = connection.CreateCommand();
+
+ session_command.CommandText = "INSERT INTO " + TablePrefix + "devices_sessions (deviceId, deviceTitle, FormUri, QualifiedName) VALUES (@deviceId, @deviceTitle, @FormUri, @QualifiedName)";
+ session_command.Parameters.Add(new SqlParameter("@deviceId", ""));
+ session_command.Parameters.Add(new SqlParameter("@deviceTitle", ""));
+ session_command.Parameters.Add(new SqlParameter("@FormUri", ""));
+ session_command.Parameters.Add(new SqlParameter("@QualifiedName", ""));
+
+ data_command.CommandText = "INSERT INTO " + TablePrefix + "devices_sessions_data (deviceId, [key], value, type) VALUES (@deviceId, @key, @value, @type)";
+ data_command.Parameters.Add(new SqlParameter("@deviceId", ""));
+ data_command.Parameters.Add(new SqlParameter("@key", ""));
+ data_command.Parameters.Add(new SqlParameter("@value", ""));
+ data_command.Parameters.Add(new SqlParameter("@type", ""));
+
+ //Store session data in database
+ foreach (var state in container.States)
+ {
+ session_command.Parameters["@deviceId"].Value = state.DeviceId;
+ session_command.Parameters["@deviceTitle"].Value = state.ChatTitle ?? "";
+ session_command.Parameters["@FormUri"].Value = state.FormUri;
+ session_command.Parameters["@QualifiedName"].Value = state.QualifiedName;
+
+ session_command.ExecuteNonQuery();
+
+ foreach (var data in state.Values)
+ {
+ data_command.Parameters["@deviceId"].Value = state.DeviceId;
+ data_command.Parameters["@key"].Value = data.Key;
+
+ var type = data.Value.GetType();
+
+ if (type.IsPrimitive || type.Equals(typeof(string)))
+ {
+ data_command.Parameters["@value"].Value = data.Value;
+ }
+ else
+ {
+ data_command.Parameters["@value"].Value = Newtonsoft.Json.JsonConvert.SerializeObject(data.Value);
+ }
+
+ data_command.Parameters["@type"].Value = type.AssemblyQualifiedName;
+
+ data_command.ExecuteNonQuery();
+ }
+
+ }
+
+ connection.Close();
+ }
+
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/TelegramBotBase.Extensions.Serializer.Database.MSSQL/README.md b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/README.md
new file mode 100644
index 0000000..1a7f027
--- /dev/null
+++ b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/README.md
@@ -0,0 +1,28 @@
+# TelegramBotBase.Extensions.Serializer.Database.MSSQL
+
+[](https://www.nuget.org/packages/TelegramBotBase.Extensions.Serializer.Database.MSSQL/)
+[](https://www.t.me/tgbotbase)
+
+
+[](https://raw.githubusercontent.com/MajMcCloud/TelegramBotFramework/master/LICENCE.md)
+[](https://www.nuget.org/packages/TelegramBotBase.Extensions.Serializer.Database.MSSQL)
+
+## How to use
+
+```csharp
+using TelegramBotBase.Extensions.Serializer.Database.MSSQL;
+
+
+var bot = BotBaseBuilder
+ .Create()
+ .WithAPIKey(APIKey)
+ .DefaultMessageLoop()
+ .WithStartForm()
+ .NoProxy()
+ .OnlyStart()
+ .UseSQLDatabase("localhost", "telegram_bot")
+ .UseEnglish()
+ .Build();
+
+bot.Start();
+```
diff --git a/TelegramBotBase.Extensions.Serializer.Database.MSSQL/TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj
new file mode 100644
index 0000000..a0d40f7
--- /dev/null
+++ b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj
@@ -0,0 +1,30 @@
+
+
+
+ netstandard2.0;net5;netcoreapp3.1;net6
+ True
+ https://github.com/MajMcCloud/TelegramBotFramework
+ https://github.com/MajMcCloud/TelegramBotFramework
+ MIT
+ true
+ snupkg
+ 1.0.1
+ 1.0.1
+ 1.0.1
+ A session serializer for Microsoft SQL Server.
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
diff --git a/TelegramBotBase.Extensions.Serializer.Database.MSSQL/create_tables.sql b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/create_tables.sql
new file mode 100644
index 0000000..587eb4f
--- /dev/null
+++ b/TelegramBotBase.Extensions.Serializer.Database.MSSQL/create_tables.sql
@@ -0,0 +1,37 @@
+USE [telegram_bot]
+GO
+/****** Object: Table [dbo].[tgb_devices_sessions] Script Date: 30.06.2022 16:22:09 ******/
+SET ANSI_NULLS ON
+GO
+SET QUOTED_IDENTIFIER ON
+GO
+CREATE TABLE [dbo].[tgb_devices_sessions](
+ [deviceId] [bigint] NOT NULL,
+ [deviceTitle] [nvarchar](512) NOT NULL,
+ [FormUri] [nvarchar](512) NOT NULL,
+ [QualifiedName] [nvarchar](512) NOT NULL,
+ CONSTRAINT [PK_tgb_devices_sessions_1] PRIMARY KEY CLUSTERED
+(
+ [deviceId] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
+) ON [PRIMARY]
+GO
+/****** Object: Table [dbo].[tgb_devices_sessions_data] Script Date: 30.06.2022 16:22:09 ******/
+SET ANSI_NULLS ON
+GO
+SET QUOTED_IDENTIFIER ON
+GO
+CREATE TABLE [dbo].[tgb_devices_sessions_data](
+ [Id] [uniqueidentifier] NOT NULL,
+ [deviceId] [bigint] NOT NULL,
+ [key] [nvarchar](512) NOT NULL,
+ [value] [nvarchar](max) NOT NULL,
+ [type] [nvarchar](512) NOT NULL,
+ CONSTRAINT [PK_tgb_devices_session_data] PRIMARY KEY CLUSTERED
+(
+ [Id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+ALTER TABLE [dbo].[tgb_devices_sessions_data] ADD CONSTRAINT [DF_tgb_devices_session_data_Id] DEFAULT (newid()) FOR [Id]
+GO
diff --git a/TelegramBotBase.Test/Program.cs b/TelegramBotBase.Test/Program.cs
index 55ac0aa..6e3eb4c 100644
--- a/TelegramBotBase.Test/Program.cs
+++ b/TelegramBotBase.Test/Program.cs
@@ -14,7 +14,7 @@ namespace TelegramBotBaseTest
{
class Program
{
- static void Main(string[] args)
+ static async void Main(string[] args)
{
String APIKey = "";
@@ -28,6 +28,7 @@ namespace TelegramBotBaseTest
.CustomCommands(a =>
{
a.Start("Starts the bot");
+ a.Add("myid", "Returns my Device ID");
a.Help("Should show you some help");
a.Settings("Should show you some settings");
a.Add("form1", "Opens test form 1");
@@ -39,48 +40,10 @@ namespace TelegramBotBaseTest
.Build();
- bb.BotCommand += async (s, en) =>
- {
- switch (en.Command)
- {
- case "/start":
-
- var start = new Menu();
-
- await en.Device.ActiveForm.NavigateTo(start);
-
- break;
- case "/form1":
-
- var form1 = new TestForm();
-
- await en.Device.ActiveForm.NavigateTo(form1);
-
- break;
-
- case "/form2":
-
- var form2 = new TestForm2();
-
- await en.Device.ActiveForm.NavigateTo(form2);
-
- break;
-
- case "/params":
-
- String m = en.Parameters.DefaultIfEmpty("").Aggregate((a, b) => a + " and " + b);
-
- await en.Device.Send("Your parameters are: " + m, replyTo: en.Device.LastMessageId);
-
- en.Handled = true;
-
- break;
- }
-
- };
+ bb.BotCommand += Bb_BotCommand;
//Update Bot commands to botfather
- bb.UploadBotCommands().Wait();
+ await bb.UploadBotCommands();
bb.SetSetting(TelegramBotBase.Enums.eSettings.LogAllMessages, true);
@@ -91,8 +54,6 @@ namespace TelegramBotBaseTest
bb.Start();
-
-
Console.WriteLine("Telegram Bot started...");
Console.WriteLine("Press q to quit application.");
@@ -104,6 +65,54 @@ namespace TelegramBotBaseTest
}
+ private static async Task Bb_BotCommand(object sender, TelegramBotBase.Args.BotCommandEventArgs en)
+ {
+ switch (en.Command)
+ {
+ case "/start":
+
+ var start = new Menu();
+
+ await en.Device.ActiveForm.NavigateTo(start);
+
+ break;
+ case "/form1":
+
+ var form1 = new TestForm();
+
+ await en.Device.ActiveForm.NavigateTo(form1);
+
+
+ break;
+
+
+ case "/form2":
+
+ var form2 = new TestForm2();
+
+ await en.Device.ActiveForm.NavigateTo(form2);
+
+ break;
+
+ case "/myid":
+
+ await en.Device.Send($"Your Device ID is: {en.DeviceId}");
+
+ en.Handled = true;
+
+ break;
+
+ case "/params":
+
+ String m = en.Parameters.DefaultIfEmpty("").Aggregate((a, b) => a + " and " + b);
+
+ await en.Device.Send("Your parameters are: " + m, replyTo: en.Device.LastMessageId);
+
+ en.Handled = true;
+
+ break;
+ }
+ }
}
}
diff --git a/TelegramBotBase/Args/MessageSentEventArgs.cs b/TelegramBotBase/Args/MessageSentEventArgs.cs
index d096db1..9cfe651 100644
--- a/TelegramBotBase/Args/MessageSentEventArgs.cs
+++ b/TelegramBotBase/Args/MessageSentEventArgs.cs
@@ -7,7 +7,7 @@ using Telegram.Bot.Types;
namespace TelegramBotBase.Args
{
- public class MessageSentEventArgs
+ public class MessageSentEventArgs : EventArgs
{
public int MessageId
{
diff --git a/TelegramBotBase/Base/DataResult.cs b/TelegramBotBase/Base/DataResult.cs
index 8fc9e34..fb87df0 100644
--- a/TelegramBotBase/Base/DataResult.cs
+++ b/TelegramBotBase/Base/DataResult.cs
@@ -108,8 +108,9 @@ namespace TelegramBotBase.Base
public async Task DownloadDocument()
{
- var encryptedContent = new System.IO.MemoryStream(this.Document.FileSize.Value);
- var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, encryptedContent);
+ var encryptedContent = new System.IO.MemoryStream();
+ encryptedContent.SetLength(this.Document.FileSize.Value);
+ var file = await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, encryptedContent);
return new InputOnlineFile(encryptedContent, this.Document.FileName);
}
@@ -122,9 +123,9 @@ namespace TelegramBotBase.Base
///
public async Task DownloadDocument(String path)
{
- var file = await this.Client.TelegramClient.GetFileAsync(this.Document.FileId);
+ var file = await Device.Client.TelegramClient.GetFileAsync(this.Document.FileId);
FileStream fs = new FileStream(path, FileMode.Create);
- await this.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
+ await Device.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
fs.Close();
fs.Dispose();
}
@@ -136,7 +137,7 @@ namespace TelegramBotBase.Base
public async Task DownloadRawDocument()
{
MemoryStream ms = new MemoryStream();
- await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, ms);
+ await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, ms);
return ms.ToArray();
}
@@ -156,7 +157,7 @@ namespace TelegramBotBase.Base
public async Task DownloadRawTextDocument(Encoding encoding)
{
MemoryStream ms = new MemoryStream();
- await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, ms);
+ await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, ms);
ms.Position = 0;
@@ -167,34 +168,36 @@ namespace TelegramBotBase.Base
public async Task DownloadVideo()
{
- var encryptedContent = new System.IO.MemoryStream(this.Video.FileSize.Value);
- var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Video.FileId, encryptedContent);
+ var encryptedContent = new System.IO.MemoryStream();
+ encryptedContent.SetLength(this.Video.FileSize.Value);
+ var file = await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Video.FileId, encryptedContent);
return new InputOnlineFile(encryptedContent, "");
}
public async Task DownloadVideo(String path)
{
- var file = await this.Client.TelegramClient.GetFileAsync(this.Video.FileId);
+ var file = await Device.Client.TelegramClient.GetFileAsync(this.Video.FileId);
FileStream fs = new FileStream(path, FileMode.Create);
- await this.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
+ await Device.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
fs.Close();
fs.Dispose();
}
public async Task DownloadAudio()
{
- var encryptedContent = new System.IO.MemoryStream(this.Audio.FileSize.Value);
- var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Audio.FileId, encryptedContent);
+ var encryptedContent = new System.IO.MemoryStream();
+ encryptedContent.SetLength(this.Audio.FileSize.Value);
+ var file = await Device.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);
+ var file = await Device.Client.TelegramClient.GetFileAsync(this.Audio.FileId);
FileStream fs = new FileStream(path, FileMode.Create);
- await this.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
+ await Device.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
fs.Close();
fs.Dispose();
}
@@ -202,8 +205,9 @@ namespace TelegramBotBase.Base
public async Task DownloadPhoto(int index)
{
var photo = this.Photos[index];
- var encryptedContent = new System.IO.MemoryStream(photo.FileSize.Value);
- var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(photo.FileId, encryptedContent);
+ var encryptedContent = new System.IO.MemoryStream();
+ encryptedContent.SetLength(photo.FileSize.Value);
+ var file = await Device.Client.TelegramClient.GetInfoAndDownloadFileAsync(photo.FileId, encryptedContent);
return new InputOnlineFile(encryptedContent, "");
}
@@ -211,9 +215,9 @@ namespace TelegramBotBase.Base
public async Task DownloadPhoto(int index, String path)
{
var photo = this.Photos[index];
- var file = await this.Client.TelegramClient.GetFileAsync(photo.FileId);
+ var file = await Device.Client.TelegramClient.GetFileAsync(photo.FileId);
FileStream fs = new FileStream(path, FileMode.Create);
- await this.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
+ await Device.Client.TelegramClient.DownloadFileAsync(file.FilePath, fs);
fs.Close();
fs.Dispose();
}
diff --git a/TelegramBotBase/Base/FormBase.cs b/TelegramBotBase/Base/FormBase.cs
index fb1cb69..291e733 100644
--- a/TelegramBotBase/Base/FormBase.cs
+++ b/TelegramBotBase/Base/FormBase.cs
@@ -55,9 +55,6 @@ namespace TelegramBotBase.Form
public async Task OnInit(InitEventArgs e)
{
- if (this.Events[__evInit] == null)
- return;
-
var handler = this.Events[__evInit]?.GetInvocationList().Cast>();
if (handler == null)
return;
@@ -87,9 +84,6 @@ namespace TelegramBotBase.Form
public async Task OnOpened(EventArgs e)
{
- if (this.Events[__evOpened] == null)
- return;
-
var handler = this.Events[__evOpened]?.GetInvocationList().Cast>();
if (handler == null)
return;
@@ -120,9 +114,6 @@ namespace TelegramBotBase.Form
public async Task OnClosed(EventArgs e)
{
- if (this.Events[__evClosed] == null)
- return;
-
var handler = this.Events[__evClosed]?.GetInvocationList().Cast>();
if (handler == null)
return;
diff --git a/TelegramBotBase/Base/MessageClient.cs b/TelegramBotBase/Base/MessageClient.cs
index e252f35..85195f9 100644
--- a/TelegramBotBase/Base/MessageClient.cs
+++ b/TelegramBotBase/Base/MessageClient.cs
@@ -159,27 +159,35 @@ namespace TelegramBotBase.Base
/// This will return the current list of bot commands.
///
///
- public async Task GetBotCommands()
+ public async Task GetBotCommands(BotCommandScope scope = null, String languageCode = null)
{
- return await this.TelegramClient.GetMyCommandsAsync();
+ return await this.TelegramClient.GetMyCommandsAsync(scope, languageCode);
}
+
///
/// This will set your bot commands to the given list.
///
///
///
- public async Task SetBotCommands(List botcommands)
+ public async Task SetBotCommands(List botcommands, BotCommandScope scope = null, String languageCode = null)
{
- await this.TelegramClient.SetMyCommandsAsync(botcommands);
+ await this.TelegramClient.SetMyCommandsAsync(botcommands, scope, languageCode);
}
-
+ ///
+ /// This will delete the current list of bot commands.
+ ///
+ ///
+ public async Task DeleteBotCommands(BotCommandScope scope = null, String languageCode = null)
+ {
+ await this.TelegramClient.DeleteMyCommandsAsync(scope, languageCode);
+ }
#region "Events"
-
+
public event Async.AsyncEventHandler MessageLoop
{
diff --git a/TelegramBotBase/Base/MessageResult.cs b/TelegramBotBase/Base/MessageResult.cs
index 762ac8f..ed5d4d2 100644
--- a/TelegramBotBase/Base/MessageResult.cs
+++ b/TelegramBotBase/Base/MessageResult.cs
@@ -29,12 +29,6 @@ namespace TelegramBotBase.Base
}
}
- public DeviceSession Device
- {
- get;
- set;
- }
-
///
/// The message id
///
@@ -170,7 +164,7 @@ namespace TelegramBotBase.Base
}
///
- /// Confirm incomming action (i.e. Button click)
+ /// Confirm incoming action (i.e. Button click)
///
///
///
diff --git a/TelegramBotBase/Base/ResultBase.cs b/TelegramBotBase/Base/ResultBase.cs
index e5d37e8..adf8ecc 100644
--- a/TelegramBotBase/Base/ResultBase.cs
+++ b/TelegramBotBase/Base/ResultBase.cs
@@ -4,12 +4,17 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Telegram.Bot;
+using TelegramBotBase.Sessions;
namespace TelegramBotBase.Base
{
public class ResultBase : EventArgs
{
- public MessageClient Client { get; set; }
+ public DeviceSession Device
+ {
+ get;
+ set;
+ }
public virtual long DeviceId { get; set; }
@@ -42,7 +47,7 @@ namespace TelegramBotBase.Base
{
try
{
- await this.Client.TelegramClient.DeleteMessageAsync(this.DeviceId, (messageId == -1 ? this.MessageId : messageId));
+ await Device.Client.TelegramClient.DeleteMessageAsync(this.DeviceId, (messageId == -1 ? this.MessageId : messageId));
}
catch
{
diff --git a/TelegramBotBase/BotBase.cs b/TelegramBotBase/BotBase.cs
index c853c30..903505c 100644
--- a/TelegramBotBase/BotBase.cs
+++ b/TelegramBotBase/BotBase.cs
@@ -13,7 +13,7 @@ using TelegramBotBase.Args;
using TelegramBotBase.Attributes;
using TelegramBotBase.Base;
using TelegramBotBase.Enums;
-using TelegramBotBase.Factories.MessageLoops;
+using TelegramBotBase.MessageLoops;
using TelegramBotBase.Form;
using TelegramBotBase.Interfaces;
using TelegramBotBase.Sessions;
@@ -24,7 +24,7 @@ namespace TelegramBotBase
/// Bot base class for full Device/Context and Messagehandling
///
///
- public class BotBase
+ public sealed class BotBase
{
public MessageClient Client { get; set; }
@@ -36,17 +36,17 @@ namespace TelegramBotBase
///
/// List of all running/active sessions
///
- public SessionBase Sessions { get; set; }
+ public SessionManager Sessions { get; set; }
///
/// Contains System commands which will be available at everytime and didnt get passed to forms, i.e. /start
///
- public List BotCommands { get; set; }
+ public Dictionary> BotCommandScopes { get; set; } = new Dictionary>();
#region "Events"
- private EventHandlerList __Events = new EventHandlerList();
+ private EventHandlerList __events = new EventHandlerList();
private static object __evSessionBegins = new object();
@@ -83,9 +83,9 @@ namespace TelegramBotBase
///
public Dictionary SystemSettings { get; private set; }
- public BotBase()
+ internal BotBase()
{
- this.SystemSettings = new Dictionary();
+ SystemSettings = new Dictionary();
SetSetting(eSettings.MaxNumberOfRetries, 5);
SetSetting(eSettings.NavigationMaximum, 10);
@@ -93,10 +93,9 @@ namespace TelegramBotBase
SetSetting(eSettings.SkipAllMessages, false);
SetSetting(eSettings.SaveSessionsOnConsoleExit, false);
- this.BotCommands = new List();
+ BotCommandScopes = new Dictionary>();
- this.Sessions = new SessionBase();
- this.Sessions.BotBase = this;
+ Sessions = new SessionManager(this);
}
@@ -104,31 +103,22 @@ namespace TelegramBotBase
///
/// Start your Bot
///
- public void Start()
+ public async Task Start()
{
- if (this.Client == null)
- return;
-
- this.Client.MessageLoop += Client_MessageLoop;
+ Client.MessageLoop += Client_MessageLoop;
- if (this.StateMachine != null)
- {
- this.Sessions.LoadSessionStates(this.StateMachine);
- }
+ if (StateMachine != null) await Sessions.LoadSessionStates(StateMachine);
+
//Enable auto session saving
- if (this.GetSetting(eSettings.SaveSessionsOnConsoleExit, false))
- {
- TelegramBotBase.Tools.Console.SetHandler(() =>
- {
- this.Sessions.SaveSessionStates();
- });
- }
+ if (GetSetting(eSettings.SaveSessionsOnConsoleExit, false))
+ TelegramBotBase.Tools.Console.SetHandler(() => { Task.Run(Sessions.SaveSessionStates); });
+
- DeviceSession.MaxNumberOfRetries = this.GetSetting(eSettings.MaxNumberOfRetries, 5);
+ DeviceSession.MaxNumberOfRetries = GetSetting(eSettings.MaxNumberOfRetries, 5);
- this.Client.StartReceiving();
+ Client.StartReceiving();
}
@@ -137,7 +127,7 @@ namespace TelegramBotBase
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
if (ds == null)
{
- ds = this.Sessions.StartSession(e.DeviceId).GetAwaiter().GetResult();
+ ds = Sessions.StartSession(e.DeviceId).GetAwaiter().GetResult();
e.Device = ds;
ds.LastMessage = e.RawData.Message;
@@ -160,24 +150,24 @@ namespace TelegramBotBase
mr.IsFirstHandler = false;
- } while (ds.FormSwitched && i < this.GetSetting(eSettings.NavigationMaximum, 10));
+ } while (ds.FormSwitched && i < GetSetting(eSettings.NavigationMaximum, 10));
}
///
/// Stop your Bot
///
- public void Stop()
+ public async Task Stop()
{
- if (this.Client == null)
+ if (Client == null)
return;
- this.Client.MessageLoop -= Client_MessageLoop;
+ Client.MessageLoop -= Client_MessageLoop;
- this.Client.StopReceiving();
+ Client.StopReceiving();
- this.Sessions.SaveSessionStates();
+ await Sessions.SaveSessionStates();
}
///
@@ -187,12 +177,12 @@ namespace TelegramBotBase
///
public async Task SentToAll(String message)
{
- if (this.Client == null)
+ if (Client == null)
return;
- foreach (var s in this.Sessions.SessionList)
+ foreach (var s in Sessions.SessionList)
{
- await this.Client.TelegramClient.SendTextMessageAsync(s.Key, message);
+ await Client.TelegramClient.SendTextMessageAsync(s.Key, message);
}
}
@@ -206,6 +196,11 @@ namespace TelegramBotBase
{
var mr = new MessageResult();
+ mr.UpdateData = new Update()
+ {
+ Message = new Message()
+ };
+
await InvokeMessageLoop(DeviceId, mr);
}
@@ -247,7 +242,34 @@ namespace TelegramBotBase
///
public async Task UploadBotCommands()
{
- await this.Client.SetBotCommands(this.BotCommands);
+ foreach (var bs in BotCommandScopes)
+ {
+ if (bs.Value != null)
+ {
+ await Client.SetBotCommands(bs.Value, bs.Key);
+ }
+ else
+ {
+ await Client.DeleteBotCommands(bs.Key);
+ }
+
+ }
+ }
+
+ ///
+ /// Searching if parameter is a known command in all configured BotCommandScopes.
+ ///
+ ///
+ ///
+ public bool IsKnownBotCommand(String command)
+ {
+ foreach (var scope in BotCommandScopes)
+ {
+ if (scope.Value.Any(a => "/" + a.Command == command))
+ return true;
+ }
+
+ return false;
}
///
@@ -257,7 +279,7 @@ namespace TelegramBotBase
///
public void SetSetting(eSettings set, uint Value)
{
- this.SystemSettings[set] = Value;
+ SystemSettings[set] = Value;
}
///
@@ -267,7 +289,7 @@ namespace TelegramBotBase
///
public void SetSetting(eSettings set, bool Value)
{
- this.SystemSettings[set] = (Value ? 1u : 0u);
+ SystemSettings[set] = (Value ? 1u : 0u);
}
///
@@ -278,10 +300,10 @@ namespace TelegramBotBase
///
public uint GetSetting(eSettings set, uint defaultValue)
{
- if (!this.SystemSettings.ContainsKey(set))
+ if (!SystemSettings.ContainsKey(set))
return defaultValue;
- return this.SystemSettings[set];
+ return SystemSettings[set];
}
///
@@ -292,10 +314,10 @@ namespace TelegramBotBase
///
public bool GetSetting(eSettings set, bool defaultValue)
{
- if (!this.SystemSettings.ContainsKey(set))
+ if (!SystemSettings.ContainsKey(set))
return defaultValue;
- return this.SystemSettings[set] == 0u ? false : true;
+ return SystemSettings[set] == 0u ? false : true;
}
#region "Events"
@@ -308,17 +330,17 @@ namespace TelegramBotBase
{
add
{
- this.__Events.AddHandler(__evSessionBegins, value);
+ __events.AddHandler(__evSessionBegins, value);
}
remove
{
- this.__Events.RemoveHandler(__evSessionBegins, value);
+ __events.RemoveHandler(__evSessionBegins, value);
}
}
public void OnSessionBegins(SessionBeginEventArgs e)
{
- (this.__Events[__evSessionBegins] as EventHandler)?.Invoke(this, e);
+ (__events[__evSessionBegins] as EventHandler)?.Invoke(this, e);
}
@@ -329,17 +351,17 @@ namespace TelegramBotBase
{
add
{
- this.__Events.AddHandler(__evMessage, value);
+ __events.AddHandler(__evMessage, value);
}
remove
{
- this.__Events.RemoveHandler(__evMessage, value);
+ __events.RemoveHandler(__evMessage, value);
}
}
public void OnMessage(MessageIncomeEventArgs e)
{
- (this.__Events[__evMessage] as EventHandler)?.Invoke(this, e);
+ (__events[__evMessage] as EventHandler)?.Invoke(this, e);
}
@@ -351,7 +373,7 @@ namespace TelegramBotBase
public async Task OnBotCommand(BotCommandEventArgs e)
{
- if (this.BotCommand != null)
+ if (BotCommand != null)
await BotCommand(this, e);
}
@@ -362,17 +384,17 @@ namespace TelegramBotBase
{
add
{
- this.__Events.AddHandler(__evException, value);
+ __events.AddHandler(__evException, value);
}
remove
{
- this.__Events.RemoveHandler(__evException, value);
+ __events.RemoveHandler(__evException, value);
}
}
public void OnException(SystemExceptionEventArgs e)
{
- (this.__Events[__evException] as EventHandler)?.Invoke(this, e);
+ (__events[__evException] as EventHandler)?.Invoke(this, e);
}
@@ -383,17 +405,17 @@ namespace TelegramBotBase
{
add
{
- this.__Events.AddHandler(__evUnhandledCall, value);
+ __events.AddHandler(__evUnhandledCall, value);
}
remove
{
- this.__Events.RemoveHandler(__evUnhandledCall, value);
+ __events.RemoveHandler(__evUnhandledCall, value);
}
}
public void OnUnhandledCall(UnhandledCallEventArgs e)
{
- (this.__Events[__evUnhandledCall] as EventHandler)?.Invoke(this, e);
+ (__events[__evUnhandledCall] as EventHandler)?.Invoke(this, e);
}
diff --git a/TelegramBotBase/Builder/BotBaseBuilder.cs b/TelegramBotBase/Builder/BotBaseBuilder.cs
index 517a8fb..63b3658 100644
--- a/TelegramBotBase/Builder/BotBaseBuilder.cs
+++ b/TelegramBotBase/Builder/BotBaseBuilder.cs
@@ -7,6 +7,7 @@ using Telegram.Bot.Types;
using TelegramBotBase.Base;
using TelegramBotBase.Builder.Interfaces;
using TelegramBotBase.Commands;
+using TelegramBotBase.Factories;
using TelegramBotBase.Form;
using TelegramBotBase.Interfaces;
using TelegramBotBase.Localizations;
@@ -23,7 +24,12 @@ namespace TelegramBotBase.Builder
MessageClient _client = null;
- List _botcommands = new List();
+ ///
+ /// Contains different Botcommands for different areas.
+ ///
+ Dictionary> _BotCommandScopes { get; set; } = new Dictionary>();
+
+ //List _botcommands = new List();
IStateMachine _statemachine = null;
@@ -111,11 +117,20 @@ namespace TelegramBotBase.Builder
public IStartFormSelectionStage DefaultMessageLoop()
{
- _messageloopfactory = new Factories.MessageLoops.FormBaseMessageLoop();
+ _messageloopfactory = new MessageLoops.FormBaseMessageLoop();
return this;
}
+
+ public IStartFormSelectionStage MinimalMessageLoop()
+ {
+ _messageloopfactory = new MessageLoops.MinimalMessageLoop();
+
+ return this;
+ }
+
+
public IStartFormSelectionStage CustomMessageLoop(IMessageLoopFactory messageLoopClass)
{
_messageloopfactory = messageLoopClass;
@@ -134,7 +149,7 @@ namespace TelegramBotBase.Builder
#endregion
- #region "Step 3 (Start Form/Factory)"
+ #region "Step 3 (Start Form/Factory)"
public INetworkingSelectionStage WithStartForm(Type startFormClass)
{
@@ -149,6 +164,19 @@ namespace TelegramBotBase.Builder
return this;
}
+ public INetworkingSelectionStage WithServiceProvider(Type startFormClass, IServiceProvider serviceProvider)
+ {
+ this._factory = new ServiceProviderStartFormFactory(startFormClass, serviceProvider);
+ return this;
+ }
+
+ public INetworkingSelectionStage WithServiceProvider(IServiceProvider serviceProvider)
+ where T : FormBase
+ {
+ this._factory = new ServiceProviderStartFormFactory(serviceProvider);
+ return this;
+ }
+
public INetworkingSelectionStage WithStartFormFactory(IStartFormFactory factory)
{
this._factory = factory;
@@ -212,7 +240,7 @@ namespace TelegramBotBase.Builder
public ISessionSerializationStage OnlyStart()
{
- _botcommands.Start("Starts the bot");
+ _BotCommandScopes.Start("Starts the bot");
return this;
@@ -220,15 +248,15 @@ namespace TelegramBotBase.Builder
public ISessionSerializationStage DefaultCommands()
{
- _botcommands.Start("Starts the bot");
- _botcommands.Help("Should show you some help");
- _botcommands.Settings("Should show you some settings");
+ _BotCommandScopes.Start("Starts the bot");
+ _BotCommandScopes.Help("Should show you some help");
+ _BotCommandScopes.Settings("Should show you some settings");
return this;
}
- public ISessionSerializationStage CustomCommands(Action> action)
+ public ISessionSerializationStage CustomCommands(Action>> action)
{
- action?.Invoke(_botcommands);
+ action?.Invoke(_BotCommandScopes);
return this;
}
@@ -307,9 +335,7 @@ namespace TelegramBotBase.Builder
bb.Client = _client;
- bb.Sessions.Client = bb.Client;
-
- bb.BotCommands = _botcommands;
+ bb.BotCommandScopes = _BotCommandScopes;
bb.StateMachine = _statemachine;
diff --git a/TelegramBotBase/Builder/Interfaces/IBotCommandsStage.cs b/TelegramBotBase/Builder/Interfaces/IBotCommandsStage.cs
index cb1507c..a275090 100644
--- a/TelegramBotBase/Builder/Interfaces/IBotCommandsStage.cs
+++ b/TelegramBotBase/Builder/Interfaces/IBotCommandsStage.cs
@@ -33,7 +33,9 @@ namespace TelegramBotBase.Builder.Interfaces
///
///
///
- ISessionSerializationStage CustomCommands(Action> action);
+
+ ISessionSerializationStage CustomCommands(Action>> action);
+
}
}
diff --git a/TelegramBotBase/Builder/Interfaces/IMessageLoopSelectionStage.cs b/TelegramBotBase/Builder/Interfaces/IMessageLoopSelectionStage.cs
index 02cf87e..429a81d 100644
--- a/TelegramBotBase/Builder/Interfaces/IMessageLoopSelectionStage.cs
+++ b/TelegramBotBase/Builder/Interfaces/IMessageLoopSelectionStage.cs
@@ -16,6 +16,14 @@ namespace TelegramBotBase.Builder.Interfaces
///
IStartFormSelectionStage DefaultMessageLoop();
+
+ ///
+ /// Chooses a minimalistic message loop, which catches all update types and only calls the Load function.
+ ///
+ ///
+ IStartFormSelectionStage MinimalMessageLoop();
+
+
///
/// Chooses a custom message loop.
///
diff --git a/TelegramBotBase/Builder/Interfaces/IStartFormSelectionStage.cs b/TelegramBotBase/Builder/Interfaces/IStartFormSelectionStage.cs
index fec05b3..78692ea 100644
--- a/TelegramBotBase/Builder/Interfaces/IStartFormSelectionStage.cs
+++ b/TelegramBotBase/Builder/Interfaces/IStartFormSelectionStage.cs
@@ -23,6 +23,22 @@ namespace TelegramBotBase.Builder.Interfaces
///
INetworkingSelectionStage WithStartForm() where T : FormBase, new();
+ ///
+ /// Chooses a StartFormFactory which will be use for new sessions.
+ ///
+ ///
+ ///
+ ///
+ INetworkingSelectionStage WithServiceProvider(Type startFormClass, IServiceProvider serviceProvider);
+
+ ///
+ /// Chooses a StartFormFactory which will be use for new sessions.
+ ///
+ ///
+ ///
+ ///
+ INetworkingSelectionStage WithServiceProvider(IServiceProvider serviceProvider) where T : FormBase;
+
///
/// Chooses a StartFormFactory which will be use for new sessions.
///
diff --git a/TelegramBotBase/Commands/Extensions.cs b/TelegramBotBase/Commands/Extensions.cs
index a07c031..8237d4f 100644
--- a/TelegramBotBase/Commands/Extensions.cs
+++ b/TelegramBotBase/Commands/Extensions.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
+using System.Data;
+using System.Linq;
using System.Text;
using Telegram.Bot.Types;
@@ -8,33 +10,28 @@ namespace TelegramBotBase.Commands
public static class Extensions
{
///
- /// Adding the default /start command with a description.
+ /// Adding the command with a description.
///
///
+ ///
///
- public static void Start(this List cmds, String description)
+ public static void Add(this Dictionary> cmds, String command, String description, BotCommandScope scope = null)
{
- cmds.Add(new BotCommand() { Command = "start", Description = description });
- }
+ if (scope == null)
+ {
+ scope = BotCommandScope.Default();
+ }
- ///
- /// Adding the default /help command with a description.
- ///
- ///
- ///
- public static void Help(this List cmds, String description)
- {
- cmds.Add(new BotCommand() { Command = "help", Description = description });
- }
+ var item = cmds.FirstOrDefault(a => a.Key.Type == scope.Type);
- ///
- /// Adding the default /settings command with a description.
- ///
- ///
- ///
- public static void Settings(this List cmds, String description)
- {
- cmds.Add(new BotCommand() { Command = "settings", Description = description });
+ if (item.Value != null)
+ {
+ item.Value.Add(new BotCommand() { Command = command, Description = description });
+ }
+ else
+ {
+ cmds.Add(scope, new List { new BotCommand() { Command = command, Description = description } });
+ }
}
///
@@ -43,9 +40,106 @@ namespace TelegramBotBase.Commands
///
///
///
- public static void Add(this List cmds, String command, String description)
+ public static void Clear(this Dictionary> cmds, BotCommandScope scope = null)
{
- cmds.Add(new BotCommand() { Command = command, Description = description });
+ if (scope == null)
+ {
+ scope = BotCommandScope.Default();
+ }
+
+ var item = cmds.FirstOrDefault(a => a.Key.Type == scope.Type);
+
+ if (item.Key != null)
+ {
+ cmds[item.Key] = null;
+ }
+ else
+ {
+ cmds[scope] = null;
+ }
}
+
+ ///
+ /// Adding the default /start command with a description.
+ ///
+ ///
+ ///
+ public static void Start(this Dictionary> cmds, String description) => Add(cmds, "start", description, null);
+
+ ///
+ /// Adding the default /help command with a description.
+ ///
+ ///
+ ///
+ public static void Help(this Dictionary> cmds, String description) => Add(cmds, "help", description, null);
+
+ ///
+ /// Adding the default /settings command with a description.
+ ///
+ ///
+ ///
+ public static void Settings(this Dictionary> cmds, String description) => Add(cmds, "settings", description, null);
+
+ ///
+ /// Clears all default commands.
+ ///
+ ///
+ public static void ClearDefaultCommands(this Dictionary> cmds) => Clear(cmds, null);
+
+ ///
+ /// Clears all commands of a specific device.
+ ///
+ ///
+ public static void ClearChatCommands(this Dictionary> cmds, long DeviceId) => Clear(cmds, new BotCommandScopeChat() { ChatId = DeviceId });
+
+ ///
+ /// Adding a chat command with a description.
+ ///
+ ///
+ ///
+ ///
+ public static void AddChatCommand(this Dictionary> cmds, long DeviceId, String command, String description) => Add(cmds, command, description, new BotCommandScopeChat() { ChatId = DeviceId });
+
+ ///
+ /// Adding a group command with a description.
+ ///
+ ///
+ ///
+ ///
+ public static void AddGroupCommand(this Dictionary> cmds, String command, String description) => Add(cmds, command, description, new BotCommandScopeAllGroupChats());
+
+ ///
+ /// Clears all group commands.
+ ///
+ ///
+ public static void ClearGroupCommands(this Dictionary> cmds) => Clear(cmds, new BotCommandScopeAllGroupChats());
+
+ ///
+ /// Adding group admin command with a description.
+ ///
+ ///
+ ///
+ ///
+ public static void AddGroupAdminCommand(this Dictionary> cmds, String command, String description) => Add(cmds, command, description, new BotCommandScopeAllChatAdministrators());
+
+ ///
+ /// Clears all group admin commands.
+ ///
+ ///
+ public static void ClearGroupAdminCommand(this Dictionary> cmds) => Clear(cmds, new BotCommandScopeAllChatAdministrators());
+
+ ///
+ /// Adding a privat command with a description.
+ ///
+ ///
+ ///
+ ///
+ public static void AddPrivateChatCommand(this Dictionary> cmds, String command, String description) => Add(cmds, command, description, new BotCommandScopeAllPrivateChats());
+
+ ///
+ /// Clears all private commands.
+ ///
+ ///
+ public static void ClearPrivateChatCommand(this Dictionary> cmds) => Clear(cmds, new BotCommandScopeAllPrivateChats());
}
}
diff --git a/TelegramBotBase/Controls/Hybrid/MultiView.cs b/TelegramBotBase/Controls/Hybrid/MultiView.cs
index 1f66264..83eb0e6 100644
--- a/TelegramBotBase/Controls/Hybrid/MultiView.cs
+++ b/TelegramBotBase/Controls/Hybrid/MultiView.cs
@@ -50,7 +50,7 @@ namespace TelegramBotBase.Controls.Hybrid
}
- private void Device_MessageSent(object sender, MessageSentEventArgs e)
+ private async Task Device_MessageSent(object sender, MessageSentEventArgs e)
{
if (e.Origin == null || !e.Origin.IsSubclassOf(typeof(MultiView)))
return;
diff --git a/TelegramBotBase/Datasources/ButtonFormDataSource.cs b/TelegramBotBase/Datasources/ButtonFormDataSource.cs
index e8fbfd4..31ef4f6 100644
--- a/TelegramBotBase/Datasources/ButtonFormDataSource.cs
+++ b/TelegramBotBase/Datasources/ButtonFormDataSource.cs
@@ -35,7 +35,7 @@ namespace TelegramBotBase.Datasources
///
- /// Returns the amount of rows exisiting.
+ /// Returns the amount of rows existing.
///
///
public virtual int Count => ButtonForm.Count;
diff --git a/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs b/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs
new file mode 100644
index 0000000..4f2a0ef
--- /dev/null
+++ b/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs
@@ -0,0 +1,35 @@
+using System;
+using Microsoft.Extensions.DependencyInjection;
+using TelegramBotBase.Form;
+using TelegramBotBase.Interfaces;
+
+namespace TelegramBotBase.Factories
+{
+ public class ServiceProviderStartFormFactory : IStartFormFactory
+ {
+ private readonly Type _startFormClass;
+ private readonly IServiceProvider _serviceProvider;
+
+ public ServiceProviderStartFormFactory(Type startFormClass, IServiceProvider serviceProvider)
+ {
+ if (!typeof(FormBase).IsAssignableFrom(startFormClass))
+ throw new ArgumentException("startFormClass argument must be a FormBase type");
+
+ _startFormClass = startFormClass;
+ _serviceProvider = serviceProvider;
+ }
+
+ public FormBase CreateForm()
+ {
+ return (FormBase)ActivatorUtilities.CreateInstance(_serviceProvider, _startFormClass);
+ }
+ }
+
+ public class ServiceProviderStartFormFactory : ServiceProviderStartFormFactory
+ where T : FormBase
+ {
+ public ServiceProviderStartFormFactory(IServiceProvider serviceProvider) : base(typeof(T), serviceProvider)
+ {
+ }
+ }
+}
diff --git a/TelegramBotBase/Form/AutoCleanForm.cs b/TelegramBotBase/Form/AutoCleanForm.cs
index 4e6a692..b05938e 100644
--- a/TelegramBotBase/Form/AutoCleanForm.cs
+++ b/TelegramBotBase/Form/AutoCleanForm.cs
@@ -67,7 +67,7 @@ namespace TelegramBotBase.Form
this.OldMessages.Add(e.Message.MessageId);
}
- private void Device_MessageSent(object sender, MessageSentEventArgs e)
+ private async Task Device_MessageSent(object sender, MessageSentEventArgs e)
{
if (this.DeleteSide == eDeleteSide.UserOnly)
return;
diff --git a/TelegramBotBase/Localizations/English.cs b/TelegramBotBase/Localizations/English.cs
index d340291..35ac031 100644
--- a/TelegramBotBase/Localizations/English.cs
+++ b/TelegramBotBase/Localizations/English.cs
@@ -28,10 +28,10 @@ namespace TelegramBotBase.Localizations
Values["ToggleButton_OnIcon"] = "⚫";
Values["ToggleButton_OffIcon"] = "⚪";
Values["ToggleButton_Title"] = "Toggle";
- Values["ToggleButton_Changed"] = "Choosen";
+ Values["ToggleButton_Changed"] = "Chosen";
Values["MultiToggleButton_SelectedIcon"] = "✅";
Values["MultiToggleButton_Title"] = "Multi-Toggle";
- Values["MultiToggleButton_Changed"] = "Choosen";
+ Values["MultiToggleButton_Changed"] = "Chosen";
Values["PromptDialog_Back"] = "Back";
Values["ToggleButton_Changed"] = "Setting changed";
}
diff --git a/TelegramBotBase/Factories/MessageLoops/FormBaseMessageLoop.cs b/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs
similarity index 93%
rename from TelegramBotBase/Factories/MessageLoops/FormBaseMessageLoop.cs
rename to TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs
index 6568e19..3a6b00c 100644
--- a/TelegramBotBase/Factories/MessageLoops/FormBaseMessageLoop.cs
+++ b/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs
@@ -11,8 +11,11 @@ using TelegramBotBase.Enums;
using TelegramBotBase.Interfaces;
using TelegramBotBase.Sessions;
-namespace TelegramBotBase.Factories.MessageLoops
+namespace TelegramBotBase.MessageLoops
{
+ ///
+ /// Thats the default message loop which reacts to Message, EditMessage and CallbackQuery.
+ ///
public class FormBaseMessageLoop : IMessageLoopFactory
{
private static object __evUnhandledCall = new object();
@@ -37,7 +40,7 @@ namespace TelegramBotBase.Factories.MessageLoops
}
//Is this a bot command ?
- if (mr.IsFirstHandler && mr.IsBotCommand && Bot.BotCommands.Count(a => "/" + a.Command == mr.BotCommand) > 0)
+ if (mr.IsFirstHandler && mr.IsBotCommand && Bot.IsKnownBotCommand(mr.BotCommand))
{
var sce = new BotCommandEventArgs(mr.BotCommand, mr.BotCommandParameters, mr.Message, session.DeviceId, session);
await Bot.OnBotCommand(sce);
diff --git a/TelegramBotBase/MessageLoops/FullMessageLoop.cs b/TelegramBotBase/MessageLoops/FullMessageLoop.cs
new file mode 100644
index 0000000..63e8160
--- /dev/null
+++ b/TelegramBotBase/MessageLoops/FullMessageLoop.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using TelegramBotBase.Args;
+using TelegramBotBase.Base;
+using TelegramBotBase.Enums;
+using TelegramBotBase.Interfaces;
+using TelegramBotBase.Sessions;
+
+namespace TelegramBotBase.MessageLoops
+{
+ ///
+ /// This message loop reacts to all update types.
+ ///
+ public class FullMessageLoop : IMessageLoopFactory
+ {
+ private static object __evUnhandledCall = new object();
+
+ private EventHandlerList __Events = new EventHandlerList();
+
+ public FullMessageLoop()
+ {
+
+ }
+
+ public async Task MessageLoop(BotBase Bot, DeviceSession session, UpdateResult ur, MessageResult mr)
+ {
+ var update = ur.RawData;
+
+
+ //Is this a bot command ?
+ if (mr.IsFirstHandler && mr.IsBotCommand && Bot.IsKnownBotCommand(mr.BotCommand))
+ {
+ var sce = new BotCommandEventArgs(mr.BotCommand, mr.BotCommandParameters, mr.Message, session.DeviceId, session);
+ await Bot.OnBotCommand(sce);
+
+ if (sce.Handled)
+ return;
+ }
+
+ mr.Device = session;
+
+ var activeForm = session.ActiveForm;
+
+ //Pre Loading Event
+ await activeForm.PreLoad(mr);
+
+ //Send Load event to controls
+ await activeForm.LoadControls(mr);
+
+ //Loading Event
+ await activeForm.Load(mr);
+
+
+ //Is Attachment ? (Photo, Audio, Video, Contact, Location, Document) (Ignore Callback Queries)
+ if (update.Type == Telegram.Bot.Types.Enums.UpdateType.Message)
+ {
+ if (mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Contact
+ | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Document
+ | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Location
+ | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Photo
+ | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Video
+ | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Audio)
+ {
+ await activeForm.SentData(new DataResult(ur));
+ }
+ }
+
+ //Action Event
+ if (!session.FormSwitched && mr.IsAction)
+ {
+ //Send Action event to controls
+ await activeForm.ActionControls(mr);
+
+ //Send Action event to form itself
+ await activeForm.Action(mr);
+
+ if (!mr.Handled)
+ {
+ var uhc = new UnhandledCallEventArgs(ur.Message.Text, mr.RawData, session.DeviceId, mr.MessageId, ur.Message, session);
+ OnUnhandledCall(uhc);
+
+ if (uhc.Handled)
+ {
+ mr.Handled = true;
+ if (!session.FormSwitched)
+ {
+ return;
+ }
+ }
+ }
+
+ }
+
+ if (!session.FormSwitched)
+ {
+ //Render Event
+ await activeForm.RenderControls(mr);
+
+ await activeForm.Render(mr);
+ }
+
+ }
+
+ ///
+ /// Will be called if no form handeled this call
+ ///
+ public event EventHandler UnhandledCall
+ {
+ add
+ {
+ this.__Events.AddHandler(__evUnhandledCall, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evUnhandledCall, value);
+ }
+ }
+
+ public void OnUnhandledCall(UnhandledCallEventArgs e)
+ {
+ (this.__Events[__evUnhandledCall] as EventHandler)?.Invoke(this, e);
+
+ }
+ }
+}
diff --git a/TelegramBotBase/MessageLoops/MinimalMessageLoop.cs b/TelegramBotBase/MessageLoops/MinimalMessageLoop.cs
new file mode 100644
index 0000000..0be394b
--- /dev/null
+++ b/TelegramBotBase/MessageLoops/MinimalMessageLoop.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using TelegramBotBase.Args;
+using TelegramBotBase.Base;
+using TelegramBotBase.Enums;
+using TelegramBotBase.Interfaces;
+using TelegramBotBase.Sessions;
+
+namespace TelegramBotBase.MessageLoops
+{
+ ///
+ /// This is a minimal message loop which will react to all update types and just calling the Load method.
+ ///
+ public class MinimalMessageLoop : IMessageLoopFactory
+ {
+ private static object __evUnhandledCall = new object();
+
+ private EventHandlerList __Events = new EventHandlerList();
+
+ public MinimalMessageLoop()
+ {
+
+ }
+
+ public async Task MessageLoop(BotBase Bot, DeviceSession session, UpdateResult ur, MessageResult mr)
+ {
+ var update = ur.RawData;
+
+
+ mr.Device = session;
+
+ var activeForm = session.ActiveForm;
+
+ //Loading Event
+ await activeForm.Load(mr);
+
+ }
+
+ ///
+ /// Will be called if no form handeled this call
+ ///
+ public event EventHandler UnhandledCall
+ {
+ add
+ {
+ this.__Events.AddHandler(__evUnhandledCall, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evUnhandledCall, value);
+ }
+ }
+
+ public void OnUnhandledCall(UnhandledCallEventArgs e)
+ {
+ (this.__Events[__evUnhandledCall] as EventHandler)?.Invoke(this, e);
+
+ }
+ }
+}
diff --git a/TelegramBotBase/SessionBase.cs b/TelegramBotBase/SessionManager.cs
similarity index 83%
rename from TelegramBotBase/SessionBase.cs
rename to TelegramBotBase/SessionManager.cs
index b94f59a..0cceeda 100644
--- a/TelegramBotBase/SessionBase.cs
+++ b/TelegramBotBase/SessionManager.cs
@@ -14,14 +14,14 @@ using TelegramBotBase.Sessions;
namespace TelegramBotBase
{
///
- /// Base class for managing all active sessions
+ /// Class for managing all active sessions
///
- public class SessionBase
+ public sealed class SessionManager
{
///
/// The Basic message client.
///
- public MessageClient Client { get; set; }
+ public MessageClient Client => BotBase.Client;
///
/// A list of all active sessions.
@@ -32,29 +32,13 @@ namespace TelegramBotBase
///
/// Reference to the Main BotBase instance for later use.
///
- public BotBase BotBase { get; set; }
+ public BotBase BotBase { get; }
- public SessionBase()
+ public SessionManager(BotBase botBase)
{
- this.SessionList = new Dictionary();
- }
-
- ///
- /// Get device session from Device/ChatId
- ///
- ///
- ///
- public DeviceSession this[long key]
- {
- get
- {
- return this.SessionList[key];
- }
- set
- {
- this.SessionList[key] = value;
- }
+ BotBase = botBase;
+ SessionList = new Dictionary();
}
///
@@ -64,7 +48,7 @@ namespace TelegramBotBase
///
public DeviceSession GetSession(long deviceId)
{
- DeviceSession ds = this.SessionList.FirstOrDefault(a => a.Key == deviceId).Value ?? null;
+ var ds = SessionList.FirstOrDefault(a => a.Key == deviceId).Value ?? null;
return ds;
}
@@ -77,7 +61,6 @@ namespace TelegramBotBase
public async Task StartSession(long deviceId)
{
var start = BotBase.StartFormFactory.CreateForm();
- //T start = typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { }) as T;
start.Client = this.Client;
@@ -88,7 +71,7 @@ namespace TelegramBotBase
await start.OnOpened(new EventArgs());
- this[deviceId] = ds;
+ SessionList[deviceId] = ds;
return ds;
}
@@ -98,12 +81,8 @@ namespace TelegramBotBase
///
public void EndSession(long deviceId)
{
- var d = this[deviceId];
- if (d != null)
- {
- this.SessionList.Remove(deviceId);
-
- }
+ var d = SessionList[deviceId];
+ if (d != null) SessionList.Remove(deviceId);
}
///
@@ -112,7 +91,7 @@ namespace TelegramBotBase
///
public List GetUserSessions()
{
- return this.SessionList.Where(a => a.Key > 0).Select(a => a.Value).ToList();
+ return SessionList.Where(a => a.Key > 0).Select(a => a.Value).ToList();
}
///
@@ -121,27 +100,27 @@ namespace TelegramBotBase
///
public List GetGroupSessions()
{
- return this.SessionList.Where(a => a.Key < 0).Select(a => a.Value).ToList();
+ return SessionList.Where(a => a.Key < 0).Select(a => a.Value).ToList();
}
///
/// Loads the previously saved states from the machine.
///
- public async void LoadSessionStates()
+ public async Task LoadSessionStates()
{
if (BotBase.StateMachine == null)
{
return;
}
- LoadSessionStates(BotBase.StateMachine);
+ await LoadSessionStates(BotBase.StateMachine);
}
///
/// Loads the previously saved states from the machine.
///
- public async void LoadSessionStates(IStateMachine statemachine)
+ public async Task LoadSessionStates(IStateMachine statemachine)
{
if (statemachine == null)
{
@@ -159,7 +138,7 @@ namespace TelegramBotBase
}
//Key already existing
- if (this.SessionList.ContainsKey(s.DeviceId))
+ if (SessionList.ContainsKey(s.DeviceId))
continue;
var form = t.GetConstructor(new Type[] { })?.Invoke(new object[] { }) as FormBase;
@@ -222,7 +201,7 @@ namespace TelegramBotBase
device.ChatTitle = s.ChatTitle;
- this.SessionList.Add(s.DeviceId, device);
+ SessionList.Add(s.DeviceId, device);
//Is Subclass of IStateForm
var iform = form as IStateForm;
@@ -242,7 +221,7 @@ namespace TelegramBotBase
catch
{
//Skip on exception
- this.SessionList.Remove(s.DeviceId);
+ SessionList.Remove(s.DeviceId);
}
}
@@ -254,7 +233,7 @@ namespace TelegramBotBase
///
/// Saves all open states into the machine.
///
- public void SaveSessionStates(IStateMachine statemachine)
+ public async Task SaveSessionStates(IStateMachine statemachine)
{
if (statemachine == null)
{
@@ -263,7 +242,7 @@ namespace TelegramBotBase
var states = new List();
- foreach (var s in this.SessionList)
+ foreach (var s in SessionList)
{
if (s.Value == null)
{
@@ -333,13 +312,13 @@ namespace TelegramBotBase
///
/// Saves all open states into the machine.
///
- public void SaveSessionStates()
+ public async Task SaveSessionStates()
{
- if (this.BotBase.StateMachine == null)
+ if (BotBase.StateMachine == null)
return;
- this.SaveSessionStates(this.BotBase.StateMachine);
+ await SaveSessionStates(BotBase.StateMachine);
}
}
}
diff --git a/TelegramBotBase/Sessions/DeviceSession.cs b/TelegramBotBase/Sessions/DeviceSession.cs
index 945abfd..17d52e8 100644
--- a/TelegramBotBase/Sessions/DeviceSession.cs
+++ b/TelegramBotBase/Sessions/DeviceSession.cs
@@ -84,7 +84,7 @@ namespace TelegramBotBase.Sessions
///
public Message LastMessage { get; set; }
- private MessageClient Client
+ public MessageClient Client
{
get
{
@@ -291,7 +291,8 @@ namespace TelegramBotBase.Sessions
var t = API(a => a.SendTextMessageAsync(deviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var o = GetOrigin(new StackTrace());
- OnMessageSent(new MessageSentEventArgs(await t, o));
+
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
@@ -342,7 +343,7 @@ namespace TelegramBotBase.Sessions
var t = API(a => a.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var o = GetOrigin(new StackTrace());
- OnMessageSent(new MessageSentEventArgs(await t, o));
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
@@ -380,7 +381,7 @@ namespace TelegramBotBase.Sessions
var t = API(a => a.SendTextMessageAsync(this.DeviceId, text, parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var o = GetOrigin(new StackTrace());
- OnMessageSent(new MessageSentEventArgs(await t, o));
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
@@ -410,7 +411,7 @@ namespace TelegramBotBase.Sessions
var t = API(a => a.SendPhotoAsync(this.DeviceId, file, caption: caption, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var o = GetOrigin(new StackTrace());
- OnMessageSent(new MessageSentEventArgs(await t, o));
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
@@ -440,7 +441,7 @@ namespace TelegramBotBase.Sessions
var t = API(a => a.SendVideoAsync(this.DeviceId, file, caption: caption, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var o = GetOrigin(new StackTrace());
- OnMessageSent(new MessageSentEventArgs(await t, o));
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
@@ -453,7 +454,7 @@ namespace TelegramBotBase.Sessions
///
/// Sends an video
///
- ///
+ ///
///
///
///
@@ -470,7 +471,79 @@ namespace TelegramBotBase.Sessions
var t = API(a => a.SendVideoAsync(this.DeviceId, new InputOnlineFile(url), parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
var o = GetOrigin(new StackTrace());
- OnMessageSent(new MessageSentEventArgs(await t, o));
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
+
+ return await t;
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ ///
+ /// Sends an video
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendVideo(String filename, byte[] video, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Markdown)
+ {
+ if (this.ActiveForm == null)
+ return null;
+
+ InlineKeyboardMarkup markup = buttons;
+
+ try
+ {
+ MemoryStream ms = new MemoryStream(video);
+
+ InputOnlineFile fts = new InputOnlineFile(ms, filename);
+
+ var t = API(a => a.SendVideoAsync(this.DeviceId, fts, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
+
+ var o = GetOrigin(new StackTrace());
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
+
+ return await t;
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ ///
+ /// Sends an local file as video
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendLocalVideo(String filepath, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false, ParseMode parseMode = ParseMode.Markdown)
+ {
+ if (this.ActiveForm == null)
+ return null;
+
+ InlineKeyboardMarkup markup = buttons;
+
+ try
+ {
+ FileStream fs = new FileStream(filepath, FileMode.Open);
+
+ var filename = Path.GetFileName(filepath);
+
+ InputOnlineFile fts = new InputOnlineFile(fs, filename);
+
+ var t = API(a => a.SendVideoAsync(this.DeviceId, fts, parseMode: parseMode, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
+
+ var o = GetOrigin(new StackTrace());
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
@@ -547,7 +620,7 @@ namespace TelegramBotBase.Sessions
var t = API(a => a.SendDocumentAsync(this.DeviceId, document, caption, replyMarkup: markup, disableNotification: disableNotification, replyToMessageId: replyTo));
var o = GetOrigin(new StackTrace());
- OnMessageSent(new MessageSentEventArgs(await t, o));
+ await OnMessageSent(new MessageSentEventArgs(await t, o));
return await t;
}
@@ -810,7 +883,7 @@ namespace TelegramBotBase.Sessions
///
/// Eventhandler for sent messages
///
- public event EventHandler MessageSent
+ public event Base.Async.AsyncEventHandler MessageSent
{
add
{
@@ -823,9 +896,21 @@ namespace TelegramBotBase.Sessions
}
- public void OnMessageSent(MessageSentEventArgs e)
+ public async Task OnMessageSent(MessageSentEventArgs e)
{
- (this.__Events[__evMessageSent] as EventHandler)?.Invoke(this, e);
+ if (e.Message == null)
+ return;
+
+ var handler = this.__Events[__evMessageSent]?.GetInvocationList().Cast>();
+ if (handler == null)
+ return;
+
+ foreach (var h in handler)
+ {
+ await Base.Async.InvokeAllAsync(h, this, e);
+ }
+
+ //(this.__Events[__evMessageSent] as EventHandler)?.Invoke(this, e);
}
///
diff --git a/TelegramBotBase/TelegramBotBase.csproj b/TelegramBotBase/TelegramBotBase.csproj
index 7d4eddc..a5b9666 100644
--- a/TelegramBotBase/TelegramBotBase.csproj
+++ b/TelegramBotBase/TelegramBotBase.csproj
@@ -23,6 +23,7 @@
+
@@ -57,8 +58,8 @@
-
-
+
+
diff --git a/TelegramBotFramework.sln b/TelegramBotFramework.sln
index 326160e..34eec3f 100644
--- a/TelegramBotFramework.sln
+++ b/TelegramBotFramework.sln
@@ -14,11 +14,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
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}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SystemCommandsBot", "Examples\SystemCommandsBot\SystemCommandsBot.csproj", "{FC484952-3060-4F87-9809-4CD66D6961C0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JoinHiderBot", "Examples\JoinHiderBot\JoinHiderBot.csproj", "{E804B9E5-7ACC-49D3-9253-806766C1D9A5}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JoinHiderBot", "Examples\JoinHiderBot\JoinHiderBot.csproj", "{E804B9E5-7ACC-49D3-9253-806766C1D9A5}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramBotBase.Extensions.Images", "TelegramBotBase.Extensions.Images\TelegramBotBase.Extensions.Images.csproj", "{B5DDFA45-0E01-46A5-B67D-541300CDD606}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBotBase.Extensions.Images", "TelegramBotBase.Extensions.Images\TelegramBotBase.Extensions.Images.csproj", "{B5DDFA45-0E01-46A5-B67D-541300CDD606}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsyncFormUpdates", "Examples\AsyncFormUpdates\AsyncFormUpdates.csproj", "{673A56F5-6110-4AED-A68D-562FD6ED3EA6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{E3193182-6FDA-4FA3-AD26-A487291E7681}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBotBase.Extensions.Serializer.Database.MSSQL", "TelegramBotBase.Extensions.Serializer.Database.MSSQL\TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj", "{889B170E-32E9-4F26-BB04-8D06EA367857}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFCoreBot", "Examples\EFCoreBot\EFCoreBot.csproj", "{261BED47-0404-4A9A-86FC-047DE42A7D25}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -46,6 +54,18 @@ Global
{B5DDFA45-0E01-46A5-B67D-541300CDD606}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5DDFA45-0E01-46A5-B67D-541300CDD606}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5DDFA45-0E01-46A5-B67D-541300CDD606}.Release|Any CPU.Build.0 = Release|Any CPU
+ {673A56F5-6110-4AED-A68D-562FD6ED3EA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {673A56F5-6110-4AED-A68D-562FD6ED3EA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {673A56F5-6110-4AED-A68D-562FD6ED3EA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {673A56F5-6110-4AED-A68D-562FD6ED3EA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {889B170E-32E9-4F26-BB04-8D06EA367857}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {889B170E-32E9-4F26-BB04-8D06EA367857}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {889B170E-32E9-4F26-BB04-8D06EA367857}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {889B170E-32E9-4F26-BB04-8D06EA367857}.Release|Any CPU.Build.0 = Release|Any CPU
+ {261BED47-0404-4A9A-86FC-047DE42A7D25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {261BED47-0404-4A9A-86FC-047DE42A7D25}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {261BED47-0404-4A9A-86FC-047DE42A7D25}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {261BED47-0404-4A9A-86FC-047DE42A7D25}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -53,6 +73,10 @@ Global
GlobalSection(NestedProjects) = preSolution
{FC484952-3060-4F87-9809-4CD66D6961C0} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
{E804B9E5-7ACC-49D3-9253-806766C1D9A5} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
+ {B5DDFA45-0E01-46A5-B67D-541300CDD606} = {E3193182-6FDA-4FA3-AD26-A487291E7681}
+ {673A56F5-6110-4AED-A68D-562FD6ED3EA6} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
+ {889B170E-32E9-4F26-BB04-8D06EA367857} = {E3193182-6FDA-4FA3-AD26-A487291E7681}
+ {261BED47-0404-4A9A-86FC-047DE42A7D25} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {59CB40E1-9FA7-4867-A56F-4F418286F057}
diff --git a/images/alertdialog.PNG b/images/alertdialog.PNG
deleted file mode 100644
index f03969c..0000000
Binary files a/images/alertdialog.PNG and /dev/null differ
diff --git a/images/buttongrid.gif b/images/buttongrid.gif
deleted file mode 100644
index 2deec60..0000000
Binary files a/images/buttongrid.gif and /dev/null differ
diff --git a/images/buttongrid_pagingfilter.gif b/images/buttongrid_pagingfilter.gif
deleted file mode 100644
index e887288..0000000
Binary files a/images/buttongrid_pagingfilter.gif and /dev/null differ
diff --git a/images/calendarpicker.PNG b/images/calendarpicker.PNG
deleted file mode 100644
index cd9018b..0000000
Binary files a/images/calendarpicker.PNG and /dev/null differ
diff --git a/images/calendarpicker.gif b/images/calendarpicker.gif
deleted file mode 100644
index b3642b1..0000000
Binary files a/images/calendarpicker.gif and /dev/null differ
diff --git a/images/checkedbuttonlist.gif b/images/checkedbuttonlist.gif
deleted file mode 100644
index f025fb8..0000000
Binary files a/images/checkedbuttonlist.gif and /dev/null differ
diff --git a/images/confirmdialog.PNG b/images/confirmdialog.PNG
deleted file mode 100644
index 29f311c..0000000
Binary files a/images/confirmdialog.PNG and /dev/null differ
diff --git a/images/example1.PNG b/images/example1.PNG
deleted file mode 100644
index e05722d..0000000
Binary files a/images/example1.PNG and /dev/null differ
diff --git a/images/example2.PNG b/images/example2.PNG
deleted file mode 100644
index e69ad61..0000000
Binary files a/images/example2.PNG and /dev/null differ
diff --git a/images/example3.PNG b/images/example3.PNG
deleted file mode 100644
index 2d43757..0000000
Binary files a/images/example3.PNG and /dev/null differ
diff --git a/images/example4.1.PNG b/images/example4.1.PNG
deleted file mode 100644
index 081adae..0000000
Binary files a/images/example4.1.PNG and /dev/null differ
diff --git a/images/example4.2.PNG b/images/example4.2.PNG
deleted file mode 100644
index f89d6b7..0000000
Binary files a/images/example4.2.PNG and /dev/null differ
diff --git a/images/example4.3.PNG b/images/example4.3.PNG
deleted file mode 100644
index 208784f..0000000
Binary files a/images/example4.3.PNG and /dev/null differ
diff --git a/images/example4.4.PNG b/images/example4.4.PNG
deleted file mode 100644
index 192157a..0000000
Binary files a/images/example4.4.PNG and /dev/null differ
diff --git a/images/monthpicker1.PNG b/images/monthpicker1.PNG
deleted file mode 100644
index 44c51a9..0000000
Binary files a/images/monthpicker1.PNG and /dev/null differ
diff --git a/images/monthpicker2.PNG b/images/monthpicker2.PNG
deleted file mode 100644
index 3201cac..0000000
Binary files a/images/monthpicker2.PNG and /dev/null differ
diff --git a/images/multitogglebutton.gif b/images/multitogglebutton.gif
deleted file mode 100644
index b399eae..0000000
Binary files a/images/multitogglebutton.gif and /dev/null differ
diff --git a/images/progressbar.PNG b/images/progressbar.PNG
deleted file mode 100644
index 556ab24..0000000
Binary files a/images/progressbar.PNG and /dev/null differ
diff --git a/images/promptdialog.PNG b/images/promptdialog.PNG
deleted file mode 100644
index b015067..0000000
Binary files a/images/promptdialog.PNG and /dev/null differ
diff --git a/images/taggedbuttongrid.gif b/images/taggedbuttongrid.gif
deleted file mode 100644
index 8313144..0000000
Binary files a/images/taggedbuttongrid.gif and /dev/null differ
diff --git a/images/togglebutton.gif b/images/togglebutton.gif
deleted file mode 100644
index 643ba9c..0000000
Binary files a/images/togglebutton.gif and /dev/null differ
diff --git a/images/treeview1.PNG b/images/treeview1.PNG
deleted file mode 100644
index 8e5055b..0000000
Binary files a/images/treeview1.PNG and /dev/null differ
diff --git a/images/treeview2.PNG b/images/treeview2.PNG
deleted file mode 100644
index 7a0f838..0000000
Binary files a/images/treeview2.PNG and /dev/null differ
diff --git a/images/treeview3.PNG b/images/treeview3.PNG
deleted file mode 100644
index 698d56b..0000000
Binary files a/images/treeview3.PNG and /dev/null differ
diff --git a/images/treeview4.PNG b/images/treeview4.PNG
deleted file mode 100644
index b73979d..0000000
Binary files a/images/treeview4.PNG and /dev/null differ