using SoUnBot.AccessControl; using SoUnBot.ModuleLoader; 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.ReplyMarkups; namespace SoUnBot.Telegram { internal class TelegramBot { private AccessManager _accessManager; private string _moth_path; private Dictionary _modules; public TelegramBotClient BotClient { get; private set; } private Dictionary _usersContext; public TelegramBot(string token, AccessManager accessManager, string motd_path, Dictionary modules) { _accessManager = accessManager; _moth_path = motd_path; _modules = modules; _usersContext = new Dictionary(); BotClient = new TelegramBotClient(token); using var cts = new CancellationTokenSource(); // StartReceiving does not block the caller thread. Receiving is done on the ThreadPool. var receiverOptions = new ReceiverOptions { AllowedUpdates = { } // receive all update types }; BotClient.StartReceiving( HandleUpdateAsync, HandleErrorAsync, receiverOptions, cancellationToken: cts.Token); GetMe(); } private async void GetMe() { var me = await BotClient.GetMeAsync(); Console.WriteLine($"Start listening for @{me.Username}"); } async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) { try { long chatId; if (update.Type == UpdateType.CallbackQuery) { chatId = update.CallbackQuery.From.Id; if (update.CallbackQuery.Message.Text.StartsWith("ACM: ") && update.CallbackQuery.Data.Contains("Grant")) { long uid = int.Parse(update.CallbackQuery.Message.Text.Substring(5).Split('\n')[0]); string perm = update.CallbackQuery.Message.Text.Split("Ha richiesto l'accesso a: ")[1]; _accessManager.GrantPermission(uid, perm); await botClient.AnswerCallbackQueryAsync( update.CallbackQuery.Id, "Successo!" ); await botClient.SendTextMessageAsync( uid, "✅ Congratulazioni! Hai ottenuto l'accesso a: " + perm ); return; } if (update.CallbackQuery.Message.Text.StartsWith("ACM") && update.CallbackQuery.Data.Contains("🔆 Richiedi accesso")) { string perm = update.CallbackQuery.Message.Text.Split('`')[1]; _accessManager.AskPermission(update.CallbackQuery.From, perm, botClient); await botClient.AnswerCallbackQueryAsync( update.CallbackQuery.Id, "Richiesta effettuata" ); await botClient.EditMessageTextAsync( update.CallbackQuery.From.Id, update.CallbackQuery.Message.MessageId, update.CallbackQuery.Message.Text, replyMarkup: new InlineKeyboardMarkup(InlineKeyboardButton.WithCallbackData("Richiesto 〽️")) ); return; } if (update.CallbackQuery.Message.Text.StartsWith("ACM")) { return; } } if (update.Type != UpdateType.Message) // this is temp return; if (update.Message!.Type != MessageType.Text) return; chatId = update.Message.Chat.Id; if (update.Type == UpdateType.Message && update.Message!.Type == MessageType.Text && update.Message.Text.StartsWith("/spam")) { if (!_accessManager.CheckPermission(update.Message.From, "global.spam", botClient)) return; await botClient.SendTextMessageAsync( chatId: chatId, text: "Invio annuncio in corso..."); new Thread(() => { Thread.CurrentThread.IsBackground = true; SendToEveryone(botClient, chatId, update.Message.Text.Substring(6)); }).Start(); return; } if (update.Type == UpdateType.Message && update.Message!.Type == MessageType.Text && update.Message.Text == "/leave") { _usersContext.Remove(chatId); } if (_usersContext.ContainsKey(chatId)) { _usersContext[chatId].ProcessUpdate(botClient, update, cancellationToken); return; } if (update.Type == UpdateType.Message && update.Message!.Type == MessageType.Text) { var msg = update.Message.Text.StartsWith("/") ? update.Message.Text.Substring(1) : update.Message.Text; if (_modules.ContainsKey(msg)) { _usersContext.Add(chatId, _modules[msg]); _modules[msg].ProcessUpdate(botClient, update, cancellationToken); return; } } string validModules = _modules.Keys.Select(i => "/" + i).Aggregate((a, b) => a + "\n" + b); var motd = System.IO.File.ReadAllText(_moth_path); // Echo received message text Message sentMessage = await botClient.SendTextMessageAsync( chatId: chatId, text: motd); } catch(Exception e) { Console.WriteLine("Error handling the update: " + e.Message); } } async Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken) { if (exception is ApiRequestException apiRequestException) { await botClient.SendTextMessageAsync(_accessManager.AdminId, apiRequestException.ToString()); } // Restart the bot (otherwise it would become an amoeba) using var cts = new CancellationTokenSource(); var receiverOptions = new ReceiverOptions { AllowedUpdates = { } }; BotClient.StartReceiving( HandleUpdateAsync, HandleErrorAsync, receiverOptions, cancellationToken: cts.Token); } private async void SendToEveryone(ITelegramBotClient botClient, long chatId, string text) { foreach (long user in _accessManager.Users()) { try { Console.WriteLine("Sto spammando a" + user.ToString()); await botClient.SendTextMessageAsync( chatId: user, text: text ); await Task.Delay(100); } catch { Console.WriteLine("Ho fallito"); } } await botClient.SendTextMessageAsync( chatId: chatId, text: "✅ Annunciato a tutti!"); } } }