Skip to content

Commit

Permalink
harmonize with Console.Advanced
Browse files Browse the repository at this point in the history
  • Loading branch information
wiz0u committed Jul 5, 2024
1 parent 7da94ad commit dabaf50
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 40 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 4 additions & 4 deletions Webhook.Controllers/Controllers/BotController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@ namespace Webhook.Controllers.Controllers;
public class BotController(IOptions<BotConfiguration> Config) : ControllerBase
{
[HttpGet("setWebhook")]
public async Task<string> SetWebHook([FromServices] TelegramBotClient bot, CancellationToken ct)
public async Task<string> SetWebHook([FromServices] ITelegramBotClient bot, CancellationToken ct)
{
var webhookUrl = Config.Value.BotWebhookUrl.AbsoluteUri;
await bot.SetWebhookAsync(webhookUrl, allowedUpdates: [], secretToken: Config.Value.SecretToken, cancellationToken: ct);
return $"Webhook set to {webhookUrl}";
}

[HttpPost]
public async Task<IActionResult> Post([FromBody] Update update, [FromServices] UpdateHandler handleUpdateService, CancellationToken ct)
public async Task<IActionResult> 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();
}
Expand Down
4 changes: 2 additions & 2 deletions Webhook.Controllers/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// Setup bot configuration
var botConfigSection = builder.Configuration.GetSection("BotConfiguration");
builder.Services.Configure<BotConfiguration>(botConfigSection);
builder.Services.AddHttpClient("tgwebhook").RemoveAllLoggers().AddTypedClient(
builder.Services.AddHttpClient("tgwebhook").RemoveAllLoggers().AddTypedClient<ITelegramBotClient>(
httpClient => new TelegramBotClient(botConfigSection.Get<BotConfiguration>()!.BotToken, httpClient));
builder.Services.AddScoped<Webhook.Controllers.Services.UpdateHandler>();
builder.Services.AddSingleton<Webhook.Controllers.Services.UpdateHandler>();
builder.Services.ConfigureTelegramBotMvc();

builder.Services.AddControllers();
Expand Down
61 changes: 27 additions & 34 deletions Webhook.Controllers/Services/UpdateHandler.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,26 @@
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;
using Telegram.Bot.Types.ReplyMarkups;

namespace Webhook.Controllers.Services;

public class UpdateHandler
public class UpdateHandler(ITelegramBotClient bot, ILogger<UpdateHandler> logger) : IUpdateHandler
{
private readonly TelegramBotClient _bot;
private readonly ILogger<UpdateHandler> _logger;
private static readonly InputPollOption[] PollOptions = ["Hello", "World!"];

public UpdateHandler(TelegramBotClient bot, ILogger<UpdateHandler> 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));

Check warning on line 20 in Webhook.Controllers/Services/UpdateHandler.cs

View workflow job for this annotation

GitHub Actions / build

Forward the 'cancellationToken' parameter to the 'Delay' method or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2016)
}

public async Task HandleUpdateAsync(Update update, CancellationToken cancellationToken)
public async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
await (update switch
Expand All @@ -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;

Expand All @@ -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<Message> Usage(Message msg)
Expand All @@ -83,15 +76,15 @@ async Task<Message> 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<Message> 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
Expand All @@ -105,7 +98,7 @@ async Task<Message> 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<Message> SendReplyKeyboard(Message msg)
Expand All @@ -115,12 +108,12 @@ async Task<Message> 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<Message> 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<Message> RequestContactAndLocation(Message msg)
Expand All @@ -130,24 +123,24 @@ async Task<Message> 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<Message> 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<Message> 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<Message> SendAnonymousPoll(Message msg)
{
return await _bot.SendPollAsync(chatId: msg.Chat, "Question", PollOptions);
return await bot.SendPollAsync(chatId: msg.Chat, "Question", PollOptions);
}

static Task<Message> FailingHandler(Message msg)
Expand All @@ -158,48 +151,48 @@ static Task<Message> 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;
}

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");

Check warning on line 190 in Webhook.Controllers/Services/UpdateHandler.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
}

private Task UnknownUpdateHandlerAsync(Update update)
{
_logger.LogInformation("Unknown update type: {UpdateType}", update.Type);
logger.LogInformation("Unknown update type: {UpdateType}", update.Type);
return Task.CompletedTask;
}
}

0 comments on commit dabaf50

Please sign in to comment.