From 25f906e03e37e8c748fa229cb4619eea049ee4c8 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Mon, 24 Jun 2024 16:48:09 +0200 Subject: [PATCH 01/14] Fix updating the user preferences --- frontend/src/app/pages/users/UserDialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/pages/users/UserDialog.tsx b/frontend/src/app/pages/users/UserDialog.tsx index ec596268..1f62e956 100644 --- a/frontend/src/app/pages/users/UserDialog.tsx +++ b/frontend/src/app/pages/users/UserDialog.tsx @@ -133,7 +133,7 @@ export const UserDialog = (props: UserDialogProps) => {
{allProperties.map(x => - , )} From 2f402647762a0f87e17d289a26e653bf87e0f0bc Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 11:44:35 +0200 Subject: [PATCH 02/14] Fix adding user properties to UserInfo context --- .../Integrations/IntegrationExtensions.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs b/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs index 0d97299c..2c9ca70b 100644 --- a/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs +++ b/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs @@ -6,6 +6,7 @@ // ========================================================================== using Notifo.Domain.Users; +using Notifo.Infrastructure.Collections; namespace Notifo.Domain.Integrations; @@ -13,6 +14,17 @@ public static class IntegrationExtensions { public static UserInfo ToContext(this User user) { - return new UserInfo { Id = user.Id, EmailAddress = user.EmailAddress, PhoneNumber = user.PhoneNumber, Properties = user.SystemProperties }; + return new UserInfo + { + Id = user.Id, + EmailAddress = user.EmailAddress, + PhoneNumber = user.PhoneNumber, + Properties = user.Properties + .Concat( + user.SystemProperties ?? Enumerable.Empty>() + ) + .GroupBy(x => x.Key) + .ToReadonlyDictionary(p => p.Key, p => p.Last().Value) + }; } } From 118cfc0b3450fefc214ef66e2a8f2465796b4cb7 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 11:44:35 +0200 Subject: [PATCH 03/14] Fix adding user properties to UserInfo context --- .../Integrations/IntegrationExtensions.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs b/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs index 0d97299c..2c9ca70b 100644 --- a/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs +++ b/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs @@ -6,6 +6,7 @@ // ========================================================================== using Notifo.Domain.Users; +using Notifo.Infrastructure.Collections; namespace Notifo.Domain.Integrations; @@ -13,6 +14,17 @@ public static class IntegrationExtensions { public static UserInfo ToContext(this User user) { - return new UserInfo { Id = user.Id, EmailAddress = user.EmailAddress, PhoneNumber = user.PhoneNumber, Properties = user.SystemProperties }; + return new UserInfo + { + Id = user.Id, + EmailAddress = user.EmailAddress, + PhoneNumber = user.PhoneNumber, + Properties = user.Properties + .Concat( + user.SystemProperties ?? Enumerable.Empty>() + ) + .GroupBy(x => x.Key) + .ToReadonlyDictionary(p => p.Key, p => p.Last().Value) + }; } } From f20fc3661b7d0ec98303a95a384c408279d2ab73 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 12:46:42 +0200 Subject: [PATCH 04/14] Make the dictionaries merge code more imperative --- .../Integrations/IntegrationExtensions.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs b/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs index 2c9ca70b..1c096b49 100644 --- a/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs +++ b/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs @@ -14,17 +14,22 @@ public static class IntegrationExtensions { public static UserInfo ToContext(this User user) { + var properties = new Dictionary(user.Properties); + + if (user.SystemProperties != null) + { + foreach (var (key, value) in user.SystemProperties) + { + properties[key] = value; + } + } + return new UserInfo { Id = user.Id, EmailAddress = user.EmailAddress, PhoneNumber = user.PhoneNumber, - Properties = user.Properties - .Concat( - user.SystemProperties ?? Enumerable.Empty>() - ) - .GroupBy(x => x.Key) - .ToReadonlyDictionary(p => p.Key, p => p.Last().Value) + Properties = properties.ToReadonlyDictionary() }; } } From 4b72ef2832762df33d314d4acbfa0f1997c7d211 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 18:58:55 +0200 Subject: [PATCH 05/14] Create Discord integration --- .../MessagingMessage.cs | 12 +- .../Discord/DiscordBotClientPool.cs | 36 ++++++ .../Discord/DiscordClient.cs | 19 ++++ .../Discord/DiscordIntegration.Messaging.cs | 103 ++++++++++++++++++ .../Discord/DiscordIntegration.cs | 77 +++++++++++++ .../Discord/DiscordServiceExtensions.cs | 24 ++++ .../Notifo.Domain.Integrations.csproj | 1 + .../Resources/Texts.Designer.cs | 54 +++++++++ .../Resources/Texts.resx | 18 +++ .../Channels/Messaging/MessagingChannel.cs | 5 + .../Integrations/IntegrationExtensions.cs | 1 - backend/src/Notifo/Startup.cs | 10 +- 12 files changed, 354 insertions(+), 6 deletions(-) create mode 100644 backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs create mode 100644 backend/src/Notifo.Domain.Integrations/Discord/DiscordClient.cs create mode 100644 backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs create mode 100644 backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs create mode 100644 backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs diff --git a/backend/src/Notifo.Domain.Integrations.Abstractions/MessagingMessage.cs b/backend/src/Notifo.Domain.Integrations.Abstractions/MessagingMessage.cs index 56868784..4d089908 100644 --- a/backend/src/Notifo.Domain.Integrations.Abstractions/MessagingMessage.cs +++ b/backend/src/Notifo.Domain.Integrations.Abstractions/MessagingMessage.cs @@ -9,7 +9,17 @@ namespace Notifo.Domain.Integrations; public sealed class MessagingMessage : BaseMessage { + public IReadOnlyDictionary Targets { get; set; } + public string Text { get; set; } + public string? DetailedBodyText { get; init; } - public IReadOnlyDictionary Targets { get; set; } + + public string? ImageLarge { get; init; } + + public string? ImageSmall { get; init; } + + public string? LinkText { get; init; } + + public string? LinkUrl { get; init; } } diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs new file mode 100644 index 00000000..7f2f5be6 --- /dev/null +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs @@ -0,0 +1,36 @@ +// ===================================================== +// Notifo.io +// ========================================================================== +// Copyright (c) Sebastian Stehle +// Author of the file: Artur Nowak +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Discord; +using Microsoft.Extensions.Caching.Memory; + +namespace Notifo.Domain.Integrations.Discord; +public class DiscordBotClientPool : CachePool +{ + public DiscordBotClientPool(IMemoryCache memoryCache) + : base(memoryCache) + { + } + + public IDiscordClient GetDiscordClient(string botToken, CancellationToken ct) + { + var cacheKey = $"{nameof(IDiscordClient)}_{botToken}"; + + var found = GetOrCreate(cacheKey, TimeSpan.FromMinutes(5), () => + { + var client = new DiscordClient(); + + client.LoginAsync(TokenType.Bot, botToken).Wait(ct); + + return client; + }); + + return found; + } + +} diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordClient.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordClient.cs new file mode 100644 index 00000000..891751ce --- /dev/null +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordClient.cs @@ -0,0 +1,19 @@ +// ===================================================== +// Notifo.io +// ========================================================================== +// Copyright (c) Sebastian Stehle +// Author of the file: Artur Nowak +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Discord.Rest; + +namespace Notifo.Domain.Integrations.Discord; +public class DiscordClient : DiscordRestClient, IAsyncDisposable +{ + public async new ValueTask DisposeAsync() + { + await LogoutAsync(); + await base.DisposeAsync(); + } +} diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs new file mode 100644 index 00000000..808fb9b5 --- /dev/null +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs @@ -0,0 +1,103 @@ +// ===================================================== +// Notifo.io +// ========================================================================== +// Copyright (c) Sebastian Stehle +// Author of the file: Artur Nowak +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Discord; +using Discord.Net; + +namespace Notifo.Domain.Integrations.Discord; +public sealed partial class DiscordIntegration : IMessagingSender +{ + private const int Attempts = 5; + private const string DiscordChatId = nameof(DiscordChatId); + + public void AddTargets(IDictionary targets, UserInfo user) + { + var userId = GetUserId(user); + + if (!string.IsNullOrWhiteSpace(userId)) + { + targets[DiscordChatId] = userId; + } + } + + public async Task SendAsync(IntegrationContext context, MessagingMessage message, + CancellationToken ct) + { + if (!message.Targets.TryGetValue(DiscordChatId, out var chatId)) + { + return DeliveryResult.Skipped(); + } + + await SendMessageAsync(context, message, chatId, ct); + + return DeliveryResult.Handled; + } + + private async Task SendMessageAsync(IntegrationContext context, MessagingMessage message, string chatId, + CancellationToken ct) + { + var botToken = BotToken.GetString(context.Properties); + + for (var i = 1; i <= Attempts; i++) + { + try + { + var client = discordBotClientPool.GetDiscordClient(botToken, ct); + + var user = await client.GetUserAsync(ulong.Parse(chatId)); + if (user is null) + { + throw new InvalidOperationException("User not found."); + } + + EmbedBuilder builder = new EmbedBuilder(); + + builder.WithTitle(message.Text); + builder.WithDescription(message.DetailedBodyText); + + if (!string.IsNullOrWhiteSpace(message.ImageSmall)) + { + builder.WithThumbnailUrl(message.ImageSmall); + } + + if (!string.IsNullOrWhiteSpace(message.ImageLarge)) + { + builder.WithImageUrl(message.ImageLarge); + } + + if (!string.IsNullOrWhiteSpace(message.LinkUrl)) + { + builder.WithFields(new EmbedFieldBuilder().WithName(message.LinkText ?? message.LinkUrl).WithValue(message.LinkUrl)); + } + + builder.WithFooter("Sent with Notifo"); + + await user.SendMessageAsync(string.Empty, false, builder.Build()); // Throws HttpException if the user has some privacy settings that make it impossible to text them. + break; + } + catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.CannotSendMessageToUser) + { + return DeliveryResult.Failed("User has privacy settings that prevent sending them DMs on Discord."); + } + catch + { + if (i == Attempts) + { + return DeliveryResult.Failed("Unknown error when sending Discord DM to user."); + } + } + } + + return DeliveryResult.Handled; + } + + private static string? GetUserId(UserInfo user) + { + return UserId.GetString(user.Properties); + } +} diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs new file mode 100644 index 00000000..55b6d77e --- /dev/null +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs @@ -0,0 +1,77 @@ +// ===================================================== +// Notifo.io +// ========================================================================== +// Copyright (c) Sebastian Stehle +// Author of the file: Artur Nowak +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Discord; +using Notifo.Domain.Integrations.Resources; + +namespace Notifo.Domain.Integrations.Discord; +public sealed partial class DiscordIntegration : IIntegration +{ + private readonly DiscordBotClientPool discordBotClientPool; + + public static readonly IntegrationProperty UserId = new IntegrationProperty("discordUserId", PropertyType.Text) + { + EditorLabel = Texts.Discord_UserIdLabel, + EditorDescription = Texts.Discord_UserIdDescription + }; + + public static readonly IntegrationProperty BotToken = new IntegrationProperty("discordBotToken", PropertyType.Text) + { + EditorLabel = Texts.Discord_BotTokenLabel, + EditorDescription = Texts.Discord_BotTokenDescription, + IsRequired = true + }; + + public IntegrationDefinition Definition { get; } = + new IntegrationDefinition( + "Discord", + Texts.Discord_Name, + "", + new List + { + BotToken + }, + new List + { + UserId + }, + new HashSet + { + Providers.Messaging, + }) + { + Description = Texts.Discord_Description + }; + + public DiscordIntegration(DiscordBotClientPool discordBotClientPool) + { + this.discordBotClientPool = discordBotClientPool; + } + + public async Task OnConfiguredAsync(IntegrationContext context, IntegrationConfiguration? previous, + CancellationToken ct) + { + // Validate if the token is valid. + var botToken = BotToken.GetString(context.Properties); + if (botToken == null) + { + return IntegrationStatus.VerificationFailed; + } + + try + { + TokenUtils.ValidateToken(TokenType.Bot, botToken); + } + catch + { + return IntegrationStatus.VerificationFailed; + } + + return IntegrationStatus.Verified; + } +} diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs new file mode 100644 index 00000000..297ecfc9 --- /dev/null +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs @@ -0,0 +1,24 @@ +// ===================================================== +// Notifo.io +// ========================================================================== +// Copyright (c) Sebastian Stehle +// Author of the file: Artur Nowak +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.DependencyInjection; + +namespace Notifo.Domain.Integrations.Discord; +public static class DiscordServiceExtensions +{ + public static IServiceCollection AddIntegrationDiscord(this IServiceCollection services) + { + services.AddSingletonAs() + .As(); + + services.AddSingletonAs() + .AsSelf(); + + return services; + } +} diff --git a/backend/src/Notifo.Domain.Integrations/Notifo.Domain.Integrations.csproj b/backend/src/Notifo.Domain.Integrations/Notifo.Domain.Integrations.csproj index f9c03620..935684a3 100644 --- a/backend/src/Notifo.Domain.Integrations/Notifo.Domain.Integrations.csproj +++ b/backend/src/Notifo.Domain.Integrations/Notifo.Domain.Integrations.csproj @@ -11,6 +11,7 @@ + diff --git a/backend/src/Notifo.Domain.Integrations/Resources/Texts.Designer.cs b/backend/src/Notifo.Domain.Integrations/Resources/Texts.Designer.cs index 70d845dc..e18d0bf9 100644 --- a/backend/src/Notifo.Domain.Integrations/Resources/Texts.Designer.cs +++ b/backend/src/Notifo.Domain.Integrations/Resources/Texts.Designer.cs @@ -87,6 +87,60 @@ internal static string AmazonSES_ReservedEmailAddress { } } + /// + /// Looks up a localized string similar to You will find it on your Discord Developer Platform. Go to your app and then to the "Bot" tab.. + /// + internal static string Discord_BotTokenDescription { + get { + return ResourceManager.GetString("Discord_BotTokenDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Discord Bot token. + /// + internal static string Discord_BotTokenLabel { + get { + return ResourceManager.GetString("Discord_BotTokenLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send Notifo's notifications via direct messages to your Discord account.. + /// + internal static string Discord_Description { + get { + return ResourceManager.GetString("Discord_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Discord. + /// + internal static string Discord_Name { + get { + return ResourceManager.GetString("Discord_Name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The user_id of the user the bot will send the DMs to. User is required to install the Discord bot on their account.. + /// + internal static string Discord_UserIdDescription { + get { + return ResourceManager.GetString("Discord_UserIdDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Discord user id. + /// + internal static string Discord_UserIdLabel { + get { + return ResourceManager.GetString("Discord_UserIdLabel", resourceCulture); + } + } + /// /// Looks up a localized string similar to Comma or line-separated list of additional email-addresses.. /// diff --git a/backend/src/Notifo.Domain.Integrations/Resources/Texts.resx b/backend/src/Notifo.Domain.Integrations/Resources/Texts.resx index 3be2d294..8a738434 100644 --- a/backend/src/Notifo.Domain.Integrations/Resources/Texts.resx +++ b/backend/src/Notifo.Domain.Integrations/Resources/Texts.resx @@ -126,6 +126,24 @@ Email address {0} is already used by another app. + + You will find it on your Discord Developer Platform. Go to your app and then to the "Bot" tab. + + + Discord Bot token + + + Send Notifo's notifications via direct messages to your Discord account. + + + Discord + + + The user_id of the user the bot will send the DMs to. User is required to install the Discord bot on their account. + + + Discord user id + Comma or line-separated list of additional email-addresses. diff --git a/backend/src/Notifo.Domain/Channels/Messaging/MessagingChannel.cs b/backend/src/Notifo.Domain/Channels/Messaging/MessagingChannel.cs index e527e922..e71c836e 100644 --- a/backend/src/Notifo.Domain/Channels/Messaging/MessagingChannel.cs +++ b/backend/src/Notifo.Domain/Channels/Messaging/MessagingChannel.cs @@ -262,6 +262,11 @@ private async Task SendCoreAsync(string appId, MessagingMessage Targets = lastJob.Configuration, // We might also format the text without the template if no primary template is defined. Text = text, + DetailedBodyText = lastJob.Notification.Formatting.Body, + ImageLarge = lastJob.Notification.Formatting.ImageLarge, + ImageSmall = lastJob.Notification.Formatting.ImageSmall, + LinkText = lastJob.Notification.Formatting.LinkText, + LinkUrl = lastJob.Notification.Formatting.LinkUrl, }; return (default, message.Enrich(lastJob, Name)); diff --git a/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs b/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs index a433c19e..1c096b49 100644 --- a/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs +++ b/backend/src/Notifo.Domain/Integrations/IntegrationExtensions.cs @@ -7,7 +7,6 @@ using Notifo.Domain.Users; using Notifo.Infrastructure.Collections; -using System.Collections.Generic; namespace Notifo.Domain.Integrations; diff --git a/backend/src/Notifo/Startup.cs b/backend/src/Notifo/Startup.cs index bc71307f..00019577 100644 --- a/backend/src/Notifo/Startup.cs +++ b/backend/src/Notifo/Startup.cs @@ -5,18 +5,19 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Globalization; -using System.Net; -using System.Text.Json; -using System.Text.Json.Serialization; using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Notifo.Areas.Api.Controllers.Notifications; using Notifo.Areas.Frontend; using Notifo.Domain; +using Notifo.Domain.Integrations.Discord; using Notifo.Domain.Utils; using Notifo.Pipeline; +using System.Globalization; +using System.Net; +using System.Text.Json; +using System.Text.Json.Serialization; namespace Notifo; @@ -146,6 +147,7 @@ public void ConfigureServices(IServiceCollection services) services.AddMyWebPushChannel(config); services.AddIntegrationAmazonSES(config); + services.AddIntegrationDiscord(); services.AddIntegrationFirebase(); services.AddIntegrationHttp(); services.AddIntegrationMailchimp(); From 7a77581d41051926bceb0312ff1166388ce2d974 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 19:59:24 +0200 Subject: [PATCH 06/14] Fix invalid status on Discord integration --- .../Discord/DiscordIntegration.Messaging.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs index 808fb9b5..bb935fad 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs @@ -13,7 +13,7 @@ namespace Notifo.Domain.Integrations.Discord; public sealed partial class DiscordIntegration : IMessagingSender { private const int Attempts = 5; - private const string DiscordChatId = nameof(DiscordChatId); + public const string DiscordChatId = nameof(DiscordChatId); public void AddTargets(IDictionary targets, UserInfo user) { @@ -33,9 +33,7 @@ public async Task SendAsync(IntegrationContext context, Messagin return DeliveryResult.Skipped(); } - await SendMessageAsync(context, message, chatId, ct); - - return DeliveryResult.Handled; + return await SendMessageAsync(context, message, chatId, ct); } private async Task SendMessageAsync(IntegrationContext context, MessagingMessage message, string chatId, From 47dc766c8cc08dbcf6066693b8f1fcc24c91a4b8 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 20:00:38 +0200 Subject: [PATCH 07/14] Add tests for Discord integration --- .../Integrations/Discord/DiscordTests.cs | 154 ++++++++++++++++++ .../Notifo.Domain.Tests/appsettings.json | 84 +++++----- 2 files changed, 198 insertions(+), 40 deletions(-) create mode 100644 backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs diff --git a/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs b/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs new file mode 100644 index 00000000..b5143dc2 --- /dev/null +++ b/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs @@ -0,0 +1,154 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Notifo.Domain.Integrations.Discord; +public sealed class DiscordTests +{ + [Fact] + public void Should_get_integration() + { + var client = CreateClient(); + Assert.NotNull(client.System); + } + + [Fact] + public async Task Should_send_simple_message() + { + var client = CreateClient(); + + var message = new MessagingMessage + { + Text = "Test message", + }; + + var userId = GetUserId(); + AddTargets(message, userId); + + var result = await client.System.SendAsync(client.Context, message, default); + + Assert.Equal(DeliveryResult.Handled, result); + } + + [Fact] + public async Task Send_full_message() + { + var client = CreateClient(); + + var message = new MessagingMessage + { + Text = "Test message", + DetailedBodyText = "Detailed body text", + }; + + var userId = GetUserId(); + AddTargets(message, userId); + var result = await client.System.SendAsync(client.Context, message, default); + + Assert.Equal(DeliveryResult.Handled, result); + } + + [Fact] + public async Task Should_failed_on_user_without_app_installed() + { + var client = CreateClient(); + + var message = new MessagingMessage { Text = "Test message" }; + + var userId = "261155655006000000"; // Random userId + AddTargets(message, userId); + + var result = await client.System.SendAsync(client.Context, message, default); + + Assert.Equal(DeliveryStatus.Failed, result.Status); + } + + [Fact] + public async Task Should_accept_images() + { + var client = CreateClient(); + + var message = new MessagingMessage + { + Text = "Test message", + ImageSmall = "https://picsum.photos/200/300", + ImageLarge = "https://picsum.photos/400/600" + }; + + var userId = GetUserId(); + AddTargets(message, userId); + var result = await client.System.SendAsync(client.Context, message, default); + + Assert.Equal(DeliveryResult.Handled, result); + } + + [Fact] + public async Task Should_accept_urls() + { + var client = CreateClient(); + + var message = new MessagingMessage + { + Text = "Test message", + LinkUrl = "https://notifo.io", + LinkText = "Notifo" + }; + var userId = GetUserId(); + AddTargets(message, userId); + var result = await client.System.SendAsync(client.Context, message, default); + + Assert.Equal(DeliveryResult.Handled, result); + } + + static ResolvedIntegration CreateClient() + { + var botToken = TestHelpers.Configuration.GetValue("discord:botToken")!; + + var context = BuildContext(new Dictionary + { + [DiscordIntegration.BotToken.Name] = botToken, + }); + + var integration = + new ServiceCollection() + .AddIntegrationDiscord() + .AddMemoryCache() + .BuildServiceProvider() + .GetRequiredService(); + + Assert.NotNull(integration); + return new ResolvedIntegration(Guid.NewGuid().ToString(), context, integration); + } + + private string GetUserId() + { + var id = TestHelpers.Configuration.GetValue("discord:userId"); + + Assert.False(string.IsNullOrWhiteSpace(id), "Please set the Discord userId in the testing env"); + return id; + } + + private MessagingMessage AddTargets(MessagingMessage message, string userId) + { + message.Targets = new Dictionary() + { + { DiscordIntegration.DiscordChatId, userId } + }; + return message; + } + + static IntegrationContext BuildContext(Dictionary properties) + { + return new IntegrationContext + { + UpdateStatusAsync = null!, + AppId = string.Empty, + AppName = string.Empty, + CallbackToken = string.Empty, + CallbackUrl = string.Empty, + IntegrationAdapter = null!, + IntegrationId = string.Empty, + Properties = properties, + WebhookUrl = string.Empty, + }; + } +} diff --git a/backend/tests/Notifo.Domain.Tests/appsettings.json b/backend/tests/Notifo.Domain.Tests/appsettings.json index 447ebed9..ee1844b2 100644 --- a/backend/tests/Notifo.Domain.Tests/appsettings.json +++ b/backend/tests/Notifo.Domain.Tests/appsettings.json @@ -1,47 +1,51 @@ { - - "sms": { - "to": "", - - "messageBird": { - "accessKey": "", - "phoneNumber": "", - "phoneNumbers": "" - }, - "telekom": { - "apiKey": "", - "phoneNumber": "" - }, + "sms": { + "to": "", - "twilio": { - "authToken": "", - "accountSid": "", - "phoneNumber": "" - } - }, - "email": { - "address": "sebastian@squidex.io", - - "amazonSES": { - "host": "", - "username": "", - "password": "" - }, + "messageBird": { + "accessKey": "", + "phoneNumber": "", + "phoneNumbers": "" + }, - "mailchimp": { - "apiKey": "" - }, + "telekom": { + "apiKey": "", + "phoneNumber": "" + }, - "mailjet": { - "apiKey": "", - "apiSecret": "" - }, + "twilio": { + "authToken": "", + "accountSid": "", + "phoneNumber": "" + }, + "email": { + "address": "sebastian@squidex.io", + + "amazonSES": { + "host": "", + "username": "", + "password": "" + }, + + "mailchimp": { + "apiKey": "" + }, - "smtp": { - "host": "", - "username": "", - "password": "" + "mailjet": { + "apiKey": "", + "apiSecret": "" + }, + + "smtp": { + "host": "", + "username": "", + "password": "" + } + } + }, + "discord": { + "botToken": "", + "userId": "" } - } -} +} \ No newline at end of file From 3bf2f508ed078b4fab12e905798f360efe0c7f80 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 20:05:20 +0200 Subject: [PATCH 08/14] Change appSettings indentation to match the previous one --- .../Notifo.Domain.Tests/appsettings.json | 87 +++++++++---------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/backend/tests/Notifo.Domain.Tests/appsettings.json b/backend/tests/Notifo.Domain.Tests/appsettings.json index ee1844b2..14d2aa6e 100644 --- a/backend/tests/Notifo.Domain.Tests/appsettings.json +++ b/backend/tests/Notifo.Domain.Tests/appsettings.json @@ -1,51 +1,50 @@ { + "sms": { + "to": "", - "sms": { - "to": "", - - "messageBird": { - "accessKey": "", - "phoneNumber": "", - "phoneNumbers": "" - }, - - "telekom": { - "apiKey": "", - "phoneNumber": "" - }, - - "twilio": { - "authToken": "", - "accountSid": "", - "phoneNumber": "" - }, - "email": { - "address": "sebastian@squidex.io", - - "amazonSES": { - "host": "", - "username": "", - "password": "" - }, - - "mailchimp": { - "apiKey": "" - }, + "messageBird": { + "accessKey": "", + "phoneNumber": "", + "phoneNumbers": "" + }, - "mailjet": { - "apiKey": "", - "apiSecret": "" - }, + "telekom": { + "apiKey": "", + "phoneNumber": "" + }, - "smtp": { - "host": "", - "username": "", - "password": "" - } - } + "twilio": { + "authToken": "", + "accountSid": "", + "phoneNumber": "" }, - "discord": { - "botToken": "", - "userId": "" + "email": { + "address": "sebastian@squidex.io", + + "amazonSES": { + "host": "", + "username": "", + "password": "" + }, + + "mailchimp": { + "apiKey": "" + }, + + "mailjet": { + "apiKey": "", + "apiSecret": "" + }, + + "smtp": { + "host": "", + "username": "", + "password": "" + } } + }, + "discord": { + "botToken": "", + "userId": "" + } } \ No newline at end of file From 604baa43b85d527e6bcd9e26a90e9feed5cd147b Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 20:07:48 +0200 Subject: [PATCH 09/14] Update appSettings for tests --- .../Notifo.Domain.Tests/appsettings.json | 85 ++++++++++--------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/backend/tests/Notifo.Domain.Tests/appsettings.json b/backend/tests/Notifo.Domain.Tests/appsettings.json index 14d2aa6e..435ebc64 100644 --- a/backend/tests/Notifo.Domain.Tests/appsettings.json +++ b/backend/tests/Notifo.Domain.Tests/appsettings.json @@ -1,50 +1,51 @@ { - "sms": { - "to": "", - "messageBird": { - "accessKey": "", - "phoneNumber": "", - "phoneNumbers": "" - }, + "sms": { + "to": "", - "telekom": { - "apiKey": "", - "phoneNumber": "" - }, + "messageBird": { + "accessKey": "", + "phoneNumber": "", + "phoneNumbers": "" + }, - "twilio": { - "authToken": "", - "accountSid": "", - "phoneNumber": "" + "telekom": { + "apiKey": "", + "phoneNumber": "" + }, + + "twilio": { + "authToken": "", + "accountSid": "", + "phoneNumber": "" + } }, "email": { - "address": "sebastian@squidex.io", - - "amazonSES": { - "host": "", - "username": "", - "password": "" - }, - - "mailchimp": { - "apiKey": "" - }, - - "mailjet": { - "apiKey": "", - "apiSecret": "" - }, - - "smtp": { - "host": "", - "username": "", - "password": "" - } + "address": "sebastian@squidex.io", + + "amazonSES": { + "host": "", + "username": "", + "password": "" + }, + + "mailchimp": { + "apiKey": "" + }, + + "mailjet": { + "apiKey": "", + "apiSecret": "" + }, + + "smtp": { + "host": "", + "username": "", + "password": "" + } + }, + "discord": { + "botToken": "", + "userId": "" } - }, - "discord": { - "botToken": "", - "userId": "" - } } \ No newline at end of file From 4d735e5ba66c64de000b71baa50d159dcdedaa94 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Tue, 25 Jun 2024 20:08:45 +0200 Subject: [PATCH 10/14] Add empty line at the end of the file to match the convention --- backend/tests/Notifo.Domain.Tests/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/Notifo.Domain.Tests/appsettings.json b/backend/tests/Notifo.Domain.Tests/appsettings.json index 435ebc64..7adcc6e0 100644 --- a/backend/tests/Notifo.Domain.Tests/appsettings.json +++ b/backend/tests/Notifo.Domain.Tests/appsettings.json @@ -48,4 +48,4 @@ "botToken": "", "userId": "" } -} \ No newline at end of file +} From 858ebe01ec3e8e7492096774ce61c3345134dffc Mon Sep 17 00:00:00 2001 From: Arciiix Date: Fri, 28 Jun 2024 18:43:35 +0200 Subject: [PATCH 11/14] Apply code review advice --- .../MessagingMessage.cs | 2 +- .../Notifo.Domain.Integrations/CachePool.cs | 70 +++++++++----- .../Discord/DiscordBotClientPool.cs | 17 ++-- .../Discord/DiscordClient.cs | 4 +- .../Discord/DiscordIntegration.Messaging.cs | 13 +-- .../Discord/DiscordIntegration.cs | 53 +++++------ .../Discord/DiscordServiceExtensions.cs | 4 +- .../Channels/Messaging/MessagingChannel.cs | 2 +- .../Integrations/Discord/DiscordTests.cs | 93 ++++++++++--------- .../Notifo.Domain.Tests/appsettings.json | 83 ++++++++--------- 10 files changed, 183 insertions(+), 158 deletions(-) diff --git a/backend/src/Notifo.Domain.Integrations.Abstractions/MessagingMessage.cs b/backend/src/Notifo.Domain.Integrations.Abstractions/MessagingMessage.cs index 4d089908..7e4b3421 100644 --- a/backend/src/Notifo.Domain.Integrations.Abstractions/MessagingMessage.cs +++ b/backend/src/Notifo.Domain.Integrations.Abstractions/MessagingMessage.cs @@ -12,8 +12,8 @@ public sealed class MessagingMessage : BaseMessage public IReadOnlyDictionary Targets { get; set; } public string Text { get; set; } - public string? DetailedBodyText { get; init; } + public string? Body { get; init; } public string? ImageLarge { get; init; } diff --git a/backend/src/Notifo.Domain.Integrations/CachePool.cs b/backend/src/Notifo.Domain.Integrations/CachePool.cs index 9116bfa1..3fb33200 100644 --- a/backend/src/Notifo.Domain.Integrations/CachePool.cs +++ b/backend/src/Notifo.Domain.Integrations/CachePool.cs @@ -33,39 +33,61 @@ protected TItem GetOrCreate(object key, TimeSpan expiration, Func factory entry.AbsoluteExpirationRelativeToNow = expiration; var item = factory(); + HandleDispose(item, entry); - switch (item) - { - case IDisposable disposable: + return item; + })!; + } + + protected Task GetOrCreateAsync(object key, Func> factory) + { + return GetOrCreateAsync(key, DefaultExpiration, factory); + } + + protected Task GetOrCreateAsync(object key, TimeSpan expiration, Func> factory) + { + return memoryCache.GetOrCreateAsync(key, async entry => + { + entry.AbsoluteExpirationRelativeToNow = expiration; + + var item = await factory(); + HandleDispose(item, entry); + + return item; + })!; + } + + private void HandleDispose(TItem item, ICacheEntry entry) + { + switch (item) + { + case IDisposable disposable: + { + entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration { - entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration + EvictionCallback = (key, value, reason, state) => { - EvictionCallback = (key, value, reason, state) => - { - disposable.Dispose(); - } - }); - break; - } + disposable.Dispose(); + } + }); + break; + } - case IAsyncDisposable asyncDisposable: + case IAsyncDisposable asyncDisposable: + { + entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration { - entry.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration + EvictionCallback = (key, value, reason, state) => { - EvictionCallback = (key, value, reason, state) => - { #pragma warning disable CA2012 // Use ValueTasks correctly #pragma warning disable MA0134 // Observe result of async calls - asyncDisposable.DisposeAsync(); + asyncDisposable.DisposeAsync(); #pragma warning restore MA0134 // Observe result of async calls #pragma warning restore CA2012 // Use ValueTasks correctly - } - }); - break; - } - } - - return item; - })!; + } + }); + break; + } + } } } diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs index 7f2f5be6..5598cf7d 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs @@ -1,8 +1,7 @@ -// ===================================================== +// ========================================================================== // Notifo.io // ========================================================================== // Copyright (c) Sebastian Stehle -// Author of the file: Artur Nowak // All rights reserved. Licensed under the MIT license. // ========================================================================== @@ -10,6 +9,7 @@ using Microsoft.Extensions.Caching.Memory; namespace Notifo.Domain.Integrations.Discord; + public class DiscordBotClientPool : CachePool { public DiscordBotClientPool(IMemoryCache memoryCache) @@ -17,20 +17,25 @@ public DiscordBotClientPool(IMemoryCache memoryCache) { } - public IDiscordClient GetDiscordClient(string botToken, CancellationToken ct) + public async Task GetDiscordClient(string botToken, CancellationToken ct) { var cacheKey = $"{nameof(IDiscordClient)}_{botToken}"; - var found = GetOrCreate(cacheKey, TimeSpan.FromMinutes(5), () => + var found = await GetOrCreateAsync(cacheKey, TimeSpan.FromMinutes(5), async () => { var client = new DiscordClient(); - client.LoginAsync(TokenType.Bot, botToken).Wait(ct); + // Sadly it can't receive the cancellation token. + // The LoginAsync method of DiscordRestClient is a wrapper over the internal ApiClient.LoginAsync function. + // That one accepts the RequestOptions parameter, which has a CancellationToken property. + // The problem is that the DiscordClient.LoginAsync function doesn't expose the RequestOptions parameter. + // We could use workarounds like WaitAsync, but it wouldn't interrupt the operation anyway. + // Killing the thread on the other hand would also be a bad idea and could cause some integrity issues. + await client.LoginAsync(TokenType.Bot, botToken); return client; }); return found; } - } diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordClient.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordClient.cs index 891751ce..67456f67 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordClient.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordClient.cs @@ -1,14 +1,14 @@ -// ===================================================== +// ========================================================================== // Notifo.io // ========================================================================== // Copyright (c) Sebastian Stehle -// Author of the file: Artur Nowak // All rights reserved. Licensed under the MIT license. // ========================================================================== using Discord.Rest; namespace Notifo.Domain.Integrations.Discord; + public class DiscordClient : DiscordRestClient, IAsyncDisposable { public async new ValueTask DisposeAsync() diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs index bb935fad..a65ceba0 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs @@ -1,8 +1,7 @@ -// ===================================================== +// ========================================================================== // Notifo.io // ========================================================================== // Copyright (c) Sebastian Stehle -// Author of the file: Artur Nowak // All rights reserved. Licensed under the MIT license. // ========================================================================== @@ -45,9 +44,10 @@ private async Task SendMessageAsync(IntegrationContext context, { try { - var client = discordBotClientPool.GetDiscordClient(botToken, ct); + var client = await discordBotClientPool.GetDiscordClient(botToken, ct); + var requestOptions = new RequestOptions { CancelToken = ct }; - var user = await client.GetUserAsync(ulong.Parse(chatId)); + var user = await client.GetUserAsync(ulong.Parse(chatId), CacheMode.AllowDownload, requestOptions); if (user is null) { throw new InvalidOperationException("User not found."); @@ -56,7 +56,7 @@ private async Task SendMessageAsync(IntegrationContext context, EmbedBuilder builder = new EmbedBuilder(); builder.WithTitle(message.Text); - builder.WithDescription(message.DetailedBodyText); + builder.WithDescription(message.Body); if (!string.IsNullOrWhiteSpace(message.ImageSmall)) { @@ -75,7 +75,8 @@ private async Task SendMessageAsync(IntegrationContext context, builder.WithFooter("Sent with Notifo"); - await user.SendMessageAsync(string.Empty, false, builder.Build()); // Throws HttpException if the user has some privacy settings that make it impossible to text them. + // Throws HttpException if the user has some privacy settings that make it impossible to text them. + await user.SendMessageAsync(string.Empty, false, builder.Build(), requestOptions); break; } catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.CannotSendMessageToUser) diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs index 55b6d77e..103384de 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs @@ -1,15 +1,16 @@ -// ===================================================== +// ========================================================================== // Notifo.io // ========================================================================== // Copyright (c) Sebastian Stehle -// Author of the file: Artur Nowak // All rights reserved. Licensed under the MIT license. // ========================================================================== using Discord; using Notifo.Domain.Integrations.Resources; +using Notifo.Infrastructure.Validation; namespace Notifo.Domain.Integrations.Discord; + public sealed partial class DiscordIntegration : IIntegration { private readonly DiscordBotClientPool discordBotClientPool; @@ -28,40 +29,36 @@ public sealed partial class DiscordIntegration : IIntegration }; public IntegrationDefinition Definition { get; } = - new IntegrationDefinition( - "Discord", - Texts.Discord_Name, - "", - new List - { - BotToken - }, - new List - { - UserId - }, - new HashSet - { - Providers.Messaging, - }) - { - Description = Texts.Discord_Description - }; + new IntegrationDefinition( + "Discord", + Texts.Discord_Name, + "", + new List + { + BotToken + }, + new List + { + UserId + }, + new HashSet + { + Providers.Messaging, + }) + { + Description = Texts.Discord_Description + }; public DiscordIntegration(DiscordBotClientPool discordBotClientPool) { this.discordBotClientPool = discordBotClientPool; } - public async Task OnConfiguredAsync(IntegrationContext context, IntegrationConfiguration? previous, + public Task OnConfiguredAsync(IntegrationContext context, IntegrationConfiguration? previous, CancellationToken ct) { // Validate if the token is valid. var botToken = BotToken.GetString(context.Properties); - if (botToken == null) - { - return IntegrationStatus.VerificationFailed; - } try { @@ -69,9 +66,9 @@ public async Task OnConfiguredAsync(IntegrationContext contex } catch { - return IntegrationStatus.VerificationFailed; + throw new ValidationException("The Discord bot token is invalid."); } - return IntegrationStatus.Verified; + return Task.FromResult(IntegrationStatus.Verified); } } diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs index 297ecfc9..4ff90725 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs @@ -1,14 +1,14 @@ -// ===================================================== +// ========================================================================== // Notifo.io // ========================================================================== // Copyright (c) Sebastian Stehle -// Author of the file: Artur Nowak // All rights reserved. Licensed under the MIT license. // ========================================================================== using Microsoft.Extensions.DependencyInjection; namespace Notifo.Domain.Integrations.Discord; + public static class DiscordServiceExtensions { public static IServiceCollection AddIntegrationDiscord(this IServiceCollection services) diff --git a/backend/src/Notifo.Domain/Channels/Messaging/MessagingChannel.cs b/backend/src/Notifo.Domain/Channels/Messaging/MessagingChannel.cs index e71c836e..b00d0862 100644 --- a/backend/src/Notifo.Domain/Channels/Messaging/MessagingChannel.cs +++ b/backend/src/Notifo.Domain/Channels/Messaging/MessagingChannel.cs @@ -262,7 +262,7 @@ private async Task SendCoreAsync(string appId, MessagingMessage Targets = lastJob.Configuration, // We might also format the text without the template if no primary template is defined. Text = text, - DetailedBodyText = lastJob.Notification.Formatting.Body, + Body = lastJob.Notification.Formatting.Body, ImageLarge = lastJob.Notification.Formatting.ImageLarge, ImageSmall = lastJob.Notification.Formatting.ImageSmall, LinkText = lastJob.Notification.Formatting.LinkText, diff --git a/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs b/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs index b5143dc2..4456412b 100644 --- a/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs +++ b/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs @@ -1,63 +1,77 @@ -using Microsoft.Extensions.Configuration; +// ========================================================================== +// Notifo.io +// ========================================================================== +// Copyright (c) Sebastian Stehle +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace Notifo.Domain.Integrations.Discord; + +[Trait("Category", "Dependencies")] public sealed class DiscordTests { + private readonly ResolvedIntegration sut; + + public DiscordTests() + { + sut = CreateClient(); + } + [Fact] public void Should_get_integration() { - var client = CreateClient(); - Assert.NotNull(client.System); + Assert.NotNull(sut.System); } [Fact] public async Task Should_send_simple_message() { - var client = CreateClient(); - + var userId = GetUserId(); var message = new MessagingMessage { Text = "Test message", + Targets = new Dictionary() { { DiscordIntegration.DiscordChatId, userId } } }; - var userId = GetUserId(); - AddTargets(message, userId); - - var result = await client.System.SendAsync(client.Context, message, default); + var result = await sut.System.SendAsync(sut.Context, message, default); Assert.Equal(DeliveryResult.Handled, result); } [Fact] - public async Task Send_full_message() + public async Task Should_send_full_message() { - var client = CreateClient(); + var userId = GetUserId(); var message = new MessagingMessage { Text = "Test message", - DetailedBodyText = "Detailed body text", + Body = "Detailed body text", + Targets = new Dictionary() { { DiscordIntegration.DiscordChatId, userId } } }; - var userId = GetUserId(); - AddTargets(message, userId); - var result = await client.System.SendAsync(client.Context, message, default); + var result = await sut.System.SendAsync(sut.Context, message, default); Assert.Equal(DeliveryResult.Handled, result); } [Fact] - public async Task Should_failed_on_user_without_app_installed() + public async Task Should_fail_on_user() { - var client = CreateClient(); - - var message = new MessagingMessage { Text = "Test message" }; + // Random 18-digit number + var random = new Random(); + string userId = string.Join(string.Empty, Enumerable.Range(0, 18).Select(number => random.Next(0, 9))); - var userId = "261155655006000000"; // Random userId - AddTargets(message, userId); + var message = new MessagingMessage + { + Text = "Test message", + Targets = new Dictionary() { { DiscordIntegration.DiscordChatId, userId } } + }; - var result = await client.System.SendAsync(client.Context, message, default); + var result = await sut.System.SendAsync(sut.Context, message, default); Assert.Equal(DeliveryStatus.Failed, result.Status); } @@ -65,18 +79,16 @@ public async Task Should_failed_on_user_without_app_installed() [Fact] public async Task Should_accept_images() { - var client = CreateClient(); - + var userId = GetUserId(); var message = new MessagingMessage { Text = "Test message", ImageSmall = "https://picsum.photos/200/300", - ImageLarge = "https://picsum.photos/400/600" + ImageLarge = "https://picsum.photos/400/600", + Targets = new Dictionary() { { DiscordIntegration.DiscordChatId, userId } } }; - var userId = GetUserId(); - AddTargets(message, userId); - var result = await client.System.SendAsync(client.Context, message, default); + var result = await sut.System.SendAsync(sut.Context, message, default); Assert.Equal(DeliveryResult.Handled, result); } @@ -84,22 +96,21 @@ public async Task Should_accept_images() [Fact] public async Task Should_accept_urls() { - var client = CreateClient(); + var userId = GetUserId(); var message = new MessagingMessage { Text = "Test message", LinkUrl = "https://notifo.io", - LinkText = "Notifo" + LinkText = "Notifo", + Targets = new Dictionary() { { DiscordIntegration.DiscordChatId, userId } } }; - var userId = GetUserId(); - AddTargets(message, userId); - var result = await client.System.SendAsync(client.Context, message, default); + var result = await sut.System.SendAsync(sut.Context, message, default); Assert.Equal(DeliveryResult.Handled, result); } - static ResolvedIntegration CreateClient() + private static ResolvedIntegration CreateClient() { var botToken = TestHelpers.Configuration.GetValue("discord:botToken")!; @@ -115,7 +126,6 @@ static ResolvedIntegration CreateClient() .BuildServiceProvider() .GetRequiredService(); - Assert.NotNull(integration); return new ResolvedIntegration(Guid.NewGuid().ToString(), context, integration); } @@ -123,20 +133,11 @@ private string GetUserId() { var id = TestHelpers.Configuration.GetValue("discord:userId"); - Assert.False(string.IsNullOrWhiteSpace(id), "Please set the Discord userId in the testing env"); + ArgumentException.ThrowIfNullOrEmpty(id, nameof(id)); return id; } - private MessagingMessage AddTargets(MessagingMessage message, string userId) - { - message.Targets = new Dictionary() - { - { DiscordIntegration.DiscordChatId, userId } - }; - return message; - } - - static IntegrationContext BuildContext(Dictionary properties) + private static IntegrationContext BuildContext(Dictionary properties) { return new IntegrationContext { diff --git a/backend/tests/Notifo.Domain.Tests/appsettings.json b/backend/tests/Notifo.Domain.Tests/appsettings.json index 7adcc6e0..2ee4103a 100644 --- a/backend/tests/Notifo.Domain.Tests/appsettings.json +++ b/backend/tests/Notifo.Domain.Tests/appsettings.json @@ -1,51 +1,50 @@ { - "sms": { - "to": "", - - "messageBird": { - "accessKey": "", - "phoneNumber": "", - "phoneNumbers": "" - }, - - "telekom": { - "apiKey": "", - "phoneNumber": "" - }, - - "twilio": { - "authToken": "", - "accountSid": "", - "phoneNumber": "" - } + "to": "", + + "messageBird": { + "accessKey": "", + "phoneNumber": "", + "phoneNumbers": "" + }, + + "telekom": { + "apiKey": "", + "phoneNumber": "" + }, + + "twilio": { + "authToken": "", + "accountSid": "", + "phoneNumber": "" + } }, "email": { - "address": "sebastian@squidex.io", - - "amazonSES": { - "host": "", - "username": "", - "password": "" - }, - - "mailchimp": { - "apiKey": "" - }, - - "mailjet": { - "apiKey": "", - "apiSecret": "" - }, - - "smtp": { - "host": "", - "username": "", - "password": "" - } + "address": "sebastian@squidex.io", + + "amazonSES": { + "host": "", + "username": "", + "password": "" + }, + + "mailchimp": { + "apiKey": "" + }, + + "mailjet": { + "apiKey": "", + "apiSecret": "" + }, + + "smtp": { + "host": "", + "username": "", + "password": "" + } }, "discord": { "botToken": "", "userId": "" } -} +} \ No newline at end of file From ffae14fb271e1c6ab0319cbc9f4630ffd280b505 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Fri, 28 Jun 2024 19:04:51 +0200 Subject: [PATCH 12/14] Add integration image --- media/Integrations.png | Bin 75638 -> 101877 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/media/Integrations.png b/media/Integrations.png index 34d356a6374032a2a66563e58078e8c0fddce32a..c104ab523da9b0728218396cccf439427c1b9e92 100644 GIT binary patch literal 101877 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 XmtaoNeY!OigO|ID7p-_>@S(o|q{3+v literal 75638 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\`qjnMmgQB)r&u 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 z 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 R8iZEO{rp8l{U5__{tM7b5HSD% From 4c603ddcec836f6062433e1f5e1e6690c202bc94 Mon Sep 17 00:00:00 2001 From: Arciiix Date: Sun, 30 Jun 2024 17:02:20 +0200 Subject: [PATCH 13/14] Apply code refactoring --- .../Discord/DiscordBotClientPool.cs | 7 +- .../Discord/DiscordIntegration.Messaging.cs | 10 ++- .../Discord/DiscordIntegration.cs | 1 - .../Discord/DiscordServiceExtensions.cs | 5 +- .../Integrations/Discord/DiscordTests.cs | 6 +- .../Notifo.Domain.Tests/appsettings.json | 90 +++++++++---------- 6 files changed, 59 insertions(+), 60 deletions(-) diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs index 5598cf7d..b78d59ab 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordBotClientPool.cs @@ -25,12 +25,7 @@ public async Task GetDiscordClient(string botToken, Cancellation { var client = new DiscordClient(); - // Sadly it can't receive the cancellation token. - // The LoginAsync method of DiscordRestClient is a wrapper over the internal ApiClient.LoginAsync function. - // That one accepts the RequestOptions parameter, which has a CancellationToken property. - // The problem is that the DiscordClient.LoginAsync function doesn't expose the RequestOptions parameter. - // We could use workarounds like WaitAsync, but it wouldn't interrupt the operation anyway. - // Killing the thread on the other hand would also be a bad idea and could cause some integrity issues. + // Method provides no option to pass CancellationToken await client.LoginAsync(TokenType.Bot, botToken); return client; diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs index a65ceba0..9203e9bd 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.Messaging.cs @@ -9,6 +9,7 @@ using Discord.Net; namespace Notifo.Domain.Integrations.Discord; + public sealed partial class DiscordIntegration : IMessagingSender { private const int Attempts = 5; @@ -25,7 +26,7 @@ public void AddTargets(IDictionary targets, UserInfo user) } public async Task SendAsync(IntegrationContext context, MessagingMessage message, - CancellationToken ct) + CancellationToken ct) { if (!message.Targets.TryGetValue(DiscordChatId, out var chatId)) { @@ -47,7 +48,12 @@ private async Task SendMessageAsync(IntegrationContext context, var client = await discordBotClientPool.GetDiscordClient(botToken, ct); var requestOptions = new RequestOptions { CancelToken = ct }; - var user = await client.GetUserAsync(ulong.Parse(chatId), CacheMode.AllowDownload, requestOptions); + if (!ulong.TryParse(chatId, out var chatIdParsed)) + { + throw new InvalidOperationException("Invalid Discord DM chat ID."); + } + + var user = await client.GetUserAsync(chatIdParsed, CacheMode.AllowDownload, requestOptions); if (user is null) { throw new InvalidOperationException("User not found."); diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs index 103384de..09736b4d 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordIntegration.cs @@ -57,7 +57,6 @@ public DiscordIntegration(DiscordBotClientPool discordBotClientPool) public Task OnConfiguredAsync(IntegrationContext context, IntegrationConfiguration? previous, CancellationToken ct) { - // Validate if the token is valid. var botToken = BotToken.GetString(context.Properties); try diff --git a/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs b/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs index 4ff90725..f9ea72fc 100644 --- a/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs +++ b/backend/src/Notifo.Domain.Integrations/Discord/DiscordServiceExtensions.cs @@ -5,9 +5,10 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Microsoft.Extensions.DependencyInjection; +using Notifo.Domain.Integrations; +using Notifo.Domain.Integrations.Discord; -namespace Notifo.Domain.Integrations.Discord; +namespace Microsoft.Extensions.DependencyInjection; public static class DiscordServiceExtensions { diff --git a/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs b/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs index 4456412b..cfb102fd 100644 --- a/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs +++ b/backend/tests/Notifo.Domain.Tests/Integrations/Discord/DiscordTests.cs @@ -45,7 +45,6 @@ public async Task Should_send_simple_message() public async Task Should_send_full_message() { var userId = GetUserId(); - var message = new MessagingMessage { Text = "Test message", @@ -97,7 +96,6 @@ public async Task Should_accept_images() public async Task Should_accept_urls() { var userId = GetUserId(); - var message = new MessagingMessage { Text = "Test message", @@ -105,6 +103,7 @@ public async Task Should_accept_urls() LinkText = "Notifo", Targets = new Dictionary() { { DiscordIntegration.DiscordChatId, userId } } }; + var result = await sut.System.SendAsync(sut.Context, message, default); Assert.Equal(DeliveryResult.Handled, result); @@ -113,7 +112,6 @@ public async Task Should_accept_urls() private static ResolvedIntegration CreateClient() { var botToken = TestHelpers.Configuration.GetValue("discord:botToken")!; - var context = BuildContext(new Dictionary { [DiscordIntegration.BotToken.Name] = botToken, @@ -132,8 +130,8 @@ private static ResolvedIntegration CreateClient() private string GetUserId() { var id = TestHelpers.Configuration.GetValue("discord:userId"); - ArgumentException.ThrowIfNullOrEmpty(id, nameof(id)); + return id; } diff --git a/backend/tests/Notifo.Domain.Tests/appsettings.json b/backend/tests/Notifo.Domain.Tests/appsettings.json index 2ee4103a..1244ff9b 100644 --- a/backend/tests/Notifo.Domain.Tests/appsettings.json +++ b/backend/tests/Notifo.Domain.Tests/appsettings.json @@ -1,50 +1,50 @@ { - "sms": { - "to": "", - - "messageBird": { - "accessKey": "", - "phoneNumber": "", - "phoneNumbers": "" - }, - - "telekom": { - "apiKey": "", - "phoneNumber": "" - }, - - "twilio": { - "authToken": "", - "accountSid": "", - "phoneNumber": "" - } + "sms": { + "to": "", + + "messageBird": { + "accessKey": "", + "phoneNumber": "", + "phoneNumbers": "" }, - "email": { - "address": "sebastian@squidex.io", - - "amazonSES": { - "host": "", - "username": "", - "password": "" - }, - - "mailchimp": { - "apiKey": "" - }, - - "mailjet": { - "apiKey": "", - "apiSecret": "" - }, - - "smtp": { - "host": "", - "username": "", - "password": "" - } + + "telekom": { + "apiKey": "", + "phoneNumber": "" }, - "discord": { - "botToken": "", - "userId": "" + + "twilio": { + "authToken": "", + "accountSid": "", + "phoneNumber": "" } + }, + "email": { + "address": "sebastian@squidex.io", + + "amazonSES": { + "host": "", + "username": "", + "password": "" + }, + + "mailchimp": { + "apiKey": "" + }, + + "mailjet": { + "apiKey": "", + "apiSecret": "" + }, + + "smtp": { + "host": "", + "username": "", + "password": "" + } + }, + "discord": { + "botToken": "", + "userId": "" + } } \ No newline at end of file From ce06ed4b1e76fd3df23180c6768b18ad5742ff9d Mon Sep 17 00:00:00 2001 From: Arciiix Date: Sun, 30 Jun 2024 17:04:24 +0200 Subject: [PATCH 14/14] Add a new line at the end of file --- .../Notifo.Domain.Tests/appsettings.json | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/backend/tests/Notifo.Domain.Tests/appsettings.json b/backend/tests/Notifo.Domain.Tests/appsettings.json index 1244ff9b..5c70276b 100644 --- a/backend/tests/Notifo.Domain.Tests/appsettings.json +++ b/backend/tests/Notifo.Domain.Tests/appsettings.json @@ -1,50 +1,50 @@ { - "sms": { - "to": "", + "sms": { + "to": "", - "messageBird": { - "accessKey": "", - "phoneNumber": "", - "phoneNumbers": "" - }, + "messageBird": { + "accessKey": "", + "phoneNumber": "", + "phoneNumbers": "" + }, + + "telekom": { + "apiKey": "", + "phoneNumber": "" + }, - "telekom": { - "apiKey": "", - "phoneNumber": "" + "twilio": { + "authToken": "", + "accountSid": "", + "phoneNumber": "" + } }, + "email": { + "address": "sebastian@squidex.io", - "twilio": { - "authToken": "", - "accountSid": "", - "phoneNumber": "" - } - }, - "email": { - "address": "sebastian@squidex.io", + "amazonSES": { + "host": "", + "username": "", + "password": "" + }, - "amazonSES": { - "host": "", - "username": "", - "password": "" - }, + "mailchimp": { + "apiKey": "" + }, - "mailchimp": { - "apiKey": "" - }, + "mailjet": { + "apiKey": "", + "apiSecret": "" + }, - "mailjet": { - "apiKey": "", - "apiSecret": "" + "smtp": { + "host": "", + "username": "", + "password": "" + } }, - - "smtp": { - "host": "", - "username": "", - "password": "" + "discord": { + "botToken": "", + "userId": "" } - }, - "discord": { - "botToken": "", - "userId": "" - } -} \ No newline at end of file +}