so-un-bot/Bot/Telegram/TelegramBot.cs

200 lines
7.6 KiB
C#
Raw Normal View History

2024-01-19 19:06:53 +01:00
using SoUnBot.AccessControl;
using SoUnBot.ModuleLoader;
2024-01-19 03:29:39 +01:00
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;
2024-01-19 19:06:53 +01:00
namespace SoUnBot.Telegram
2024-01-19 03:29:39 +01:00
{
internal class TelegramBot
{
2024-01-19 19:06:53 +01:00
private AccessManager _accessManager;
2024-01-19 03:29:39 +01:00
private string _moth_path;
2024-01-31 04:56:23 +01:00
2024-01-19 03:29:39 +01:00
private Dictionary<string, IModule> _modules;
public TelegramBotClient BotClient { get; private set; }
private Dictionary<long, IModule> _usersContext;
2024-01-19 19:06:53 +01:00
public TelegramBot(string token, AccessManager accessManager, string motd_path, Dictionary<string, IModule> modules)
2024-01-19 03:29:39 +01:00
{
2024-01-19 19:06:53 +01:00
_accessManager = accessManager;
2024-01-19 03:29:39 +01:00
_moth_path = motd_path;
_modules = modules;
_usersContext = new Dictionary<long, IModule>();
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;
2024-01-19 03:29:39 +01:00
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];
2024-01-19 19:06:53 +01:00
_accessManager.GrantPermission(uid, perm);
2024-01-19 03:29:39 +01:00
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];
2024-01-19 19:06:53 +01:00
_accessManager.AskPermission(update.CallbackQuery.From, perm, botClient);
2024-01-19 03:29:39 +01:00
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"))
{
2024-01-19 19:06:53 +01:00
if (!_accessManager.CheckPermission(update.Message.From, "global.spam", botClient)) return;
2024-01-19 03:29:39 +01:00
await botClient.SendTextMessageAsync(
chatId: chatId,
text: "Invio annuncio in corso...");
2024-01-21 14:12:10 +01:00
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
SendToEveryone(botClient, chatId, update.Message.Text.Substring(6));
}).Start();
2024-01-19 03:29:39 +01:00
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);
}
2024-01-19 03:29:39 +01:00
}
async Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
2024-01-19 03:29:39 +01:00
{
if (exception is ApiRequestException apiRequestException)
2024-01-19 03:29:39 +01:00
{
await botClient.SendTextMessageAsync(_accessManager.AdminId, apiRequestException.ToString());
}
2024-01-19 03:29:39 +01:00
// 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);
2024-01-19 03:29:39 +01:00
}
2024-01-19 19:06:53 +01:00
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);
2024-01-19 19:06:53 +01:00
}
catch
{
Console.WriteLine("Ho fallito");
}
}
await botClient.SendTextMessageAsync(
chatId: chatId,
text: "✅ Annunciato a tutti!");
}
2024-01-19 03:29:39 +01:00
}
}