Selaa lähdekoodia

Mapping project structure

Tigran 4 vuotta sitten
vanhempi
commit
71ea69b77f

+ 4 - 0
MafiaTelegramBot.sln.DotSettings.user

@@ -0,0 +1,4 @@
+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=MafiaTelegramBot_002Fstrings/@EntryIndexedValue">True</s:Boolean>
+	
+	<s:Boolean x:Key="/Default/ResxEditorPersonal/Initialized/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>

+ 9 - 0
MafiaTelegramBot/AppSettings.cs

@@ -0,0 +1,9 @@
+namespace MafiaTelegramBot
+{
+    public static class AppSettings
+    {
+        //public static string Url { get; set; } = ""; //TODO use this if need html tg api to get message updates
+        public static string Name { get; set; } = ""; //TODO paste your bot name here if need using full commands like /start@mafiabot, if value "", triggers to all /start commands
+        public static string Token { get; set; } = ""; //TODO paste your bot token here
+    }
+}

+ 51 - 0
MafiaTelegramBot/Bot.cs

@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+using MafiaTelegramBot.Models.Commands;
+using MafiaTelegramBot.Models.Queries;
+using Telegram.Bot;
+
+namespace MafiaTelegramBot
+{
+    public static class Bot
+    {
+        private static TelegramBotClient _client;
+        private static List<Command> _commandsList;
+        private static List<Query> _queriesList;
+        
+        public static IReadOnlyList<Command> Commands => _commandsList.AsReadOnly();
+        public static IReadOnlyList<Query> Queries => _queriesList.AsReadOnly();
+
+        public static TelegramBotClient Get()
+        {
+            if (_client != null) return _client;
+
+            InitCommands();
+            InitQueries();
+
+            _client = new TelegramBotClient(AppSettings.Token);
+            //var hook = string.Format(AppSettings.Url, "api/message/update");
+            //await _client.SetWebhookAsync(hook);
+
+            return _client;
+        }
+
+        private static void InitCommands()
+        {
+            //TODO fill commands array
+            _commandsList = new List<Command>
+            {
+                new SendKeyboard()
+            };
+        }
+        
+        private static void InitQueries()
+        {
+            //TODO fill inline keyboard array
+            _queriesList = new List<Query>
+            {
+                new CreateGame(),
+                new ConnectGame(),
+                new ShowProfile()
+            };
+        }
+    }
+}

+ 8 - 4
MafiaTelegramBot/MafiaTelegramBot.csproj

@@ -12,17 +12,21 @@
     </ItemGroup>
 
     <ItemGroup>
-      <EmbeddedResource Update="appsettings.resx">
+      <Folder Include="Controllers" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <EmbeddedResource Update="strings.resx">
         <Generator>ResXFileCodeGenerator</Generator>
-        <LastGenOutput>appsettings.Designer.cs</LastGenOutput>
+        <LastGenOutput>strings.Designer.cs</LastGenOutput>
       </EmbeddedResource>
     </ItemGroup>
 
     <ItemGroup>
-      <Compile Update="appsettings.Designer.cs">
+      <Compile Update="strings.Designer.cs">
         <DesignTime>True</DesignTime>
         <AutoGen>True</AutoGen>
-        <DependentUpon>appsettings.resx</DependentUpon>
+        <DependentUpon>strings.resx</DependentUpon>
       </Compile>
     </ItemGroup>
 

+ 18 - 0
MafiaTelegramBot/MainClass.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Threading;
+using Telegram.Bot;
+using Telegram.Bot.Extensions.Polling;
+
+namespace MafiaTelegramBot
+{
+    public static class MainClass
+    {
+        public static void Main()
+        {
+            var cts = new CancellationTokenSource();
+            Bot.Get().StartReceiving(new DefaultUpdateHandler(MessageController.HandleUpdateAsync, MessageController.HandleErrorAsync), cts.Token);
+            Console.ReadLine();
+            cts.Cancel();
+        }
+    }
+}

+ 71 - 0
MafiaTelegramBot/MessageController.cs

