diff --git a/Bot.txt b/Bot.txt
new file mode 100644
index 0000000..d7d4d4f
--- /dev/null
+++ b/Bot.txt
@@ -0,0 +1,3 @@
+@TGBaseBot
+
+480896099:AAHo0KIurkdugqdZ1tYh7sik3tJ9guH2uuI
\ No newline at end of file
diff --git a/Telegram.sln b/Telegram.sln
new file mode 100644
index 0000000..633f797
--- /dev/null
+++ b/Telegram.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramBaseTest", "TelegramBaseTest\TelegramBaseTest.csproj", "{5817184C-0D59-4924-AC6C-6B943967811C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramBotBase", "TelegramBotBase\TelegramBotBase.csproj", "{A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5817184C-0D59-4924-AC6C-6B943967811C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5817184C-0D59-4924-AC6C-6B943967811C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5817184C-0D59-4924-AC6C-6B943967811C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5817184C-0D59-4924-AC6C-6B943967811C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/TelegramBaseTest/App.config b/TelegramBaseTest/App.config
new file mode 100644
index 0000000..88fa402
--- /dev/null
+++ b/TelegramBaseTest/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TelegramBaseTest/Program.cs b/TelegramBaseTest/Program.cs
new file mode 100644
index 0000000..00e5d2b
--- /dev/null
+++ b/TelegramBaseTest/Program.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase;
+using TelegramBotBase.Form;
+using TelegramBotBase.Tests;
+
+namespace TelegramBaseTest
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+
+
+
+ BotBase bb = new BotBase("480896099:AAHo0KIurkdugqdZ1tYh7sik3tJ9guH2uuI");
+
+ bb.SystemCalls.Add("/start");
+ bb.SystemCalls.Add("/form1");
+ bb.SystemCalls.Add("/form2");
+
+ bb.SystemCall += (s, en) =>
+ {
+ switch(en.Command)
+ {
+ case "/form1":
+
+ var form1 = new TestForm();
+ form1.Init();
+
+ en.Device.ActiveForm.NavigateTo(form1);
+
+ break;
+ case "/form2":
+
+ var form2 = new TestForm2();
+ form2.Init();
+
+ en.Device.ActiveForm.NavigateTo(form2);
+
+ break;
+ }
+
+ };
+
+ bb.Start();
+
+
+
+ Console.WriteLine("Telegram Bot started...");
+
+ Console.WriteLine("Press q to quit application.");
+
+
+ Console.ReadLine();
+
+ bb.Stop();
+
+ }
+ }
+}
diff --git a/TelegramBaseTest/Properties/AssemblyInfo.cs b/TelegramBaseTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9b1622a
--- /dev/null
+++ b/TelegramBaseTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("TelegramBaseTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TelegramBaseTest")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
+// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("5817184c-0d59-4924-ac6c-6b943967811c")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/TelegramBaseTest/TelegramBaseTest.csproj b/TelegramBaseTest/TelegramBaseTest.csproj
new file mode 100644
index 0000000..c648fdf
--- /dev/null
+++ b/TelegramBaseTest/TelegramBaseTest.csproj
@@ -0,0 +1,66 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {5817184C-0D59-4924-AC6C-6B943967811C}
+ Exe
+ Properties
+ TelegramBaseTest
+ TelegramBaseTest
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {a61eda27-cfdf-4bcb-b2d6-184f94904f2d}
+ TelegramBotBase
+
+
+
+
+
\ No newline at end of file
diff --git a/TelegramBotBase/Base/ActionResult.cs b/TelegramBotBase/Base/ActionResult.cs
new file mode 100644
index 0000000..f8f6a0f
--- /dev/null
+++ b/TelegramBotBase/Base/ActionResult.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TelegramBotBase.Base
+{
+ //public class ActionResult : ResultBase
+ //{
+ // public Telegram.Bot.Args.CallbackQueryEventArgs RawCallbackData { get; set; }
+
+ // public override long DeviceId
+ // {
+ // get
+ // {
+ // return this.RawCallbackData?.CallbackQuery.Message?.Chat.Id ?? 0;
+ // }
+ // }
+
+ // public String Command
+ // {
+ // get
+ // {
+ // return this.RawCallbackData.CallbackQuery.Message.Text ?? "";
+ // }
+ // }
+
+ // public String RawData
+ // {
+ // get
+ // {
+ // return this.RawCallbackData.CallbackQuery.Data;
+ // }
+ // }
+
+ // public T GetData()
+ // where T : class
+ // {
+ // T cd = null;
+ // try
+ // {
+ // cd = Newtonsoft.Json.JsonConvert.DeserializeObject(this.RawData);
+
+ // return cd;
+ // }
+ // catch
+ // {
+
+ // }
+
+ // return null;
+ // }
+
+ // ///
+ // /// Bestätigt den Erhalt der Aktion.
+ // ///
+ // ///
+ // ///
+ // public async Task ConfirmAction(String message = "")
+ // {
+ // try
+ // {
+ // await this.Client.TelegramClient.AnswerCallbackQueryAsync(this.RawCallbackData.CallbackQuery.Id, message);
+ // }
+ // catch
+ // {
+
+ // }
+ // }
+
+ // public override async Task DeleteMessage()
+ // {
+ // try
+ // {
+ // await this.Client.TelegramClient.DeleteMessageAsync(this.DeviceId, this.RawCallbackData.CallbackQuery.Message.MessageId);
+ // }
+ // catch
+ // {
+
+ // }
+ // }
+
+ // public ActionResult(Telegram.Bot.Args.CallbackQueryEventArgs callback)
+ // {
+ // this.RawCallbackData = callback;
+ // this.Message = callback.CallbackQuery.Message;
+ // }
+
+ //}
+}
diff --git a/TelegramBotBase/Base/ButtonClickedEventArgs.cs b/TelegramBotBase/Base/ButtonClickedEventArgs.cs
new file mode 100644
index 0000000..33750d9
--- /dev/null
+++ b/TelegramBotBase/Base/ButtonClickedEventArgs.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Form;
+
+namespace TelegramBotBase.Base
+{
+ public class ButtonClickedEventArgs : EventArgs
+ {
+ public ButtonBase Button { get; set; }
+
+
+ public ButtonClickedEventArgs()
+ {
+
+ }
+
+ public ButtonClickedEventArgs(ButtonBase button)
+ {
+ this.Button = button;
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Base/MessageClient.cs b/TelegramBotBase/Base/MessageClient.cs
new file mode 100644
index 0000000..9ab07eb
--- /dev/null
+++ b/TelegramBotBase/Base/MessageClient.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TelegramBotBase.Base
+{
+ public class MessageClient
+ {
+
+ public String APIKey { get; set; }
+
+ public Telegram.Bot.TelegramBotClient TelegramClient { get; set; }
+
+ private EventHandlerList __Events { get; set; } = new EventHandlerList();
+
+ private static object __evOnMessage = new object();
+
+ private static object __evCallbackQuery = new object();
+
+
+ public MessageClient(String APIKey)
+ {
+ this.APIKey = APIKey;
+ this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey);
+
+ Prepare();
+ }
+
+ public MessageClient(String APIKey, Telegram.Bot.TelegramBotClient Client)
+ {
+ this.APIKey = APIKey;
+ this.TelegramClient = Client;
+
+ Prepare();
+ }
+
+
+ public void Prepare()
+ {
+ this.TelegramClient.Timeout = new TimeSpan(0, 0, 30);
+
+
+ this.TelegramClient.OnMessage += TelegramClient_OnMessage;
+ this.TelegramClient.OnCallbackQuery += TelegramClient_OnCallbackQuery;
+
+ }
+
+
+ private async void TelegramClient_OnMessage(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;
+ OnMessage(mr);
+ }
+ catch
+ {
+
+ }
+ }
+
+ private async void TelegramClient_OnCallbackQuery(object sender, Telegram.Bot.Args.CallbackQueryEventArgs e)
+ {
+ try
+ {
+ var ar = new MessageResult(e);
+ ar.Client = this;
+ OnAction(ar);
+ }
+ catch
+ {
+
+ }
+ }
+
+
+ #region "Events"
+
+ public event EventHandler Message
+ {
+ add
+ {
+ this.__Events.AddHandler(__evOnMessage, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evOnMessage, value);
+ }
+ }
+
+ public void OnMessage(MessageResult result)
+ {
+ (this.__Events[__evOnMessage] as EventHandler)?.Invoke(this, result);
+ }
+
+ public event EventHandler Action
+ {
+ add
+ {
+ this.__Events.AddHandler(__evCallbackQuery, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evCallbackQuery, value);
+ }
+ }
+
+ public void OnAction(MessageResult result)
+ {
+ (this.__Events[__evCallbackQuery] as EventHandler)?.Invoke(this, result);
+ }
+
+
+ #endregion
+
+
+ }
+}
diff --git a/TelegramBotBase/Base/MessageResult.cs b/TelegramBotBase/Base/MessageResult.cs
new file mode 100644
index 0000000..7dec05f
--- /dev/null
+++ b/TelegramBotBase/Base/MessageResult.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TelegramBotBase.Base
+{
+ public class MessageResult : ResultBase
+ {
+ public Telegram.Bot.Args.MessageEventArgs RawMessageData { get; set; }
+
+ public Telegram.Bot.Args.CallbackQueryEventArgs RawCallbackData { get; set; }
+
+ public override long DeviceId
+ {
+ get
+ {
+ return this.RawMessageData?.Message?.Chat.Id ?? this.RawCallbackData?.CallbackQuery.Message?.Chat.Id ?? 0;
+ }
+ }
+
+ ///
+ /// Die Id der Nachricht
+ ///
+ public new int MessageId
+ {
+ get
+ {
+ return this.Message?.MessageId ?? this.RawCallbackData?.CallbackQuery?.Message?.MessageId ?? 0;
+ }
+ }
+
+ public String Command
+ {
+ get
+ {
+ return this.RawMessageData?.Message?.Text ?? "";
+ }
+ }
+
+ public String MessageText
+ {
+ get
+ {
+ return this.RawMessageData?.Message?.Text ?? "";
+ }
+ }
+
+ ///
+ /// Ist diese eine Aktion? (z.B.: Button Klick)
+ ///
+ public bool IsAction
+ {
+ get
+ {
+ return (this.RawCallbackData != null);
+ }
+ }
+
+ public bool Handled { get; set; } = false;
+
+ public String RawData
+ {
+ get
+ {
+ return this.RawCallbackData.CallbackQuery.Data;
+ }
+ }
+
+ public T GetData()
+ where T : class
+ {
+ T cd = null;
+ try
+ {
+ cd = Newtonsoft.Json.JsonConvert.DeserializeObject(this.RawData);
+
+ return cd;
+ }
+ catch
+ {
+
+ }
+
+ return null;
+ }
+
+ ///
+ /// Bestätigt den Erhalt der Aktion.
+ ///
+ ///
+ ///
+ public async Task ConfirmAction(String message = "")
+ {
+ try
+ {
+ await this.Client.TelegramClient.AnswerCallbackQueryAsync(this.RawCallbackData.CallbackQuery.Id, message);
+ }
+ catch
+ {
+
+ }
+ }
+
+ public override async Task DeleteMessage()
+ {
+ try
+ {
+ await base.DeleteMessage(this.MessageId);
+ }
+ catch
+ {
+
+ }
+ }
+
+
+ public MessageResult(Telegram.Bot.Args.MessageEventArgs rawdata)
+ {
+ this.RawMessageData = rawdata;
+ this.Message = rawdata.Message;
+ }
+
+ public MessageResult(Telegram.Bot.Args.CallbackQueryEventArgs callback)
+ {
+ this.RawCallbackData = callback;
+ this.Message = callback.CallbackQuery.Message;
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Base/MessageSentEventArgs.cs b/TelegramBotBase/Base/MessageSentEventArgs.cs
new file mode 100644
index 0000000..c71072a
--- /dev/null
+++ b/TelegramBotBase/Base/MessageSentEventArgs.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+
+namespace TelegramBotBase.Base
+{
+ public class MessageSentEventArgs
+ {
+ public int MessageId { get; set; }
+
+ public Message Message { get; set; }
+
+ public MessageSentEventArgs()
+ {
+
+ }
+
+ public MessageSentEventArgs(int MessageId, Message message)
+ {
+ this.MessageId = MessageId;
+ this.Message = message;
+ }
+
+
+ }
+}
diff --git a/TelegramBotBase/Base/ResultBase.cs b/TelegramBotBase/Base/ResultBase.cs
new file mode 100644
index 0000000..b792b7d
--- /dev/null
+++ b/TelegramBotBase/Base/ResultBase.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TelegramBotBase.Base
+{
+ public class ResultBase
+ {
+ public MessageClient Client { get; set; }
+
+ public virtual long DeviceId { get; set; }
+
+ public int MessageId
+ {
+ get
+ {
+ return this.Message.MessageId;
+ }
+ }
+
+ public Telegram.Bot.Types.Message Message { get; set; }
+
+ ///
+ /// Löscht die aktuelle Nachricht, oder die übergebene
+ ///
+ ///
+ ///
+ public virtual async Task DeleteMessage()
+ {
+ await DeleteMessage(this.MessageId);
+ }
+
+ ///
+ /// Löscht die aktuelle Nachricht, oder die übergebene
+ ///
+ ///
+ ///
+ public virtual async Task DeleteMessage(int messageId = -1)
+ {
+ try
+ {
+ await this.Client.TelegramClient.DeleteMessageAsync(this.DeviceId, (messageId == -1 ? this.MessageId : messageId));
+ }
+ catch
+ {
+
+ }
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Base/SessionBeginResult.cs b/TelegramBotBase/Base/SessionBeginResult.cs
new file mode 100644
index 0000000..084d41a
--- /dev/null
+++ b/TelegramBotBase/Base/SessionBeginResult.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Sessions;
+
+namespace TelegramBotBase.Base
+{
+ public class SessionBeginResult : EventArgs
+ {
+ public long DeviceId { get; set; }
+
+ public DeviceSession Device { get; set; }
+
+ public SessionBeginResult(long DeviceId, DeviceSession Device)
+ {
+ this.DeviceId = DeviceId;
+ this.Device = Device;
+ }
+ }
+}
diff --git a/TelegramBotBase/Base/SystemCallEventArgs.cs b/TelegramBotBase/Base/SystemCallEventArgs.cs
new file mode 100644
index 0000000..bf0b0f3
--- /dev/null
+++ b/TelegramBotBase/Base/SystemCallEventArgs.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Sessions;
+
+namespace TelegramBotBase.Base
+{
+ public class SystemCallEventArgs : EventArgs
+ {
+ public String Command { get; set; }
+
+ public long DeviceId { get; set; }
+
+ public DeviceSession Device {get;set;}
+
+
+ public SystemCallEventArgs()
+ {
+
+
+ }
+
+ public SystemCallEventArgs(String Command, long DeviceId, DeviceSession Device)
+ {
+ this.Command = Command;
+ this.DeviceId = DeviceId;
+ this.Device = Device;
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Base/SystemExceptionEventArgs.cs b/TelegramBotBase/Base/SystemExceptionEventArgs.cs
new file mode 100644
index 0000000..af2bba6
--- /dev/null
+++ b/TelegramBotBase/Base/SystemExceptionEventArgs.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Sessions;
+
+namespace TelegramBotBase.Base
+{
+ public class SystemExceptionEventArgs : EventArgs
+ {
+
+ public String Command { get; set; }
+
+ public long DeviceId { get; set; }
+
+ public DeviceSession Device { get; set; }
+
+ public Exception Error { get; set; }
+
+ public SystemExceptionEventArgs()
+ {
+
+
+ }
+
+ public SystemExceptionEventArgs(String Command, long DeviceId, DeviceSession Device, Exception error)
+ {
+ this.Command = Command;
+ this.DeviceId = DeviceId;
+ this.Device = Device;
+ this.Error = error;
+ }
+ }
+
+}
diff --git a/TelegramBotBase/Base/UnhandledCallEventArgs.cs b/TelegramBotBase/Base/UnhandledCallEventArgs.cs
new file mode 100644
index 0000000..0d2209a
--- /dev/null
+++ b/TelegramBotBase/Base/UnhandledCallEventArgs.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using TelegramBotBase.Sessions;
+
+namespace TelegramBotBase.Base
+{
+ public class UnhandledCallEventArgs : EventArgs
+ {
+ public String Command { get; set; }
+
+ public long DeviceId { get; set; }
+
+ public DeviceSession Device {get;set;}
+
+ public String RawData { get; set; }
+
+ public int MessageId { get; set; }
+
+ public Message Message { get; set; }
+
+ public bool Handled { get; set; }
+
+
+ public UnhandledCallEventArgs()
+ {
+ this.Handled = false;
+
+ }
+
+ public UnhandledCallEventArgs(String Command,String RawData, long DeviceId, int MessageId, Message message, DeviceSession Device) : this()
+ {
+ this.Command = Command;
+ this.RawData = RawData;
+ this.DeviceId = DeviceId;
+ this.MessageId = MessageId;
+ this.Message = message;
+ this.Device = Device;
+ }
+
+ }
+}
diff --git a/TelegramBotBase/BotBase.cs b/TelegramBotBase/BotBase.cs
new file mode 100644
index 0000000..699620d
--- /dev/null
+++ b/TelegramBotBase/BotBase.cs
@@ -0,0 +1,308 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Base;
+using TelegramBotBase.Form;
+using TelegramBotBase.Sessions;
+
+namespace TelegramBotBase
+{
+ public class BotBase
+ where T : FormBase
+ {
+ public MessageClient Client { get; set; }
+
+ public String APIKey { get; set; } = "";
+
+
+ public SessionBase Sessions { get; set; }
+
+ ///
+ /// Beinhaltet Systembefehle die immer erreichbar sind und nicht an die Formulare weitergereicht werden. z.b. /start
+ ///
+ public List SystemCalls { get; set; }
+
+ private EventHandlerList __Events = new EventHandlerList();
+
+ private static object __evSessionBegins = new object();
+
+ private static object __evSystemCall = new object();
+
+ private static object __evException = new object();
+
+ private static object __evUnhandledCall = new object();
+
+ public BotBase(String apiKey)
+ {
+ this.APIKey = apiKey;
+
+ this.Client = new Base.MessageClient(this.APIKey);
+
+ this.SystemCalls = new List();
+
+ this.Sessions = new SessionBase();
+ this.Sessions.Client = this.Client;
+ }
+
+ public void Start()
+ {
+ if (this.Client == null)
+ return;
+
+ this.Client.Message += Client_Message;
+ this.Client.Action += Client_Action;
+
+
+ this.Client.TelegramClient.StartReceiving();
+ }
+
+
+ public void Stop()
+ {
+ if (this.Client == null)
+ return;
+
+ this.Client.TelegramClient.StopReceiving();
+ }
+
+
+ public async Task SentToAll(String message)
+ {
+ if (this.Client == null)
+ return;
+
+ foreach (var s in this.Sessions.SessionList)
+ {
+ await this.Client.TelegramClient.SendTextMessageAsync(s.Key, message);
+ }
+ }
+
+ private void Client_Message(object sender, MessageResult e)
+ {
+ try
+ {
+ Client_TryMessage(sender, e);
+ }
+ catch (Exception ex)
+ {
+ DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
+ OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex));
+ }
+ }
+
+ private async void Client_TryMessage(object sender, MessageResult e)
+ {
+ DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
+ if (ds == null)
+ {
+ ds = await this.Sessions.StartSession(e.DeviceId);
+
+ ds.LastMessage = e.MessageId;
+
+ OnSessionBegins(new SessionBeginResult(e.DeviceId, ds));
+ }
+
+ ds.LastAction = DateTime.Now;
+ ds.LastMessage = e.MessageId;
+
+
+ //Ist das ein Systembefehl ?
+ if (e.Message.Text != null && this.SystemCalls.Contains(e.Message.Text))
+ {
+ var sce = new SystemCallEventArgs(e.Message.Text, ds.DeviceId, ds);
+ OnSystemCall(sce);
+ //return;
+ }
+
+ FormBase activeForm = null;
+
+ int i = 0;
+
+ //Sollten die Formulare gewechselt werden, alle durchgehen (maximal 10 Versuche, um Schleifen zu verhindern)
+ do
+ {
+ i++;
+
+ activeForm = ds.ActiveForm;
+
+ //Wenn das Formular sich selbst um die Events kümmert, nicht weiter machen
+ if (activeForm.CustomEventManagement)
+ return;
+
+ //Pre Loading Event
+ await activeForm.PreLoad(e);
+
+ //Loading Event
+ await activeForm.Load(e);
+
+ ////Action Event
+ //if (!activeForm.FormSwitched)
+ // await activeForm.Action(e);
+
+ //Render Event
+ if (!activeForm.FormSwitched)
+ await activeForm.Render(e);
+
+ } while (activeForm.FormSwitched && i < 10);
+
+ }
+
+ private void Client_Action(object sender, MessageResult e)
+ {
+ try
+ {
+ Client_TryAction(sender, e);
+ }
+ catch (Exception ex)
+ {
+ DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
+ OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex));
+ }
+ }
+
+ private async void Client_TryAction(object sender, MessageResult e)
+ {
+ DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
+ if (ds == null)
+ {
+ ds = await this.Sessions.StartSession(e.DeviceId);
+ }
+
+
+ ds.LastAction = DateTime.Now;
+ ds.LastMessage = e.MessageId;
+
+ FormBase activeForm = null;
+
+ int i = 0;
+
+ //Sollten die Formulare gewechselt werden, alle durchgehen (maximal 10 Versuche, um Schleifen zu verhindern)
+ do
+ {
+ i++;
+
+ activeForm = ds.ActiveForm;
+
+ //Wenn das Formular sich selbst um die Events kümmert, nicht weiter machen
+ if (activeForm.CustomEventManagement)
+ return;
+
+ //Pre Loading Event
+ await activeForm.PreLoad(e);
+
+ //Loading Event
+ await activeForm.Load(e);
+
+ //Action Event
+ if (!activeForm.FormSwitched)
+ {
+ await activeForm.Action(e);
+
+ if (!e.Handled)
+ {
+ var uhc = new UnhandledCallEventArgs(e.Message.Text, e.RawData, ds.DeviceId, e.MessageId, e.Message, ds);
+ OnUnhandledCall(uhc);
+
+ if (uhc.Handled)
+ {
+ if (activeForm.FormSwitched)
+ {
+ continue;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ }
+
+ //Render Event
+ if (!activeForm.FormSwitched)
+ await activeForm.Render(e);
+
+ } while (activeForm.FormSwitched && i < 10);
+
+ }
+
+ ///
+ /// Wird aufgerufen wenn eine Session begonnen wird
+ ///
+
+ public event EventHandler SessionBegins
+ {
+ add
+ {
+ this.__Events.AddHandler(__evSessionBegins, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evSessionBegins, value);
+ }
+ }
+
+ public void OnSessionBegins(SessionBeginResult e)
+ {
+ (this.__Events[__evSessionBegins] as EventHandler)?.Invoke(this, e);
+
+ }
+
+ public event EventHandler SystemCall
+ {
+ add
+ {
+ this.__Events.AddHandler(__evSystemCall, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evSystemCall, value);
+ }
+ }
+
+ public void OnSystemCall(SystemCallEventArgs e)
+ {
+ (this.__Events[__evSystemCall] as EventHandler)?.Invoke(this, e);
+
+ }
+
+ public event EventHandler Exception
+ {
+ add
+ {
+ this.__Events.AddHandler(__evException, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evException, value);
+ }
+ }
+
+ public void OnException(SystemExceptionEventArgs e)
+ {
+ (this.__Events[__evException] as EventHandler)?.Invoke(this, e);
+
+ }
+
+ 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/Form/AlertDialog.cs b/TelegramBotBase/Form/AlertDialog.cs
new file mode 100644
index 0000000..4634970
--- /dev/null
+++ b/TelegramBotBase/Form/AlertDialog.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Base;
+
+namespace TelegramBotBase.Form
+{
+ public class AlertDialog : PromptDialog
+ {
+ public String ButtonText { get; set; }
+
+ public AlertDialog(String Message, String ButtonText, FormBase FormToOpen = null) : base(Message)
+ {
+ this.Buttons.Add(new ButtonBase(ButtonText, "ok"));
+ this.ButtonText = ButtonText;
+
+ if (FormToOpen != null)
+ this.ButtonForms.Add("ok", FormToOpen);
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Form/ArrayPromptDialog.cs b/TelegramBotBase/Form/ArrayPromptDialog.cs
new file mode 100644
index 0000000..7a423b8
--- /dev/null
+++ b/TelegramBotBase/Form/ArrayPromptDialog.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Base;
+
+namespace TelegramBotBase.Form
+{
+ public class ArrayPromptDialog : FormBase
+ {
+ public String Message { get; set; }
+
+
+ public ButtonBase[][] Buttons { get; set; }
+
+ public Dictionary ButtonForms { get; set; } = new Dictionary();
+
+ private EventHandlerList __Events { get; set; } = new EventHandlerList();
+
+ private static object __evButtonClicked { get; } = new object();
+
+ public ArrayPromptDialog()
+ {
+
+ }
+
+ public ArrayPromptDialog(String Message)
+ {
+ this.Message = Message;
+ }
+
+ public ArrayPromptDialog(String Message, params ButtonBase[][] Buttons)
+ {
+ this.Message = Message;
+ this.Buttons = Buttons;
+ }
+
+ public override async Task Action(MessageResult message)
+ {
+ var call = message.GetData();
+
+ message.Handled = true;
+
+ if (!message.IsAction)
+ return;
+
+ await message.ConfirmAction();
+
+ await message.DeleteMessage();
+
+ var buttons = this.Buttons.Aggregate((a, b) => a.Union(b).ToArray()).ToList();
+
+ if(call==null)
+ {
+ return;
+ }
+
+ ButtonBase button = buttons.FirstOrDefault(a => a.Value == call.Value);
+
+ if (button == null)
+ {
+ return;
+ }
+
+ OnButtonClicked(new ButtonClickedEventArgs(button));
+
+ FormBase fb = ButtonForms.ContainsKey(call.Value) ? ButtonForms[call.Value] : null;
+
+ if (fb != null)
+ {
+ await this.NavigateTo(fb);
+ }
+ }
+
+
+ public override async Task Render(MessageResult message)
+ {
+ ButtonForm btn = new ButtonForm();
+
+ foreach(var bl in this.Buttons)
+ {
+ btn.AddButtonRow(bl.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList());
+ }
+
+ await this.Device.Send(this.Message, btn);
+ }
+
+
+ public event EventHandler ButtonClicked
+ {
+ add
+ {
+ this.__Events.AddHandler(__evButtonClicked, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evButtonClicked, value);
+ }
+ }
+
+ public void OnButtonClicked(ButtonClickedEventArgs e)
+ {
+ (this.__Events[__evButtonClicked] as EventHandler)?.Invoke(this, e);
+ }
+ }
+}
diff --git a/TelegramBotBase/Form/AutoCleanForm.cs b/TelegramBotBase/Form/AutoCleanForm.cs
new file mode 100644
index 0000000..22caa82
--- /dev/null
+++ b/TelegramBotBase/Form/AutoCleanForm.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using TelegramBotBase.Base;
+
+namespace TelegramBotBase.Form
+{
+ public class AutoCleanForm : FormBase
+ {
+ List OldMessages { get; set; }
+
+ public eDeleteMode DeleteMode { get; set; }
+
+ public enum eDeleteMode
+ {
+ OnEveryCall = 0,
+ OnLeavingForm = 1
+ }
+
+ public AutoCleanForm()
+ {
+ this.OldMessages = new List();
+ this.DeleteMode = eDeleteMode.OnEveryCall;
+
+ }
+
+ public override async Task Init(params object[] args)
+ {
+ if (this.Device == null)
+ return;
+
+ this.Device.MessageSent += Device_MessageSent;
+ }
+
+ private void Device_MessageSent(object sender, MessageSentEventArgs e)
+ {
+ this.OldMessages.Add(e.Message);
+ }
+
+ public override async Task PreLoad(MessageResult message)
+ {
+ if (this.DeleteMode != eDeleteMode.OnEveryCall)
+ return;
+
+ while (this.OldMessages.Count > 0)
+ {
+ if (!await this.Device.DeleteMessage(this.OldMessages[0].MessageId))
+ {
+ //Nachricht konnte nicht gelöscht werden, vermutlich existiert diese nicht mehr
+ if (this.OldMessages.Count > 0)
+ this.OldMessages.RemoveAt(0);
+ }
+ }
+ }
+
+ ///
+ /// Fügt eine Nachricht zu der Liste der löschenden hinzu.
+ ///
+ ///
+ public void AddMessage(Message m)
+ {
+ this.OldMessages.Add(m);
+ }
+
+ ///
+ /// Behält die Nachricht mit der angegebenen Id.
+ ///
+ ///
+ public void LeaveMessage(int Id)
+ {
+ var m = this.OldMessages.FirstOrDefault(a => a.MessageId == Id);
+ if (m == null)
+ return;
+
+ this.OldMessages.Remove(m);
+ }
+
+ ///
+ /// Behält die zuletzt gesendete Nachricht.
+ ///
+ public void LeaveLastMessage()
+ {
+ if (this.OldMessages.Count == 0)
+ return;
+
+ this.OldMessages.RemoveAt(this.OldMessages.Count - 1);
+ }
+
+ public async override Task Closed()
+ {
+ if (this.DeleteMode != eDeleteMode.OnLeavingForm)
+ return;
+
+ foreach (var m in this.OldMessages)
+ {
+ await this.Device.DeleteMessage(m.MessageId);
+ }
+ }
+ }
+}
diff --git a/TelegramBotBase/Form/ButtonBase.cs b/TelegramBotBase/Form/ButtonBase.cs
new file mode 100644
index 0000000..ac9e34d
--- /dev/null
+++ b/TelegramBotBase/Form/ButtonBase.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TelegramBotBase.Form
+{
+ public class ButtonBase
+ {
+ public String Text { get; set; }
+
+ public String Value { get; set; }
+
+ public ButtonBase()
+ {
+
+ }
+
+ public ButtonBase(String Text, String Value)
+ {
+ this.Text = Text;
+ this.Value = Value;
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Form/ButtonForm.cs b/TelegramBotBase/Form/ButtonForm.cs
new file mode 100644
index 0000000..28ab687
--- /dev/null
+++ b/TelegramBotBase/Form/ButtonForm.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types.InlineKeyboardButtons;
+using Telegram.Bot.Types.ReplyMarkups;
+
+namespace TelegramBotBase.Form
+{
+ public class ButtonForm
+ {
+ List> Buttons = new List>();
+
+ public ButtonForm()
+ {
+
+ }
+
+ public void AddButtonRow(List row)
+ {
+ Buttons.Add(row);
+ }
+
+ public void AddButtonRow(params ButtonBase[] row)
+ {
+ AddButtonRow(row.ToList());
+ }
+
+ public static T[][] SplitTo(IEnumerable items, int itemsPerRow = 2)
+ {
+ T[][] splitted = default(T[][]);
+
+ try
+ {
+ var t = items.Select((a, index) => new { a, index })
+ .GroupBy(a => a.index / itemsPerRow)
+ .Select(a => a.Select(b => b.a).ToArray()).ToArray();
+
+ splitted = t;
+ }
+ catch
+ {
+
+ }
+
+ return splitted;
+ }
+
+ ///
+ /// Fügt die Buttons automatisch aufgesplittet in Spalten ein.
+ ///
+ ///
+ ///
+ public void AddSplitted(IEnumerable buttons, int buttonsPerRow = 2)
+ {
+ var sp = SplitTo(buttons, buttonsPerRow);
+
+ foreach(var bl in sp)
+ {
+ AddButtonRow(bl);
+ }
+ }
+
+ public InlineKeyboardButton[][] ToArray()
+ {
+ var ikb = this.Buttons.Select(a => a.Select(b => InlineKeyboardButton.WithCallbackData(b.Text, b.Value)).ToArray()).ToArray();
+
+ return ikb;
+ }
+
+ public static implicit operator InlineKeyboardMarkup(ButtonForm form)
+ {
+ InlineKeyboardMarkup ikm = new InlineKeyboardMarkup();
+
+ ikm.InlineKeyboard = form.ToArray();
+
+ return ikm;
+ }
+ }
+}
diff --git a/TelegramBotBase/Form/CallbackData.cs b/TelegramBotBase/Form/CallbackData.cs
new file mode 100644
index 0000000..8f31a11
--- /dev/null
+++ b/TelegramBotBase/Form/CallbackData.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TelegramBotBase.Form
+{
+ public class CallbackData
+ {
+ public String Method { get; set; }
+
+ public String Value { get; set; }
+
+
+ public CallbackData()
+ {
+
+ }
+
+ public CallbackData(String method, String value)
+ {
+ this.Method = method;
+ this.Value = value;
+ }
+
+ public static String Create(String method, String value)
+ {
+ return new CallbackData(method, value).Serialize();
+ }
+
+ public String Serialize()
+ {
+ String s = "";
+ try
+ {
+
+ s = Newtonsoft.Json.JsonConvert.SerializeObject(this);
+ }
+ catch
+ {
+
+
+ }
+ return s;
+ }
+
+ public static CallbackData Deserialize(String data)
+ {
+ CallbackData cd = null;
+ try
+ {
+ cd = Newtonsoft.Json.JsonConvert.DeserializeObject(data);
+
+ return cd;
+ }
+ catch
+ {
+
+ }
+
+ return null;
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Form/FormBase.cs b/TelegramBotBase/Form/FormBase.cs
new file mode 100644
index 0000000..c7103a9
--- /dev/null
+++ b/TelegramBotBase/Form/FormBase.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Base;
+using TelegramBotBase.Sessions;
+
+namespace TelegramBotBase.Form
+{
+ public class FormBase : IDisposable
+ {
+ public DeviceSession Device { get; set; }
+
+ public MessageClient Client { get; set; }
+
+ public bool CustomEventManagement { get; set; } = false;
+
+ ///
+ /// Gibt an, dass das Formular gewechselt wurde, es werden keine weiteren Events ausgeführt
+ ///
+ public bool FormSwitched { get; set; } = false;
+
+ public FormBase()
+ {
+
+ }
+
+ public FormBase(MessageClient Client)
+ {
+ this.Client = Client;
+ }
+
+ ///
+ /// Wird nur aufgerufen, beim erstmaligen Laden des Formulares.
+ ///
+ public virtual async Task Init(params object[] args)
+ {
+
+ }
+
+ public virtual async Task Opened()
+ {
+
+ }
+
+ public virtual async Task Closed()
+ {
+
+ }
+
+ public virtual async Task PreLoad(MessageResult message)
+ {
+
+ }
+
+ public virtual async Task Load(MessageResult message)
+ {
+
+ }
+
+ public virtual async Task Action(MessageResult message)
+ {
+
+ }
+
+
+ public virtual async Task Render(MessageResult message)
+ {
+
+ }
+
+ /////
+ ///// Navigiert zur neuen Form.
+ /////
+ /////
+ /////
+ //public async Task NavigateTo(FormBase newForm)
+ //{
+ // DeviceSession ds = this.Device;
+ // if (ds == null)
+ // return;
+
+ // this.FormSwitched = true;
+
+ // ds.ActiveForm = newForm;
+ // newForm.Client = this.Client;
+ // newForm.Device = ds;
+
+ // await this.Closed();
+
+ // await newForm.Opened();
+ //}
+
+ ///
+ /// Navigiert zur neuen Form.
+ ///
+ ///
+ ///
+ public async Task NavigateTo(FormBase newForm, params object[] args)
+ {
+ DeviceSession ds = this.Device;
+ if (ds == null)
+ return;
+
+ this.FormSwitched = true;
+
+ ds.ActiveForm = newForm;
+ newForm.Client = this.Client;
+ newForm.Device = ds;
+
+ await newForm.Init(args);
+
+ await this.Closed();
+
+ await newForm.Opened();
+ }
+
+ public void Dispose()
+ {
+ this.Client = null;
+ this.Device = null;
+ this.FormSwitched = false;
+ }
+ }
+}
diff --git a/TelegramBotBase/Form/PromptDialog.cs b/TelegramBotBase/Form/PromptDialog.cs
new file mode 100644
index 0000000..1ea9df4
--- /dev/null
+++ b/TelegramBotBase/Form/PromptDialog.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Base;
+
+namespace TelegramBotBase.Form
+{
+ public class PromptDialog : FormBase
+ {
+ public String Message { get; set; }
+
+
+ public List Buttons { get; set; }
+
+ public Dictionary ButtonForms { get; set; } = new Dictionary();
+
+ private EventHandlerList __Events { get; set; } = new EventHandlerList();
+
+ private static object __evButtonClicked { get; } = new object();
+
+ public PromptDialog()
+ {
+
+ }
+
+ public PromptDialog(String Message)
+ {
+ this.Message = Message;
+ this.Buttons = new List();
+ }
+
+ public PromptDialog(String Message, params ButtonBase[] Buttons)
+ {
+ this.Message = Message;
+ this.Buttons = Buttons.ToList();
+ }
+
+ public override async Task Action(MessageResult message)
+ {
+ var call = message.GetData();
+ if (call == null)
+ return;
+
+ message.Handled = true;
+
+ await message.ConfirmAction();
+
+ await message.DeleteMessage();
+
+
+ ButtonBase button = this.Buttons.FirstOrDefault(a => a.Value == call.Value);
+
+ if (button == null)
+ {
+ return;
+ }
+
+ OnButtonClicked(new ButtonClickedEventArgs(button));
+
+ FormBase fb = ButtonForms.ContainsKey(call.Value) ? ButtonForms[call.Value] : null;
+
+ if (fb != null)
+ {
+ await this.NavigateTo(fb);
+ }
+ }
+
+
+ public override async Task Render(MessageResult message)
+ {
+ ButtonForm btn = new ButtonForm();
+
+
+ var buttons = this.Buttons.Select(a => new ButtonBase(a.Text, CallbackData.Create("action", a.Value))).ToList();
+ btn.AddButtonRow(buttons);
+
+ await this.Device.Send(this.Message, btn);
+ }
+
+
+ public event EventHandler ButtonClicked
+ {
+ add
+ {
+ this.__Events.AddHandler(__evButtonClicked, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evButtonClicked, value);
+ }
+ }
+
+ public void OnButtonClicked(ButtonClickedEventArgs e)
+ {
+ (this.__Events[__evButtonClicked] as EventHandler)?.Invoke(this, e);
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Properties/AssemblyInfo.cs b/TelegramBotBase/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..3ef8564
--- /dev/null
+++ b/TelegramBotBase/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("TelegramBotBase")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TelegramBotBase")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
+// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("a61eda27-cfdf-4bcb-b2d6-184f94904f2d")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/TelegramBotBase/SessionBase.cs b/TelegramBotBase/SessionBase.cs
new file mode 100644
index 0000000..482aa32
--- /dev/null
+++ b/TelegramBotBase/SessionBase.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Base;
+using TelegramBotBase.Form;
+using TelegramBotBase.Sessions;
+namespace TelegramBotBase
+{
+ public class SessionBase
+ {
+ public MessageClient Client { get; set; }
+
+ public Dictionary SessionList { get; set; }
+
+
+ public SessionBase()
+ {
+ this.SessionList = new Dictionary();
+ }
+
+ public DeviceSession this[long key]
+ {
+ get
+ {
+ return this.SessionList[key];
+ }
+ set
+ {
+ this.SessionList[key] = value;
+ }
+ }
+
+ public DeviceSession GetSession(long deviceId)
+ {
+ DeviceSession ds = this.SessionList.FirstOrDefault(a => a.Key == deviceId).Value ?? null;
+ return ds;
+ }
+
+ public async Task StartSession(long deviceId)
+ where T : FormBase
+ {
+ T start = typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { }) as T;
+
+ start.Client = this.Client;
+
+ DeviceSession ds = new Sessions.DeviceSession(deviceId, start);
+
+ start.Device = ds;
+ await start.Init();
+
+ await start.Opened();
+
+ this[deviceId] = ds;
+ return ds;
+ }
+
+
+ public void EndSession(long deviceId)
+ {
+ var d = this[deviceId];
+ if (d != null)
+ {
+ this.SessionList.Remove(deviceId);
+
+ }
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Sessions/DeviceSession.cs b/TelegramBotBase/Sessions/DeviceSession.cs
new file mode 100644
index 0000000..d79cbff
--- /dev/null
+++ b/TelegramBotBase/Sessions/DeviceSession.cs
@@ -0,0 +1,270 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+using Telegram.Bot.Types.ReplyMarkups;
+using TelegramBotBase.Base;
+using TelegramBotBase.Form;
+
+namespace TelegramBotBase.Sessions
+{
+ public class DeviceSession
+ {
+ public long DeviceId { get; set; }
+
+ public DateTime LastAction { get; set; }
+
+ public FormBase ActiveForm { get; set; }
+
+ public int LastMessage { get; set; }
+
+ private MessageClient Client
+ {
+ get
+ {
+ return this.ActiveForm.Client;
+ }
+ }
+
+ public EventHandlerList __Events = new EventHandlerList();
+
+ private static object __evMessageSent = new object();
+
+ public DeviceSession()
+ {
+ this.LastMessage = 0;
+ }
+
+ public DeviceSession(long DeviceId)
+ {
+ this.DeviceId = DeviceId;
+ }
+
+ public DeviceSession(long DeviceId, FormBase StartForm)
+ {
+ this.DeviceId = DeviceId;
+ this.ActiveForm = StartForm;
+ this.ActiveForm.Device = this;
+ }
+
+ ///
+ /// Bearbeitet die bestehende Text-Nachricht.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task Edit(int messageId, String text, ButtonForm buttons = null)
+ {
+ if (this.ActiveForm == null)
+ return;
+
+ InlineKeyboardMarkup markup = null;
+ if (buttons != null)
+ {
+ markup = buttons;
+ }
+
+ var message = await this.Client.TelegramClient.EditMessageTextAsync(this.DeviceId, messageId, text, replyMarkup: markup);
+
+ }
+
+ ///
+ /// Sendet eine einfache Text-Nachricht.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task Send(String text, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
+ {
+ if (this.ActiveForm == null)
+ return;
+
+ InlineKeyboardMarkup markup = null;
+ if (buttons != null)
+ {
+ markup = buttons;
+ }
+
+ var message = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
+
+ OnMessageSent(new MessageSentEventArgs(message.MessageId, message));
+ }
+
+ ///
+ /// Sendet eine einfache Text-Nachricht.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task Send(String text, InlineKeyboardMarkup markup , int replyTo = 0, bool disableNotification = false)
+ {
+ if (this.ActiveForm == null)
+ return;
+
+ var message = await (this.Client.TelegramClient.SendTextMessageAsync(this.DeviceId, text, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification));
+
+ OnMessageSent(new MessageSentEventArgs(message.MessageId, message));
+ }
+
+ ///
+ /// Sendet ein Bild
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendPhoto(FileToSend file, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
+ {
+ if (this.ActiveForm == null)
+ return;
+
+ InlineKeyboardMarkup markup = null;
+ if (buttons != null)
+ {
+ markup = buttons;
+ }
+
+ var message = await this.Client.TelegramClient.SendPhotoAsync(this.DeviceId, file, replyToMessageId: replyTo, replyMarkup: markup, disableNotification: disableNotification);
+
+ OnMessageSent(new MessageSentEventArgs(message.MessageId, message));
+ }
+
+ ///
+ /// Sendet ein Bild
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendPhoto(Image image, String name, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
+ {
+ using (var fileStream = Tools.Images.ToStream(image, ImageFormat.Png))
+ {
+ var fts = new FileToSend(name, fileStream);
+
+ await SendPhoto(fts, buttons, replyTo, disableNotification);
+ }
+ }
+
+ ///
+ /// Sendet ein Bild
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendPhoto(Bitmap image, String name, ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
+ {
+ using (var fileStream = Tools.Images.ToStream(image, ImageFormat.Png))
+ {
+ var fts = new FileToSend(name, fileStream);
+
+ await SendPhoto(fts, buttons, replyTo, disableNotification);
+ }
+ }
+
+ ///
+ /// Sendet ein Dokument
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendDocument(String filename, byte[] document, String caption = "", ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
+ {
+ MemoryStream ms = new MemoryStream(document);
+
+ FileToSend fts = new FileToSend(filename, ms);
+
+ await SendDocument(fts, caption, buttons, replyTo, disableNotification);
+ }
+
+ ///
+ /// Sendet ein Dokument
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendDocument(FileToSend document, String caption = "", ButtonForm buttons = null, int replyTo = 0, bool disableNotification = false)
+ {
+ InlineKeyboardMarkup markup = null;
+ if (buttons != null)
+ {
+ markup = buttons;
+ }
+
+ var message = await this.Client.TelegramClient.SendDocumentAsync(this.DeviceId, document, caption, replyMarkup: markup, disableNotification: disableNotification, replyToMessageId: replyTo);
+
+ OnMessageSent(new MessageSentEventArgs(message.MessageId, message));
+ }
+
+ ///
+ /// Legt eine Chat Aktion Fest (Wird angezeigt)
+ ///
+ ///
+ ///
+ public async Task SetAction(ChatAction action)
+ {
+ await this.Client.TelegramClient.SendChatActionAsync(this.DeviceId, action);
+ }
+
+ ///
+ /// Löscht die aktuelle Nachricht, oder die übergebene
+ ///
+ ///
+ ///
+ public virtual async Task DeleteMessage(int messageId = -1)
+ {
+ try
+ {
+ await this.Client.TelegramClient.DeleteMessageAsync(this.DeviceId, messageId);
+
+ return true;
+ }
+ catch
+ {
+
+ }
+
+ return false;
+ }
+
+
+ public event EventHandler MessageSent
+ {
+ add
+ {
+ this.__Events.AddHandler(__evMessageSent, value);
+ }
+ remove
+ {
+ this.__Events.RemoveHandler(__evMessageSent, value);
+ }
+ }
+
+
+ public void OnMessageSent(MessageSentEventArgs e)
+ {
+ (this.__Events[__evMessageSent] as EventHandler)?.Invoke(this, e);
+ }
+
+ }
+}
diff --git a/TelegramBotBase/TelegramBotBase.csproj b/TelegramBotBase/TelegramBotBase.csproj
new file mode 100644
index 0000000..bc0acc8
--- /dev/null
+++ b/TelegramBotBase/TelegramBotBase.csproj
@@ -0,0 +1,96 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {A61EDA27-CFDF-4BCB-B2D6-184F94904F2D}
+ Library
+ Properties
+ TelegramBotBase
+ TelegramBotBase
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+
+
+
+
+
+
+ ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll
+ True
+
+
+
+
+
+
+
+
+ ..\packages\Telegram.Bot.13.2.1\lib\netstandard1.1\Telegram.Bot.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TelegramBotBase/Tests/TestForm.cs b/TelegramBotBase/Tests/TestForm.cs
new file mode 100644
index 0000000..8c12aa4
--- /dev/null
+++ b/TelegramBotBase/Tests/TestForm.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using TelegramBotBase.Base;
+using TelegramBotBase.Form;
+
+namespace TelegramBotBase.Tests
+{
+ public class TestForm : FormBase
+ {
+
+
+ String LastMessage { get; set; }
+
+ public override async Task Init(params object[] param)
+ {
+
+ }
+
+ public override async Task Opened()
+ {
+ await this.Device.Send("Willkommen in Formular 1");
+ }
+
+ public override async Task Closed()
+ {
+ await this.Device.Send("Tschüss in Formular 1");
+ }
+
+ public override async Task Load(MessageResult message)
+ {
+
+
+ }
+
+
+ public override async Task Action(MessageResult message)
+ {
+ switch (message.Command)
+ {
+ case "reply":
+
+
+
+ break;
+
+ case "navigate":
+
+ var tf = new TestForm2();
+
+ await tf.Init();
+
+ await this.NavigateTo(tf);
+
+ break;
+
+ default:
+
+ this.LastMessage = message.RawMessageData.Message.Text;
+
+ break;
+ }
+
+
+ }
+
+
+ public override async Task Render(MessageResult message)
+ {
+ if (message.Command == "reply")
+ {
+
+ await this.Device.Send("Letzte Nachricht: " + this.LastMessage);
+
+ }
+
+ }
+
+ }
+}
diff --git a/TelegramBotBase/Tests/TestForm2.cs b/TelegramBotBase/Tests/TestForm2.cs
new file mode 100644
index 0000000..c412f20
--- /dev/null
+++ b/TelegramBotBase/Tests/TestForm2.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.InlineKeyboardButtons;
+using Telegram.Bot.Types.ReplyMarkups;
+using TelegramBotBase.Base;
+using TelegramBotBase.Form;
+
+namespace TelegramBotBase.Tests
+{
+ public class TestForm2 : FormBase
+ {
+
+ public override async Task Init(params object[] param)
+ {
+
+ }
+
+ public override async Task Opened()
+ {
+ await this.Device.Send("Willkommen in Formular 2");
+ }
+
+ public override async Task Closed()
+ {
+ await this.Device.Send("Tschüss in Formular 2");
+ }
+
+ public override async Task Load(MessageResult message)
+ {
+
+ }
+
+ public override async Task Action(MessageResult message)
+ {
+ var call = message.GetData();
+
+ await message.ConfirmAction();
+
+ await message.DeleteMessage();
+
+ if (call.Value == "testform1")
+ {
+
+ var tf = new TestForm();
+
+ await tf.Init();
+
+ await this.NavigateTo(tf);
+ }
+ else if (call.Value == "alert")
+ {
+ var fto = new TestForm2();
+ await fto.Init();
+
+ AlertDialog ad = new AlertDialog("Dies ist eine Meldung !", "Ok", fto);
+
+
+ await this.NavigateTo(ad);
+ }
+ else if (call.Value == "prompt")
+ {
+ PromptDialog pd = new PromptDialog("Bitte bestätigen !", new ButtonBase("Ok", "ok"), new ButtonBase("Abbrechen", "cancel"));
+
+ var tf = new TestForm2();
+
+ await tf.Init();
+
+ pd.ButtonForms.Add("ok", tf);
+ pd.ButtonForms.Add("cancel", tf);
+
+ await this.NavigateTo(pd);
+ }
+
+
+ }
+
+ public override async Task Render(MessageResult message)
+ {
+
+ Bitmap bmp = new Bitmap(800, 600);
+ using (Graphics g = Graphics.FromImage(bmp))
+ {
+
+ g.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height);
+
+ g.DrawString("Testbild", new Font("Arial", 24, FontStyle.Bold, GraphicsUnit.Pixel), Brushes.Black, new PointF(50, 50));
+
+ }
+
+ await this.Device.SetAction(Telegram.Bot.Types.Enums.ChatAction.UploadPhoto);
+
+ ButtonForm btn = new ButtonForm();
+
+ btn.AddButtonRow(new ButtonBase("Zum Testformular 1", CallbackData.Create("navigate", "testform1")), new ButtonBase("Zum Testformular 1", CallbackData.Create("navigate", "testform1")));
+
+ btn.AddButtonRow(new ButtonBase("Info Dialog", CallbackData.Create("navigate", "alert")), new ButtonBase("Bestätigungs Dialog", CallbackData.Create("navigate", "prompt")));
+
+
+ await this.Device.SendPhoto(bmp, "Test", btn);
+
+ }
+
+
+ }
+}
diff --git a/TelegramBotBase/Tools/Images.cs b/TelegramBotBase/Tools/Images.cs
new file mode 100644
index 0000000..e941884
--- /dev/null
+++ b/TelegramBotBase/Tools/Images.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TelegramBotBase.Tools
+{
+ public static class Images
+ {
+ public static Stream ToStream(this Image image, ImageFormat format)
+ {
+ var stream = new System.IO.MemoryStream();
+ image.Save(stream, format);
+ stream.Position = 0;
+ return stream;
+ }
+ }
+}
diff --git a/TelegramBotBase/packages.config b/TelegramBotBase/packages.config
new file mode 100644
index 0000000..a0682e2
--- /dev/null
+++ b/TelegramBotBase/packages.config
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file