From dabaf50f3c9fa310d5cd2d0f00db834c16b74bf2 Mon Sep 17 00:00:00 2001 From: Wizou <11647984+wiz0u@users.noreply.github.com> Date: Fri, 5 Jul 2024 16:59:08 +0200 Subject: [PATCH] harmonize with Console.Advanced --- .editorconfig | 3 + .../Controllers/BotController.cs | 8 +-- Webhook.Controllers/Program.cs | 4 +- Webhook.Controllers/Services/UpdateHandler.cs | 61 ++++++++----------- 4 files changed, 36 insertions(+), 40 deletions(-) diff --git a/.editorconfig b/.editorconfig index 2e2aad9..de3692d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -28,6 +28,9 @@ indent_size = 2 # RCS1090: Call 'ConfigureAwait(false)'. dotnet_diagnostic.RCS1090.severity = none +# CA1848: Use the LoggerMessage delegates +dotnet_diagnostic.CA1848.severity = silent + [*.md] trim_trailing_whitespace = false indent_size = 2 diff --git a/Webhook.Controllers/Controllers/BotController.cs b/Webhook.Controllers/Controllers/BotController.cs index cd7b7b4..fbb5bca 100644 --- a/Webhook.Controllers/Controllers/BotController.cs +++ b/Webhook.Controllers/Controllers/BotController.cs @@ -11,7 +11,7 @@ namespace Webhook.Controllers.Controllers; public class BotController(IOptions Config) : ControllerBase { [HttpGet("setWebhook")] - public async Task SetWebHook([FromServices] TelegramBotClient bot, CancellationToken ct) + public async Task SetWebHook([FromServices] ITelegramBotClient bot, CancellationToken ct) { var webhookUrl = Config.Value.BotWebhookUrl.AbsoluteUri; await bot.SetWebhookAsync(webhookUrl, allowedUpdates: [], secretToken: Config.Value.SecretToken, cancellationToken: ct); @@ -19,17 +19,17 @@ public async Task SetWebHook([FromServices] TelegramBotClient bot, Cance } [HttpPost] - public async Task Post([FromBody] Update update, [FromServices] UpdateHandler handleUpdateService, CancellationToken ct) + public async Task Post([FromBody] Update update, [FromServices] ITelegramBotClient bot, [FromServices] UpdateHandler handleUpdateService, CancellationToken ct) { if (Request.Headers["X-Telegram-Bot-Api-Secret-Token"] != Config.Value.SecretToken) return Forbid(); try { - await handleUpdateService.HandleUpdateAsync(update, ct); + await handleUpdateService.HandleUpdateAsync(bot, update, ct); } catch (Exception exception) { - await handleUpdateService.HandleErrorAsync(exception, ct); + await handleUpdateService.HandleErrorAsync(bot, exception, Telegram.Bot.Polling.HandleErrorSource.HandleUpdateError, ct); } return Ok(); } diff --git a/Webhook.Controllers/Program.cs b/Webhook.Controllers/Program.cs index 9d23632..1ca87cd 100644 --- a/Webhook.Controllers/Program.cs +++ b/Webhook.Controllers/Program.cs @@ -6,9 +6,9 @@ // Setup bot configuration var botConfigSection = builder.Configuration.GetSection("BotConfiguration"); builder.Services.Configure(botConfigSection); -builder.Services.AddHttpClient("tgwebhook").RemoveAllLoggers().AddTypedClient( +builder.Services.AddHttpClient("tgwebhook").RemoveAllLoggers().AddTypedClient( httpClient => new TelegramBotClient(botConfigSection.Get()!.BotToken, httpClient)); -builder.Services.AddScoped(); +builder.Services.AddSingleton(); builder.Services.ConfigureTelegramBotMvc(); builder.Services.AddControllers(); diff --git a/Webhook.Controllers/Services/UpdateHandler.cs b/Webhook.Controllers/Services/UpdateHandler.cs index ff4791d..7d116f0 100644 --- a/Webhook.Controllers/Services/UpdateHandler.cs +++ b/Webhook.Controllers/Services/UpdateHandler.cs @@ -1,5 +1,6 @@ using Telegram.Bot; using Telegram.Bot.Exceptions; +using Telegram.Bot.Polling; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.InlineQueryResults; @@ -7,27 +8,19 @@ namespace Webhook.Controllers.Services; -public class UpdateHandler +public class UpdateHandler(ITelegramBotClient bot, ILogger logger) : IUpdateHandler { - private readonly TelegramBotClient _bot; - private readonly ILogger _logger; private static readonly InputPollOption[] PollOptions = ["Hello", "World!"]; - public UpdateHandler(TelegramBotClient bot, ILogger logger) + public async Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, HandleErrorSource source, CancellationToken cancellationToken) { - _bot = bot; - _logger = logger; - } - - public async Task HandleErrorAsync(Exception exception, CancellationToken cancellationToken) - { - _logger.LogInformation("HandleError: {exception}", exception); + logger.LogInformation("HandleError: {exception}", exception); // Cooldown in case of network connection error if (exception is RequestException) await Task.Delay(TimeSpan.FromSeconds(2)); } - public async Task HandleUpdateAsync(Update update, CancellationToken cancellationToken) + public async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await (update switch @@ -49,7 +42,7 @@ public async Task HandleUpdateAsync(Update update, CancellationToken cancellatio private async Task OnMessage(Message msg) { - _logger.LogInformation("Receive message type: {MessageType}", msg.Type); + logger.LogInformation("Receive message type: {MessageType}", msg.Type); if (msg.Text is not { } messageText) return; @@ -66,7 +59,7 @@ private async Task OnMessage(Message msg) "/throw" => FailingHandler(msg), _ => Usage(msg) }); - _logger.LogInformation("The message was sent with id: {SentMessageId}", sentMessage.MessageId); + logger.LogInformation("The message was sent with id: {SentMessageId}", sentMessage.MessageId); } async Task Usage(Message msg) @@ -83,15 +76,15 @@ async Task Usage(Message msg) /poll_anonymous - send an anonymous poll /throw - what happens if handler fails """; - return await _bot.SendTextMessageAsync(msg.Chat, usage, parseMode: ParseMode.Html, replyMarkup: new ReplyKeyboardRemove()); + return await bot.SendTextMessageAsync(msg.Chat, usage, parseMode: ParseMode.Html, replyMarkup: new ReplyKeyboardRemove()); } async Task SendPhoto(Message msg) { - await _bot.SendChatActionAsync(msg.Chat, ChatAction.UploadPhoto); + await bot.SendChatActionAsync(msg.Chat, ChatAction.UploadPhoto); await Task.Delay(2000); // simulate a long task await using var fileStream = new FileStream("Files/bot.gif", FileMode.Open, FileAccess.Read); - return await _bot.SendPhotoAsync(msg.Chat, fileStream, caption: "Read https://telegrambots.github.io/book/"); + return await bot.SendPhotoAsync(msg.Chat, fileStream, caption: "Read https://telegrambots.github.io/book/"); } // Send inline keyboard. You can process responses in OnCallbackQuery handler @@ -105,7 +98,7 @@ async Task SendInlineKeyboard(Message msg) InlineKeyboardButton.WithUrl("WithUrl", "https://github.com/TelegramBots/Telegram.Bot") ], ]; - return await _bot.SendTextMessageAsync(msg.Chat, "Inline buttons:", replyMarkup: new InlineKeyboardMarkup(buttons)); + return await bot.SendTextMessageAsync(msg.Chat, "Inline buttons:", replyMarkup: new InlineKeyboardMarkup(buttons)); } async Task SendReplyKeyboard(Message msg) @@ -115,12 +108,12 @@ async Task SendReplyKeyboard(Message msg) ["1.1", "1.2", "1.3"], ["2.1", "2.2"], ]; - return await _bot.SendTextMessageAsync(msg.Chat, "Keyboard buttons:", replyMarkup: new ReplyKeyboardMarkup(keys) { ResizeKeyboard = true }); + return await bot.SendTextMessageAsync(msg.Chat, "Keyboard buttons:", replyMarkup: new ReplyKeyboardMarkup(keys) { ResizeKeyboard = true }); } async Task RemoveKeyboard(Message msg) { - return await _bot.SendTextMessageAsync(msg.Chat, "Removing keyboard", replyMarkup: new ReplyKeyboardRemove()); + return await bot.SendTextMessageAsync(msg.Chat, "Removing keyboard", replyMarkup: new ReplyKeyboardRemove()); } async Task RequestContactAndLocation(Message msg) @@ -130,24 +123,24 @@ async Task RequestContactAndLocation(Message msg) KeyboardButton.WithRequestLocation("Location"), KeyboardButton.WithRequestContact("Contact"), ]; - return await _bot.SendTextMessageAsync(msg.Chat, "Who or Where are you?", replyMarkup: new ReplyKeyboardMarkup(buttons)); + return await bot.SendTextMessageAsync(msg.Chat, "Who or Where are you?", replyMarkup: new ReplyKeyboardMarkup(buttons)); } async Task StartInlineQuery(Message msg) { var button = InlineKeyboardButton.WithSwitchInlineQueryCurrentChat("Inline Mode"); - return await _bot.SendTextMessageAsync(msg.Chat, "Press the button to start Inline Query\n\n" + + return await bot.SendTextMessageAsync(msg.Chat, "Press the button to start Inline Query\n\n" + "(Make sure you enabled Inline Mode in @BotFather)", replyMarkup: new InlineKeyboardMarkup(button)); } async Task SendPoll(Message msg) { - return await _bot.SendPollAsync(msg.Chat, "Question", PollOptions, isAnonymous: false); + return await bot.SendPollAsync(msg.Chat, "Question", PollOptions, isAnonymous: false); } async Task SendAnonymousPoll(Message msg) { - return await _bot.SendPollAsync(chatId: msg.Chat, "Question", PollOptions); + return await bot.SendPollAsync(chatId: msg.Chat, "Question", PollOptions); } static Task FailingHandler(Message msg) @@ -158,35 +151,35 @@ static Task FailingHandler(Message msg) // Process Inline Keyboard callback data private async Task OnCallbackQuery(CallbackQuery callbackQuery) { - _logger.LogInformation("Received inline keyboard callback from: {CallbackQueryId}", callbackQuery.Id); - await _bot.AnswerCallbackQueryAsync(callbackQuery.Id, $"Received {callbackQuery.Data}"); - await _bot.SendTextMessageAsync(callbackQuery.Message!.Chat, $"Received {callbackQuery.Data}"); + logger.LogInformation("Received inline keyboard callback from: {CallbackQueryId}", callbackQuery.Id); + await bot.AnswerCallbackQueryAsync(callbackQuery.Id, $"Received {callbackQuery.Data}"); + await bot.SendTextMessageAsync(callbackQuery.Message!.Chat, $"Received {callbackQuery.Data}"); } #region Inline Mode private async Task OnInlineQuery(InlineQuery inlineQuery) { - _logger.LogInformation("Received inline query from: {InlineQueryFromId}", inlineQuery.From.Id); + logger.LogInformation("Received inline query from: {InlineQueryFromId}", inlineQuery.From.Id); InlineQueryResult[] results = [ // displayed result new InlineQueryResultArticle("1", "Telegram.Bot", new InputTextMessageContent("hello")), new InlineQueryResultArticle("2", "is the best", new InputTextMessageContent("world")) ]; - await _bot.AnswerInlineQueryAsync(inlineQuery.Id, results, cacheTime: 0, isPersonal: true); + await bot.AnswerInlineQueryAsync(inlineQuery.Id, results, cacheTime: 0, isPersonal: true); } private async Task OnChosenInlineResult(ChosenInlineResult chosenInlineResult) { - _logger.LogInformation("Received inline result: {ChosenInlineResultId}", chosenInlineResult.ResultId); - await _bot.SendTextMessageAsync(chosenInlineResult.From.Id, $"You chose result with Id: {chosenInlineResult.ResultId}"); + logger.LogInformation("Received inline result: {ChosenInlineResultId}", chosenInlineResult.ResultId); + await bot.SendTextMessageAsync(chosenInlineResult.From.Id, $"You chose result with Id: {chosenInlineResult.ResultId}"); } #endregion private Task OnPoll(Poll poll) { - _logger.LogInformation($"Received Pull info: {poll.Question}"); + logger.LogInformation($"Received Pull info: {poll.Question}"); return Task.CompletedTask; } @@ -194,12 +187,12 @@ private async Task OnPollAnswer(PollAnswer pollAnswer) { var answer = pollAnswer.OptionIds.FirstOrDefault(); var selectedOption = PollOptions[answer]; - await _bot.SendTextMessageAsync(pollAnswer.User.Id, $"You've chosen: {selectedOption.Text} in poll"); + await bot.SendTextMessageAsync(pollAnswer.User.Id, $"You've chosen: {selectedOption.Text} in poll"); } private Task UnknownUpdateHandlerAsync(Update update) { - _logger.LogInformation("Unknown update type: {UpdateType}", update.Type); + logger.LogInformation("Unknown update type: {UpdateType}", update.Type); return Task.CompletedTask; } }