@@ -0,0 +1,71 @@
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MafiaTelegramBot.Models.Commands;
+using MafiaTelegramBot.Models.Queries;
+using Telegram.Bot;
+using Telegram.Bot.Exceptions;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+
+namespace MafiaTelegramBot
+{
+    public static class MessageController //: ApiController
+    {
+        /*
+        [Route(@api/message/update)]
+        public async Task<OkResult> UpdateCommand([FromBody]UpdateCommand update)
+        {
+            var commands = Bot.Commands;
+            var message = update.Message;
+            var client = await Bot.Get();
+            
+            foreach(var command in commands)
+            {
+                if (command.Contains(message.Text)) command.Execute(message, client);
+                break;
+            }
+            
+            return Ok();
+        }
+        */
+        
+        public static async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
+        {
+            try
+            {
+                var handle = update.Type switch
+                {
+                    //TODO handle other update type if needed
+                    UpdateType.Message => Command.Update(update),
+                    UpdateType.CallbackQuery => Query.Update(update),
+                    _ => UnknownUpdateHandlerAsync(update)
+                };
+                await handle;
+            }
+            catch (Exception exception)
+            {
+                await HandleErrorAsync(botClient, exception, cancellationToken);
+            }
+        }
+        
+        private static Task UnknownUpdateHandlerAsync(Update update)
+        {
+            Console.WriteLine($"Unknown update type: {update.Type}");
+            return Task.CompletedTask;
+        }
+        
+        public static Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
+        {
+            var errorMessage = exception switch
+            {
+                ApiRequestException apiRequestException => $"Telegram API Error:\n[{apiRequestException.ErrorCode}]\n{apiRequestException.Message}",
+                _ => exception.ToString()
+            };
+
+            Console.WriteLine(errorMessage);
+            return Task.CompletedTask;
+        }
+    }
+}

+ 31 - 0
MafiaTelegramBot/Models/Commands/Command.cs

@@ -0,0 +1,31 @@
+using System.Linq;
+using System.Threading.Tasks;
+using Telegram.Bot;
+using Telegram.Bot.Types;
+
+namespace MafiaTelegramBot.Models.Commands
+{
+    public abstract class Command
+    {
+        protected abstract string Name { get; }
+
+        protected abstract Task Execute(long chatId, TelegramBotClient client);
+
+        private bool Contains(string command)
+        {
+            return command.Contains(Name) && command.Contains(AppSettings.Name);
+        }
+        
+        public static Task Update(Update update)
+        {
+            var commands = Bot.Commands;
+            var message = update.Message.Text;
+            var chatId = update.Message.Chat.Id;
+            var client = Bot.Get();
+
+            return (from command in commands
+                where command.Contains(message)
+                select command.Execute(chatId, client)).FirstOrDefault();
+        }
+    }
+}

+ 34 - 0
MafiaTelegramBot/Models/Commands/SendKeyboard.cs

@@ -0,0 +1,34 @@
+using System.Threading.Tasks;
+using Telegram.Bot;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.Enums;
+using Telegram.Bot.Types.ReplyMarkups;
+
+namespace MafiaTelegramBot.Models.Commands
+{
+    public class SendKeyboard : Command
+    {
+        protected override string Name => "/start";
+
+        protected override async Task<Message> Execute(long chatId, TelegramBotClient client)
+        {
+            await Bot.Get().SendChatActionAsync(chatId, ChatAction.Typing);
+            InlineKeyboardMarkup inlineKeyboard = new (new[]
+            {
+                new[]
+                {
+                    InlineKeyboardButton.WithCallbackData(strings.create_game, "create_game")
+                },
+                new[]
+                {
+                    InlineKeyboardButton.WithCallbackData(strings.connect_game, "connect_game")
+                },
+                new[]
+                {
+                    InlineKeyboardButton.WithCallbackData(strings.show_profile, "show_profile")
+                }
+            });
+            return await Bot.Get().SendTextMessageAsync(chatId, strings.start_message, replyMarkup: inlineKeyboard);
+        }
+    }
+}

+ 17 - 0
MafiaTelegramBot/Models/Queries/ConnectGame.cs

@@ -0,0 +1,17 @@
+using System.Threading.Tasks;
+using Telegram.Bot;
+using Telegram.Bot.Types;
+
+namespace MafiaTelegramBot.Models.Queries
+{
+    public class ConnectGame : Query
+    {
+        protected override string Name => "connect_game";
+        
+        protected override async Task<Message> Execute(long chatId, TelegramBotClient client)
+        {
+            return await Bot.Get().SendTextMessageAsync(chatId, strings.connect_game);
+            //TODO create new game logic
+        }
+    }
+}

+ 17 - 0
MafiaTelegramBot/Models/Queries/CreateGame.cs

