diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 1598b3c..9d1a0d6 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -15,9 +15,9 @@ jobs: with: submodules: 'true' - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.100 + dotnet-version: 8.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index d41621b..69c3139 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -15,9 +15,9 @@ jobs: with: submodules: 'true' - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.100 + dotnet-version: 8.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/BotNet.GrainInterfaces/BotNet.GrainInterfaces.csproj b/BotNet.GrainInterfaces/BotNet.GrainInterfaces.csproj index 16d7a81..9c9ade6 100644 --- a/BotNet.GrainInterfaces/BotNet.GrainInterfaces.csproj +++ b/BotNet.GrainInterfaces/BotNet.GrainInterfaces.csproj @@ -1,15 +1,15 @@  - net7.0 + net8.0 enable - - - - + + + + diff --git a/BotNet.Grains/BotNet.Grains.csproj b/BotNet.Grains/BotNet.Grains.csproj index 68b1c4d..156375e 100644 --- a/BotNet.Grains/BotNet.Grains.csproj +++ b/BotNet.Grains/BotNet.Grains.csproj @@ -1,13 +1,13 @@  - net7.0 + net8.0 enable - - + + diff --git a/BotNet.Grains/TrackedMessageGrain.cs b/BotNet.Grains/TrackedMessageGrain.cs index 8665109..e01cf9f 100644 --- a/BotNet.Grains/TrackedMessageGrain.cs +++ b/BotNet.Grains/TrackedMessageGrain.cs @@ -1,44 +1,44 @@ using System; using System.Collections.Immutable; -using System.Threading.Tasks; -using BotNet.GrainInterfaces; -using Orleans; - -namespace BotNet.Grains { - public class TrackedMessageGrain : Grain, ITrackedMessageGrain { - private string? _sender; - private string? _text; - private long? _replyToMessageId; - - public Task TrackMessageAsync(string sender, string text, long? replyToMessageId) { - _sender = sender; - _text = text; - _replyToMessageId = replyToMessageId; - DelayDeactivation(TimeSpan.FromHours(1)); - return Task.CompletedTask; - } - - public async Task<(string? Sender, string? Text, long? ReplyToMessageId)> GetMessageAsync() { - DelayDeactivation(TimeSpan.FromHours(1)); - return (_sender, _text, _replyToMessageId); - } - - public async Task> GetThreadAsync(int maxLines) { - if (_sender is null || _text is null) return ImmutableList<(string Sender, string Text)>.Empty; - - ImmutableList<(string Sender, string Text)>.Builder builder = ImmutableList.Create((_sender, _text)).ToBuilder(); - - long? messageId = _replyToMessageId; - for (int i = 1; messageId.HasValue && i < maxLines; i++) { - ITrackedMessageGrain repledToMessageGrain = GrainFactory.GetGrain(messageId.Value); - (string? sender, string? text, messageId) = await repledToMessageGrain.GetMessageAsync(); - if (sender is not null && text is not null) { - builder.Add((sender, text)); - } - } - - DelayDeactivation(TimeSpan.FromHours(1)); - return builder.ToImmutableList(); - } - } -} +using System.Threading.Tasks; +using BotNet.GrainInterfaces; +using Orleans; + +namespace BotNet.Grains { + public class TrackedMessageGrain : Grain, ITrackedMessageGrain { + private string? _sender; + private string? _text; + private long? _replyToMessageId; + + public Task TrackMessageAsync(string sender, string text, long? replyToMessageId) { + _sender = sender; + _text = text; + _replyToMessageId = replyToMessageId; + DelayDeactivation(TimeSpan.FromHours(1)); + return Task.CompletedTask; + } + + public Task<(string? Sender, string? Text, long? ReplyToMessageId)> GetMessageAsync() { + DelayDeactivation(TimeSpan.FromHours(1)); + return Task.FromResult((_sender, _text, _replyToMessageId)); + } + + public async Task> GetThreadAsync(int maxLines) { + if (_sender is null || _text is null) return []; + + ImmutableList<(string Sender, string Text)>.Builder builder = ImmutableList.Create((_sender, _text)).ToBuilder(); + + long? messageId = _replyToMessageId; + for (int i = 1; messageId.HasValue && i < maxLines; i++) { + ITrackedMessageGrain repledToMessageGrain = GrainFactory.GetGrain(messageId.Value); + (string? sender, string? text, messageId) = await repledToMessageGrain.GetMessageAsync(); + if (sender is not null && text is not null) { + builder.Add((sender, text)); + } + } + + DelayDeactivation(TimeSpan.FromHours(1)); + return builder.ToImmutableList(); + } + } +} diff --git a/BotNet.Services/BotCommands/Art.cs b/BotNet.Services/BotCommands/Art.cs index 542519a..efa2f10 100644 --- a/BotNet.Services/BotCommands/Art.cs +++ b/BotNet.Services/BotCommands/Art.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; @@ -11,7 +10,6 @@ using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; namespace BotNet.Services.BotCommands { public static class Art { @@ -32,7 +30,7 @@ public static async Task GetRandomArtAsync(ITelegramBotClient botClient, IServic await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(imageStream, "art.jpg"), + photo: new InputFileStream(imageStream, "art.jpg"), replyToMessageId: message.MessageId, cancellationToken: cancellationToken); } catch { @@ -40,7 +38,8 @@ await botClient.SendTextMessageAsync( chatId: message.Chat.Id, text: "Could not generate art", parseMode: ParseMode.Html, - replyToMessageId: message.MessageId); + replyToMessageId: message.MessageId, + cancellationToken: cancellationToken); } } catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { await botClient.SendTextMessageAsync( @@ -60,7 +59,7 @@ await botClient.SendTextMessageAsync( await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(imageStream, "art.jpg"), + photo: new InputFileStream(imageStream, "art.jpg"), cancellationToken: cancellationToken); } catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { await botClient.SendTextMessageAsync( @@ -95,7 +94,7 @@ public static async Task ModifyArtAsync(ITelegramBotClient botClient, IServicePr await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(imageStream, "art.jpg"), + photo: new InputFileStream(imageStream, "art.jpg"), replyToMessageId: message.MessageId, cancellationToken: cancellationToken); } catch { @@ -103,7 +102,8 @@ await botClient.SendTextMessageAsync( chatId: message.Chat.Id, text: "Could not generate art", parseMode: ParseMode.Html, - replyToMessageId: message.MessageId); + replyToMessageId: message.MessageId, + cancellationToken: cancellationToken); } } catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { await botClient.SendTextMessageAsync( diff --git a/BotNet.Services/BotCommands/BMKG.cs b/BotNet.Services/BotCommands/BMKG.cs index 29fff2b..15dff0e 100644 --- a/BotNet.Services/BotCommands/BMKG.cs +++ b/BotNet.Services/BotCommands/BMKG.cs @@ -15,12 +15,12 @@ public static async Task GetLatestEarthQuakeAsync(ITelegramBotClient botClient, try { RATE_LIMITER.ValidateActionRate(message.Chat.Id, message.From!.Id); - (string Text, string ShakemapUrl) = await serviceProvider.GetRequiredService().GetLatestAsync(); + (string text, string shakemapUrl) = await serviceProvider.GetRequiredService().GetLatestAsync(); await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: ShakemapUrl, - caption: Text, + photo: new InputFileUrl(shakemapUrl), + caption: text, replyToMessageId: message.MessageId, parseMode: ParseMode.Html, cancellationToken: cancellationToken); diff --git a/BotNet.Services/BotCommands/Cat.cs b/BotNet.Services/BotCommands/Cat.cs index 8971131..4883741 100644 --- a/BotNet.Services/BotCommands/Cat.cs +++ b/BotNet.Services/BotCommands/Cat.cs @@ -8,7 +8,6 @@ using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; namespace BotNet.Services.BotCommands { public static class Cat { @@ -22,7 +21,7 @@ public static async Task GetRandomCatAsync(ITelegramBotClient botClient, IServic await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(imageStream, "cat.jpg"), + photo: new InputFileStream(imageStream, "cat.jpg"), cancellationToken: cancellationToken); } catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { await botClient.SendTextMessageAsync( diff --git a/BotNet.Services/BotCommands/FlipFlop.cs b/BotNet.Services/BotCommands/FlipFlop.cs index c876811..420e4f7 100644 --- a/BotNet.Services/BotCommands/FlipFlop.cs +++ b/BotNet.Services/BotCommands/FlipFlop.cs @@ -7,7 +7,6 @@ using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; namespace BotNet.Services.BotCommands { public static class FlipFlop { @@ -44,7 +43,7 @@ await botClient.SendTextMessageAsync( await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(flippedImageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), + photo: new InputFileStream(flippedImageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), replyToMessageId: message.ReplyToMessage.MessageId, cancellationToken: cancellationToken); } @@ -83,7 +82,7 @@ await botClient.SendTextMessageAsync( await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(floppedImageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), + photo: new InputFileStream(floppedImageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), replyToMessageId: message.ReplyToMessage.MessageId, cancellationToken: cancellationToken); } @@ -122,7 +121,7 @@ await botClient.SendTextMessageAsync( await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(flappedImageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), + photo: new InputFileStream(flappedImageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), replyToMessageId: message.ReplyToMessage.MessageId, cancellationToken: cancellationToken); } @@ -161,7 +160,7 @@ await botClient.SendTextMessageAsync( await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(fleppedImageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), + photo: new InputFileStream(fleppedImageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), replyToMessageId: message.ReplyToMessage.MessageId, cancellationToken: cancellationToken); } diff --git a/BotNet.Services/BotCommands/Idea.cs b/BotNet.Services/BotCommands/Idea.cs index c03bebc..4bc6e38 100644 --- a/BotNet.Services/BotCommands/Idea.cs +++ b/BotNet.Services/BotCommands/Idea.cs @@ -15,7 +15,17 @@ public static async Task GetRandomIdeaAsync(ITelegramBotClient botClient, IServi try { RATE_LIMITER.ValidateActionRate(message.Chat.Id, message.From!.Id); - string idea = await serviceProvider.GetRequiredService().GetRandomIdeaAsync(cancellationToken); + string? idea = await serviceProvider.GetRequiredService().GetRandomIdeaAsync(cancellationToken); + + if (idea is null) { + await botClient.SendTextMessageAsync( + chatId: message.Chat.Id, + text: $"Bentar ya saya mikir dulu idenya. Coba lagi nanti.", + parseMode: ParseMode.Html, + replyToMessageId: message.MessageId, + cancellationToken: cancellationToken); + return; + } await botClient.SendTextMessageAsync( chatId: message.Chat.Id, diff --git a/BotNet.Services/BotCommands/Joke.cs b/BotNet.Services/BotCommands/Joke.cs index 334df07..a17aa91 100644 --- a/BotNet.Services/BotCommands/Joke.cs +++ b/BotNet.Services/BotCommands/Joke.cs @@ -8,7 +8,6 @@ using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; namespace BotNet.Services.BotCommands { public static class Joke { @@ -22,7 +21,7 @@ public static async Task GetRandomJokeAsync(ITelegramBotClient botClient, IServi await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(imageStream, "joke.webp"), + photo: new InputFileStream(imageStream, "joke.webp"), caption: title, cancellationToken: cancellationToken); } catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { diff --git a/BotNet.Services/BotCommands/Meme.cs b/BotNet.Services/BotCommands/Meme.cs index 60472a3..6fa7a14 100644 --- a/BotNet.Services/BotCommands/Meme.cs +++ b/BotNet.Services/BotCommands/Meme.cs @@ -7,7 +7,6 @@ using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; namespace BotNet.Services.BotCommands { public static class Meme { @@ -20,7 +19,7 @@ public static async Task HandleRamadAsync(ITelegramBotClient botClient, IService await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(floppedImageStream, "ramad.png"), + photo: new InputFileStream(floppedImageStream, "ramad.png"), replyToMessageId: message.MessageId, cancellationToken: cancellationToken); } else { diff --git a/BotNet.Services/BotCommands/OpenAI.cs b/BotNet.Services/BotCommands/OpenAI.cs index 1686981..a51c8cd 100644 --- a/BotNet.Services/BotCommands/OpenAI.cs +++ b/BotNet.Services/BotCommands/OpenAI.cs @@ -1,9 +1,7 @@ using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Net; -using System.Text; using System.Threading; using System.Threading.Tasks; using BotNet.Services.MarkdownV2; @@ -14,7 +12,6 @@ using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; using Telegram.Bot.Types.ReplyMarkups; namespace BotNet.Services.BotCommands { @@ -396,7 +393,7 @@ await botClient.SendTextMessageAsync( } else if (attachments.Count == 1) { return await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(attachments[0]), + photo: new InputFileUrl(attachments[0]), caption: MarkdownV2Sanitizer.Sanitize(result), parseMode: ParseMode.MarkdownV2, replyToMessageId: message.MessageId, @@ -411,7 +408,7 @@ await botClient.SendTextMessageAsync( await botClient.SendMediaGroupAsync( chatId: message.Chat.Id, media: from attachment in attachments - select new InputMediaPhoto(new InputMedia(attachment.OriginalString)), + select new InputMediaPhoto(new InputFileUrl(attachment.OriginalString)), cancellationToken: cancellationToken); return sentMessage; } @@ -446,7 +443,7 @@ await botClient.SendTextMessageAsync( return null; } - public static async Task ChatWithFriendlyBotAsync(ITelegramBotClient botClient, IServiceProvider serviceProvider, Message message, ImmutableList<(string Sender, string Text)> thread, string callSign, CancellationToken cancellationToken) { + public static async Task ChatWithFriendlyBotAsync(ITelegramBotClient botClient, IServiceProvider serviceProvider, Message message, ImmutableList<(string Sender, string Text)> thread, CancellationToken cancellationToken) { try { (message.Chat.Type == ChatType.Private ? CHAT_PRIVATE_RATE_LIMITER @@ -468,7 +465,7 @@ await botClient.SendTextMessageAsync( } else if (attachments.Count == 1) { return await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(attachments[0]), + photo: new InputFileUrl(attachments[0]), caption: MarkdownV2Sanitizer.Sanitize(result), parseMode: ParseMode.MarkdownV2, replyToMessageId: message.MessageId, @@ -483,7 +480,7 @@ await botClient.SendTextMessageAsync( await botClient.SendMediaGroupAsync( chatId: message.Chat.Id, media: from attachment in attachments - select new InputMediaPhoto(new InputMedia(attachment.OriginalString)), + select new InputMediaPhoto(new InputFileUrl(attachment.OriginalString)), cancellationToken: cancellationToken); return sentMessage; } @@ -542,7 +539,7 @@ await botClient.SendTextMessageAsync( } else if (attachments.Count == 1) { return await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(attachments[0]), + photo: new InputFileUrl(attachments[0]), caption: WebUtility.HtmlEncode(result), parseMode: ParseMode.Html, replyToMessageId: message.MessageId, @@ -557,7 +554,7 @@ await botClient.SendTextMessageAsync( await botClient.SendMediaGroupAsync( chatId: message.Chat.Id, media: from attachment in attachments - select new InputMediaPhoto(new InputMedia(attachment.OriginalString)), + select new InputMediaPhoto(new InputFileUrl(attachment.OriginalString)), cancellationToken: cancellationToken); return sentMessage; } @@ -616,7 +613,7 @@ await botClient.SendTextMessageAsync( } else if (attachments.Count == 1) { return await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(attachments[0]), + photo: new InputFileUrl(attachments[0]), caption: WebUtility.HtmlEncode(result), parseMode: ParseMode.Html, replyToMessageId: message.MessageId, @@ -631,7 +628,7 @@ await botClient.SendTextMessageAsync( await botClient.SendMediaGroupAsync( chatId: message.Chat.Id, media: from attachment in attachments - select new InputMediaPhoto(new InputMedia(attachment.OriginalString)), + select new InputMediaPhoto(new InputFileUrl(attachment.OriginalString)), cancellationToken: cancellationToken); return sentMessage; } diff --git a/BotNet.Services/BotCommands/Preview.cs b/BotNet.Services/BotCommands/Preview.cs index e3707ec..cd387c5 100644 --- a/BotNet.Services/BotCommands/Preview.cs +++ b/BotNet.Services/BotCommands/Preview.cs @@ -45,7 +45,7 @@ await botClient.SendTextMessageAsync( await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: previewYoutubeStoryboard.ToString(), + photo: new InputFileUrl(previewYoutubeStoryboard), replyToMessageId: message.MessageId, parseMode: ParseMode.Html, cancellationToken: cancellationToken); @@ -66,7 +66,7 @@ await botClient.SendTextMessageAsync( await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: previewYoutubeStoryboard.ToString(), + photo: new InputFileUrl(previewYoutubeStoryboard), replyToMessageId: message.MessageId, parseMode: ParseMode.Html, cancellationToken: cancellationToken); diff --git a/BotNet.Services/BotCommands/SearchPlace.cs b/BotNet.Services/BotCommands/SearchPlace.cs index 86b9adb..0b9749d 100644 --- a/BotNet.Services/BotCommands/SearchPlace.cs +++ b/BotNet.Services/BotCommands/SearchPlace.cs @@ -27,7 +27,7 @@ public static async Task SearchPlaceAsync(ITelegramBotClient telegramBotClient, await telegramBotClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: staticMapUrl, + photo: new InputFileUrl(staticMapUrl), caption: coords, replyToMessageId: message.MessageId, cancellationToken: cancellationToken); @@ -36,7 +36,8 @@ await telegramBotClient.SendTextMessageAsync( chatId: message.Chat.Id, text: "Lokasi tidak dapat ditemukan", parseMode: ParseMode.Html, - replyToMessageId: message.MessageId); + replyToMessageId: message.MessageId, + cancellationToken: cancellationToken); } } catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { await telegramBotClient.SendTextMessageAsync( diff --git a/BotNet.Services/BotCommands/Waifu.cs b/BotNet.Services/BotCommands/Waifu.cs index 2ada05c..d60c436 100644 --- a/BotNet.Services/BotCommands/Waifu.cs +++ b/BotNet.Services/BotCommands/Waifu.cs @@ -6,7 +6,6 @@ using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; namespace BotNet.Services.BotCommands { public static class Waifu { @@ -19,7 +18,7 @@ public static async Task GetRandomWaifuAsync(ITelegramBotClient botClient, Messa await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(randomUrl), + photo: new InputFileUrl(randomUrl), cancellationToken: cancellationToken); } catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { await botClient.SendTextMessageAsync( diff --git a/BotNet.Services/BotCommands/Weather.cs b/BotNet.Services/BotCommands/Weather.cs index c3c0064..6ef17ba 100644 --- a/BotNet.Services/BotCommands/Weather.cs +++ b/BotNet.Services/BotCommands/Weather.cs @@ -26,7 +26,7 @@ public static async Task GetWeatherAsync(ITelegramBotClient telegramBotClient, I await telegramBotClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: icon, + photo: new InputFileUrl(icon), caption: title, parseMode: ParseMode.Html, replyToMessageId: message.MessageId, @@ -36,7 +36,8 @@ await telegramBotClient.SendTextMessageAsync( chatId: message.Chat.Id, text: "Lokasi tidak dapat ditemukan", parseMode: ParseMode.Html, - replyToMessageId: message.MessageId); + replyToMessageId: message.MessageId, + cancellationToken: cancellationToken); } } catch (RateLimitExceededException exc) when (exc is { Cooldown: var cooldown }) { await telegramBotClient.SendTextMessageAsync( diff --git a/BotNet.Services/BotCommands/Webp.cs b/BotNet.Services/BotCommands/Webp.cs index 0c63ad6..e7edc54 100644 --- a/BotNet.Services/BotCommands/Webp.cs +++ b/BotNet.Services/BotCommands/Webp.cs @@ -4,7 +4,6 @@ using System.Threading; using System.Threading.Tasks; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; using Telegram.Bot.Types; using Telegram.Bot; using BotNet.Services.Webp; @@ -38,7 +37,7 @@ await botClient.SendTextMessageAsync( await botClient.SendPhotoAsync( chatId: message.Chat.Id, - photo: new InputOnlineFile(imageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), + photo: new InputFileStream(imageStream, new string(fileInfo.FileId.Reverse().ToArray()) + ".png"), replyToMessageId: message.ReplyToMessage.MessageId, cancellationToken: cancellationToken); } diff --git a/BotNet.Services/BotNet.Services.csproj b/BotNet.Services/BotNet.Services.csproj index 4eb8a7f..17e04c7 100644 --- a/BotNet.Services/BotNet.Services.csproj +++ b/BotNet.Services/BotNet.Services.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 enable @@ -44,22 +44,22 @@ - - - - - - - - - - + + + + + + + + + + - - - + + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BotNet.Services/ProgrammerHumor/ProgrammerHumorScraper.cs b/BotNet.Services/ProgrammerHumor/ProgrammerHumorScraper.cs index 4486868..ffcab23 100644 --- a/BotNet.Services/ProgrammerHumor/ProgrammerHumorScraper.cs +++ b/BotNet.Services/ProgrammerHumor/ProgrammerHumorScraper.cs @@ -6,14 +6,8 @@ using AngleSharp.Html.Dom; namespace BotNet.Services.ProgrammerHumor { - public class ProgrammerHumorScraper { - private readonly HttpClient _httpClient; - - public ProgrammerHumorScraper( - HttpClient httpClient - ) { - _httpClient = httpClient; - } + public class ProgrammerHumorScraper(HttpClient httpClient) { + private readonly HttpClient _httpClient = httpClient; public async Task<(string Title, byte[] Image)> GetRandomJokeAsync(CancellationToken cancellationToken) { const string url = "https://programmerhumor.io/?bimber_random_post=true"; @@ -21,17 +15,17 @@ HttpClient httpClient using HttpResponseMessage httpResponse = await _httpClient.SendAsync(httpRequest, cancellationToken); httpResponse.EnsureSuccessStatusCode(); - string html = await httpResponse.Content.ReadAsStringAsync(); + string html = await httpResponse.Content.ReadAsStringAsync(cancellationToken); IBrowsingContext browsingContext = BrowsingContext.New(Configuration.Default); IDocument document = await browsingContext.OpenAsync(req => req.Content(html), cancellationToken); - IHtmlHeadingElement titleElement = document.QuerySelector("article header.entry-header h1.entry-title"); - IHtmlImageElement imageElement = document.QuerySelector("article div[itemprop=\"image\"] img"); + IHtmlHeadingElement? titleElement = document.QuerySelector("article header.entry-header h1.entry-title"); + IHtmlImageElement? imageElement = document.QuerySelector("article div[itemprop=\"image\"] img"); - string src = imageElement.Dataset["src"] ?? imageElement.Source; + string? src = imageElement?.Dataset["src"] ?? imageElement?.Source; return ( - Title: titleElement.InnerHtml, + Title: titleElement?.InnerHtml ?? "Humor", Image: await _httpClient.GetByteArrayAsync(src, cancellationToken) ); } diff --git a/BotNet.Services/ThisXDoesNotExist/ThisIdeaDoesNotExist.cs b/BotNet.Services/ThisXDoesNotExist/ThisIdeaDoesNotExist.cs index 7a152e9..1228bc7 100644 --- a/BotNet.Services/ThisXDoesNotExist/ThisIdeaDoesNotExist.cs +++ b/BotNet.Services/ThisXDoesNotExist/ThisIdeaDoesNotExist.cs @@ -6,28 +6,22 @@ using AngleSharp.Html.Dom; namespace BotNet.Services.ThisXDoesNotExist { - public class ThisIdeaDoesNotExist { - private readonly HttpClient _httpClient; + public class ThisIdeaDoesNotExist(HttpClient httpClient) { + private readonly HttpClient _httpClient = httpClient; - public ThisIdeaDoesNotExist( - HttpClient httpClient - ) { - _httpClient = httpClient; - } - - public async Task GetRandomIdeaAsync(CancellationToken cancellationToken) { + public async Task GetRandomIdeaAsync(CancellationToken cancellationToken) { const string url = "https://thisideadoesnotexist.com/"; using HttpRequestMessage httpRequest = new(HttpMethod.Get, url); using HttpResponseMessage httpResponse = await _httpClient.SendAsync(httpRequest, cancellationToken); httpResponse.EnsureSuccessStatusCode(); - string html = await httpResponse.Content.ReadAsStringAsync(); + string html = await httpResponse.Content.ReadAsStringAsync(cancellationToken); IBrowsingContext browsingContext = BrowsingContext.New(Configuration.Default); IDocument document = await browsingContext.OpenAsync(req => req.Content(html), cancellationToken); - IHtmlHeadingElement titleElement = document.QuerySelector("h2"); + IHtmlHeadingElement? titleElement = document.QuerySelector("h2"); - return titleElement.InnerHtml.Trim(); + return titleElement?.InnerHtml.Trim(); } } } diff --git a/BotNet.Tests/BotNet.Tests.csproj b/BotNet.Tests/BotNet.Tests.csproj index ab3abf0..374aacb 100644 --- a/BotNet.Tests/BotNet.Tests.csproj +++ b/BotNet.Tests/BotNet.Tests.csproj @@ -1,22 +1,22 @@  - net7.0 + net8.0 enable false - - - - - + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/BotNet/Bot/UpdateHandler.cs b/BotNet/Bot/UpdateHandler.cs index 1ea2d42..c4d3167 100644 --- a/BotNet/Bot/UpdateHandler.cs +++ b/BotNet/Bot/UpdateHandler.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using BotNet.GrainInterfaces; using BotNet.Services.BotCommands; -using Microsoft.ApplicationInsights; using Microsoft.Extensions.Logging; using Orleans; using RG.Ninja; @@ -18,32 +17,20 @@ using Telegram.Bot.Types.InlineQueryResults; namespace BotNet.Bot { - public class UpdateHandler : IUpdateHandler { - private readonly IClusterClient _clusterClient; - private readonly IServiceProvider _serviceProvider; - private readonly ILogger _logger; - private readonly InlineQueryHandler _inlineQueryHandler; - private readonly TelemetryClient _telemetryClient; + public class UpdateHandler( + IClusterClient clusterClient, + IServiceProvider serviceProvider, + ILogger logger, + InlineQueryHandler inlineQueryHandler + ) : IUpdateHandler { + private readonly IClusterClient _clusterClient = clusterClient; + private readonly IServiceProvider _serviceProvider = serviceProvider; + private readonly ILogger _logger = logger; + private readonly InlineQueryHandler _inlineQueryHandler = inlineQueryHandler; private User? _me; - public UpdateHandler( - IClusterClient clusterClient, - IServiceProvider serviceProvider, - ILogger logger, - InlineQueryHandler inlineQueryHandler, - TelemetryClient telemetryClient - ) { - _clusterClient = clusterClient; - _serviceProvider = serviceProvider; - _logger = logger; - _inlineQueryHandler = inlineQueryHandler; - _telemetryClient = telemetryClient; - } - private async Task GetMeAsync(ITelegramBotClient botClient, CancellationToken cancellationToken) { - if (_me is null) { - _me = await botClient.GetMeAsync(cancellationToken); - } + _me ??= await botClient.GetMeAsync(cancellationToken); return _me; } @@ -119,7 +106,7 @@ await _clusterClient.GetGrain(sentMessage.MessageId).Track && update.Message.Entities?.FirstOrDefault(entity => entity is { Type: MessageEntityType.BotCommand, Offset: 0 }) is null && update.Message.ReplyToMessage is { MessageId: int replyToMessageId, - From: { Id: long replyToUserId } + From.Id: long replyToUserId } && replyToUserId == _me?.Id) { @@ -140,7 +127,7 @@ await _clusterClient.GetGrain(update.Message.MessageId).Tr // Respond to thread Message? sentMessage = callSign switch { - "AI" => await OpenAI.ChatWithFriendlyBotAsync(botClient, _serviceProvider, update.Message, thread, callSign, cancellationToken), + "AI" => await OpenAI.ChatWithFriendlyBotAsync(botClient, _serviceProvider, update.Message, thread, cancellationToken), "Pakde" => await OpenAI.ChatWithSarcasticBotAsync(botClient, _serviceProvider, update.Message, thread, callSign, cancellationToken), _ => throw new NotImplementedException($"Call sign {callSign} not handled") }; @@ -158,7 +145,7 @@ await _clusterClient.GetGrain(sentMessage.MessageId).Track } // Handle commands - if (update.Message.Entities?.FirstOrDefault(entity => entity is { Type: MessageEntityType.BotCommand, Offset: 0 }) is { } commandEntity) { + if (update.Message?.Entities?.FirstOrDefault(entity => entity is { Type: MessageEntityType.BotCommand, Offset: 0 }) is { } commandEntity) { string command = update.Message.Text!.Substring(commandEntity.Offset, commandEntity.Length); // Check if command is in /command@botname format @@ -242,7 +229,8 @@ await botClient.SendTextMessageAsync( chatId: update.Message.Chat.Id, text: "Here's a bubble wrap. Enjoy!", parseMode: ParseMode.Html, - replyMarkup: Pop.GenerateBubbleWrap(Pop.NewSheet()) + replyMarkup: Pop.GenerateBubbleWrap(Pop.NewSheet()), + cancellationToken: cancellationToken ); break; case "/explain": @@ -325,7 +313,8 @@ await botClient.AnswerInlineQueryAsync( await botClient.EditMessageReplyMarkupAsync( chatId: update.CallbackQuery!.Message!.Chat.Id, messageId: update.CallbackQuery.Message.MessageId, - replyMarkup: Pop.GenerateBubbleWrap(data!) + replyMarkup: Pop.GenerateBubbleWrap(data!), + cancellationToken: cancellationToken ); break; default: @@ -335,7 +324,6 @@ await botClient.EditMessageReplyMarkupAsync( throw; } catch (Exception exc) { _logger.LogError(exc, "{message}", exc.Message); - _telemetryClient.TrackException(exc); } } @@ -345,7 +333,6 @@ public Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, _ => exception.ToString() }; _logger.LogError(exception, "{message}", errorMessage); - _telemetryClient.TrackException(exception); return Task.CompletedTask; } } diff --git a/BotNet/BotNet.csproj b/BotNet/BotNet.csproj index a1cc679..7e20125 100644 --- a/BotNet/BotNet.csproj +++ b/BotNet/BotNet.csproj @@ -1,23 +1,23 @@  - net7.0 + net8.0 6593242c-9324-4f32-a0b7-87048d57e708 Linux true true + true - - - - - - - - - + + + + + + + + diff --git a/BotNet/Program.cs b/BotNet/Program.cs index 6785e52..8cee582 100644 --- a/BotNet/Program.cs +++ b/BotNet/Program.cs @@ -82,7 +82,7 @@ services.AddHostedService(); // Telegram Bot - services.AddTelegramBot(botToken: configuration["BotOptions:AccessToken"]); + services.AddTelegramBot(botToken: configuration["BotOptions:AccessToken"]!); }) .UseOrleans((hostBuilderContext, siloBuilder) => { siloBuilder diff --git a/BotNet/Startup.cs b/BotNet/Startup.cs index 8f99f96..dd56b28 100644 --- a/BotNet/Startup.cs +++ b/BotNet/Startup.cs @@ -7,14 +7,9 @@ namespace BotNet { [ExcludeFromCodeCoverage] - public class Startup { - public IConfiguration Configuration { get; } - public IWebHostEnvironment Environment { get; } - - public Startup(IConfiguration configuration, IWebHostEnvironment environment) { - Configuration = configuration; - Environment = environment; - } + public class Startup(IConfiguration configuration, IWebHostEnvironment environment) { + public IConfiguration Configuration { get; } = configuration; + public IWebHostEnvironment Environment { get; } = environment; public void ConfigureServices(IServiceCollection services) { IMvcBuilder mvcBuilder = services.AddControllersWithViews(); @@ -22,9 +17,6 @@ public void ConfigureServices(IServiceCollection services) { mvcBuilder.AddRazorRuntimeCompilation(); } - // Telemetry - services.AddApplicationInsightsTelemetry(Configuration.GetConnectionString("AppInsights")); - // Yes. Those f***ers still use NewtonsoftJson services.AddControllers() .AddNewtonsoftJson();