Enhance Telegram notification system with optional link support
CI / Backend (build + test) (push) Successful in 1m16s
CI / Frontend (lint + typecheck + build) (push) Successful in 30s

- Updated NotifyUserAsync method in TelegramNotifier to accept an optional linkPath parameter for dynamic URL generation.
- Modified various command handlers to utilize the new linkPath feature, providing users with relevant links in their notifications.
- Adjusted ITelegramNotifier interface documentation to reflect the changes in method signature and functionality.
- Enhanced unit tests to verify the correct invocation of the updated NotifyUserAsync method.
This commit is contained in:
Leonid Pershin
2026-07-14 07:36:18 +03:00
parent df137ca5a7
commit d26723dce0
14 changed files with 34 additions and 15 deletions
@@ -61,6 +61,7 @@ public sealed class ApproveActivationCommandHandler(
await telegramNotifier.NotifyUserAsync(
request.UserId,
"✅ Ваш аккаунт активирован администратором.",
null,
cancellationToken
);
return Result.Success();
@@ -82,6 +82,7 @@ public sealed class ApproveRoleRequestCommandHandler(
await telegramNotifier.NotifyUserAsync(
ticket.UserId,
"✅ Ваша заявка на роль одобрена.",
$"/support?ticket={ticket.Id}",
cancellationToken
);
@@ -51,6 +51,7 @@ public sealed class CloseTicketCommandHandler(
await telegramNotifier.NotifyUserAsync(
ticket.UserId,
"🔒 Ваше обращение закрыто.",
$"/support?ticket={ticket.Id}",
cancellationToken
);
@@ -57,6 +57,7 @@ public sealed class RejectRoleRequestCommandHandler(
await telegramNotifier.NotifyUserAsync(
ticket.UserId,
"❌ Ваша заявка на роль отклонена.",
$"/support?ticket={ticket.Id}",
cancellationToken
);
@@ -51,6 +51,7 @@ public sealed class ResolveTicketCommandHandler(
await telegramNotifier.NotifyUserAsync(
ticket.UserId,
"✅ Ваше обращение решено.",
$"/support?ticket={ticket.Id}",
cancellationToken
);
@@ -91,6 +91,7 @@ public sealed class BlockUserCommandHandler(
await telegramNotifier.NotifyUserAsync(
command.UserId,
"⛔ Ваш аккаунт заблокирован администратором.",
null,
cancellationToken
);
@@ -66,6 +66,7 @@ public sealed class DeleteUserCommandHandler(
await telegramNotifier.NotifyUserAsync(
command.UserId,
"🗑 Ваш аккаунт удалён администратором.",
null,
cancellationToken
);
@@ -71,6 +71,7 @@ public sealed class ForceRevokeConfigCommandHandler(
await telegramNotifier.NotifyUserAsync(
config.UserId,
$"⚠️ Администратор отозвал ваш конфиг «{config.Label ?? config.ClientEmail}».",
null,
cancellationToken
);
@@ -17,8 +17,9 @@ public interface ITelegramNotifier
);
/// <summary>Личное сообщение пользователю, если у него привязан Telegram (иначе no-op).
/// Если задан PublicSiteUrl — добавляет кнопку-ссылку на сайт.</summary>
Task NotifyUserAsync(Guid userId, string message, CancellationToken cancellationToken);
/// Если задан PublicSiteUrl — добавляет кнопку-ссылку на сайт; linkPath — относительный путь
/// (например "/support?ticket={id}"), на который она ведёт, null — на корень сайта.</summary>
Task NotifyUserAsync(Guid userId, string message, string? linkPath, CancellationToken cancellationToken);
/// <summary>Баг-репорт/предложение — только кнопка-ссылка на сайт (переписка и картинки — там),
/// без инлайн-действий.</summary>