@@ -0,0 +1,17 @@
+using System.Threading.Tasks;
+using Telegram.Bot;
+using Telegram.Bot.Types;
+
+namespace MafiaTelegramBot.Models.Queries
+{
+    public class CreateGame : Query
+    {
+        protected override string Name => "create_game";
+        
+        protected override async Task<Message> Execute(long chatId, TelegramBotClient client)
+        {
+            return await Bot.Get().SendTextMessageAsync(chatId, strings.create_game);
+            //TODO create new game logic
+        }
+    }
+}

+ 31 - 0
MafiaTelegramBot/Models/Queries/Query.cs

@@ -0,0 +1,31 @@
+using System.Linq;
+using System.Threading.Tasks;
+using Telegram.Bot;
+using Telegram.Bot.Types;
+
+namespace MafiaTelegramBot.Models.Queries
+{
+    public abstract class Query
+    {
+        protected abstract string Name { get; }
+
+        protected abstract Task Execute(long chatId, TelegramBotClient client);
+
+        private bool Contains(string command)
+        {
+            return command.Contains(Name);
+        }
+        
+        public static Task Update(Update update)
+        {
+            var queries = Bot.Queries;
+            var data = update.CallbackQuery.Data;
+            var chatId = update.CallbackQuery.Message.Chat.Id;
+            var client = Bot.Get();
+
+            return (from query in queries
+                where query.Contains(data)
+                select query.Execute(chatId, client)).FirstOrDefault();
+        }
+    }
+}

+ 17 - 0
MafiaTelegramBot/Models/Queries/ShowProfile.cs

@@ -0,0 +1,17 @@
+using System.Threading.Tasks;
+using Telegram.Bot;
+using Telegram.Bot.Types;
+
+namespace MafiaTelegramBot.Models.Queries
+{
+    public class ShowProfile : Query
+    {
+        protected override string Name => "show_profile";
+
+        protected override async Task<Message> Execute(long chatId, TelegramBotClient client)
+        {
+            return await Bot.Get().SendTextMessageAsync(chatId, strings.show_profile);
+            //TODO show user profile logic
+        }
+    }
+}

+ 0 - 238
MafiaTelegramBot/Program.cs

