|
@@ -1,12 +1,237 @@
|
|
|
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
|
|
|
{
|
|
|
- class Program
|
|
|
+ public static class Program
|
|
|
{
|
|
|
- static void Main(string[] args)
|
|
|
+ private static TelegramBotClient Bot;
|
|
|
+
|
|
|
+ public static async Task Main()
|
|
|
+ {
|
|
|
+ Bot = new TelegramBotClient("1729356281:AAG8D_hO9b2WIS19doTVrPiPW3q7GFwAX2w");
|
|
|
+
|
|
|
+ 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("Hello World!");
|
|
|
+ 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;
|
|
|
}
|
|
|
}
|
|
|
}
|