@@ -1,238 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Telegram.Bot;
-using Telegram.Bot.Exceptions;
-using Telegram.Bot.Extensions.Polling;
-using Telegram.Bot.Types;
-using Telegram.Bot.Types.Enums;
-using Telegram.Bot.Types.InlineQueryResults;
-using Telegram.Bot.Types.InputFiles;
-using Telegram.Bot.Types.ReplyMarkups;
-
-namespace MafiaTelegramBot
-{
-    public static class Program
-    {
-        private static TelegramBotClient Bot;
-
-        public static async Task Main()
-        {
-            var token = appsettings.ResourceManager.GetString("token");
-            Bot = new TelegramBotClient(token);
-
-            var me = await Bot.GetMeAsync();
-            Console.Title = me.Username;
-
-            var cts = new CancellationTokenSource();
-
-            // StartReceiving does not block the caller thread. Receiving is done on the ThreadPool.
-            Bot.StartReceiving(new DefaultUpdateHandler(HandleUpdateAsync, HandleErrorAsync),
-                               cts.Token);
-
-            Console.WriteLine($"Start listening for @{me.Username}");
-            Console.ReadLine();
-
-            // Send cancellation request to stop bot
-            cts.Cancel();
-        }
-
-        public static async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
-        {
-            var handler = update.Type switch
-            {
-                // UpdateType.Unknown:
-                // UpdateType.ChannelPost:
-                // UpdateType.EditedChannelPost:
-                // UpdateType.ShippingQuery:
-                // UpdateType.PreCheckoutQuery:
-                // UpdateType.Poll:
-                UpdateType.Message            => BotOnMessageReceived(update.Message),
-                UpdateType.EditedMessage      => BotOnMessageReceived(update.EditedMessage),
-                UpdateType.CallbackQuery      => BotOnCallbackQueryReceived(update.CallbackQuery),
-                UpdateType.InlineQuery        => BotOnInlineQueryReceived(update.InlineQuery),
-                UpdateType.ChosenInlineResult => BotOnChosenInlineResultReceived(update.ChosenInlineResult),
-                _                             => UnknownUpdateHandlerAsync(update)
-            };
-
-            try
-            {
-                await handler;
-            }
-            catch (Exception exception)
-            {
-                await HandleErrorAsync(botClient, exception, cancellationToken);
-            }
-        }
-
-        private static async Task BotOnMessageReceived(Message message)
-        {
-            Console.WriteLine($"Receive message type: {message.Type}");
-            if (message.Type != MessageType.Text)
-                return;
-
-            var action = (message.Text.Split(' ').First()) switch
-            {
-                "/inline"   => SendInlineKeyboard(message),
-                "/keyboard" => SendReplyKeyboard(message),
-                "/remove"   => RemoveKeyboard(message),
-                "/photo"    => SendFile(message),
-                "/request"  => RequestContactAndLocation(message),
-                _           => Usage(message)
-            };
-            var sentMessage = await action;
-            Console.WriteLine($"The message was sent with id: {sentMessage.MessageId}");
-
-
-            // Send inline keyboard
-            // You can process responses in BotOnCallbackQueryReceived handler
-            static async Task<Message> SendInlineKeyboard(Message message)
-            {
-                await Bot.SendChatActionAsync(message.Chat.Id, ChatAction.Typing);
-
-                // Simulate longer running task
-                await Task.Delay(500);
-
-                InlineKeyboardMarkup inlineKeyboard = new (new[]
-                {
-                    // first row
-                    new []
-                    {
-                        InlineKeyboardButton.WithCallbackData("1.1", "11"),
-                        InlineKeyboardButton.WithCallbackData("1.2", "12"),
-                    },
-                    // second row
-                    new []
-                    {
-                        InlineKeyboardButton.WithCallbackData("2.1", "21"),
-                        InlineKeyboardButton.WithCallbackData("2.2", "22"),
-                    },
-                });
-                return await Bot.SendTextMessageAsync(chatId: message.Chat.Id,
-                                                      text: "Choose",
-                                                      replyMarkup: inlineKeyboard);
-            }
-
-            static async Task<Message> SendReplyKeyboard(Message message)
-            {
-                ReplyKeyboardMarkup replyKeyboardMarkup = new (
-                    new KeyboardButton[][]
-                    {
-                        new KeyboardButton[] { "1.1", "1.2" },
-                        new KeyboardButton[] { "2.1", "2.2" },
-                    },
-                    resizeKeyboard: true
-                );
-
-                return await Bot.SendTextMessageAsync(chatId: message.Chat.Id,
-                                                      text: "Choose",
-                                                      replyMarkup: replyKeyboardMarkup);
-            }
-
-            static async Task<Message> RemoveKeyboard(Message message)
-            {
-                return await Bot.SendTextMessageAsync(chatId: message.Chat.Id,
-                                                      text: "Removing keyboard",
-                                                      replyMarkup: new ReplyKeyboardRemove());
-            }
-
-            static async Task<Message> SendFile(Message message)
-            {
-                await Bot.SendChatActionAsync(message.Chat.Id, ChatAction.UploadPhoto);
-
-                const string filePath = @"Files/tux.png";
-                using FileStream fileStream = new (filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
-                var fileName = filePath.Split(Path.DirectorySeparatorChar).Last();
-                return await Bot.SendPhotoAsync(chatId: message.Chat.Id,
-                                                photo: new InputOnlineFile(fileStream, fileName),
-                                                caption: "Nice Picture");
-            }
-
-            static async Task<Message> RequestContactAndLocation(Message message)
-            {
-                ReplyKeyboardMarkup RequestReplyKeyboard = new (new[]
-                {
-                    KeyboardButton.WithRequestLocation("Location"),
-                    KeyboardButton.WithRequestContact("Contact"),
-                });
-                return await Bot.SendTextMessageAsync(chatId: message.Chat.Id,
-                                                      text: "Who or Where are you?",
-                                                      replyMarkup: RequestReplyKeyboard);
-            }
-
-            static async Task<Message> Usage(Message message)
-            {
-                const string usage = "Usage:\n" +
-                                     "/inline   - send inline keyboard\n" +
-                                     "/keyboard - send custom keyboard\n" +
-                                     "/remove   - remove custom keyboard\n" +
-                                     "/photo    - send a photo\n" +
-                                     "/request  - request location or contact";
-                return await Bot.SendTextMessageAsync(chatId: message.Chat.Id,
-                                                      text: usage,
-                                                      replyMarkup: new ReplyKeyboardRemove());
-            }
-        }
-
-        // Process Inline Keyboard callback data
-        private static async Task BotOnCallbackQueryReceived(CallbackQuery callbackQuery)
-        {
-            await Bot.AnswerCallbackQueryAsync(callbackQuery.Id,
-                                               $"Received {callbackQuery.Data}");
-
-            await Bot.SendTextMessageAsync(callbackQuery.Message.Chat.Id,
-                                           $"Received {callbackQuery.Data}");
-        }
-
-        #region Inline Mode
-
-        private static async Task BotOnInlineQueryReceived(InlineQuery inlineQuery)
-        {
-            Console.WriteLine($"Received inline query from: {inlineQuery.From.Id}");
-
-            InlineQueryResultBase[] results = {
-                // displayed result
-                new InlineQueryResultArticle(
-                    id: "3",
-                    title: "TgBots",
-                    inputMessageContent: new InputTextMessageContent(
-                        "hello"
-                    )
-                )
-            };
-
-            await Bot.AnswerInlineQueryAsync(inlineQuery.Id,
-                                             results,
-                                             isPersonal: true,
-                                             cacheTime: 0);
-        }
-
-        private static Task BotOnChosenInlineResultReceived(ChosenInlineResult chosenInlineResult)
-        {
-            Console.WriteLine($"Received inline result: {chosenInlineResult.ResultId}");
-            return Task.CompletedTask;
-        }
-
-        #endregion
-
-        private static Task UnknownUpdateHandlerAsync(Update update)
-        {
-            Console.WriteLine($"Unknown update type: {update.Type}");
-            return Task.CompletedTask;
-        }
-
-        public static Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
-        {
-            var ErrorMessage = exception switch
-            {
-                ApiRequestException apiRequestException => $"Telegram API Error:\n[{apiRequestException.ErrorCode}]\n{apiRequestException.Message}",
-                _ => exception.ToString()
-            };
-
-            Console.WriteLine(ErrorMessage);
-            return Task.CompletedTask;
-        }
-    }
-}

+ 33 - 6
MafiaTelegramBot/appsettings.Designer.cs → MafiaTelegramBot/strings.Designer.cs

@@ -22,14 +22,14 @@ namespace MafiaTelegramBot {
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class appsettings {
+    internal class strings {
         
         private static global::System.Resources.ResourceManager resourceMan;
         
         private static global::System.Globalization.CultureInfo resourceCulture;
         
         [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal appsettings() {
+        internal strings() {
         }
         
         /// <summary>
@@ -39,7 +39,7 @@ namespace MafiaTelegramBot {
         internal static global::System.Resources.ResourceManager ResourceManager {
             get {
                 if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MafiaTelegramBot.appsettings", typeof(appsettings).Assembly);
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MafiaTelegramBot.strings", typeof(strings).Assembly);
                     resourceMan = temp;
                 }
                 return resourceMan;
@@ -61,11 +61,38 @@ namespace MafiaTelegramBot {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to //TODO place your token here.
+        ///   Looks up a localized string similar to Присоединиться к игре.
         /// </summary>
-        internal static string token {
+        internal static string connect_game {
             get {
-                return ResourceManager.GetString("token", resourceCulture);
+                return ResourceManager.GetString("connect_game", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Создать игру.
+        /// </summary>
+        internal static string create_game {
+            get {
+                return ResourceManager.GetString("create_game", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Показать профиль.
+        /// </summary>
+        internal static string show_profile {
+            get {
+                return ResourceManager.GetString("show_profile", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Что вы хотите сделать?.
+        /// </summary>
+        internal static string start_message {
+            get {
+                return ResourceManager.GetString("start_message", resourceCulture);
             }
         }
     }

+ 11 - 2
MafiaTelegramBot/appsettings.resx → MafiaTelegramBot/strings.resx

@@ -18,7 +18,16 @@
     <resheader name="writer">
         <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
     </resheader>
-    <data name="token" xml:space="preserve">
-        <value>//TODO place your token here</value>
+    <data name="create_game" xml:space="preserve">
+        <value>Создать игру</value>
+    </data>
+    <data name="connect_game" xml:space="preserve">
+        <value>Присоединиться к игре</value>
+    </data>
+    <data name="show_profile" xml:space="preserve">
+        <value>Показать профиль</value>
+    </data>
+    <data name="start_message" xml:space="preserve">
+        <value>Что вы хотите сделать?</value>
     </data>
 </root>