nazarovsa/main_menu (#8)

Reviewed-on: #8
Co-authored-by: Sergey Nazarov <insight.appdev@gmail.com>
Co-committed-by: Sergey Nazarov <insight.appdev@gmail.com>
This commit is contained in:
Sergey Nazarov 2024-04-19 19:43:07 +00:00 committed by nazarovsa
parent 581492a1da
commit 3a91d41443
20 changed files with 203 additions and 115 deletions

View File

@ -23,8 +23,10 @@ public class NocrCallbackData : CallbackData<NocrState>
return new NocrCallbackData(NocrState.DeleteSubscription, subscriptionId.ToString()); return new NocrCallbackData(NocrState.DeleteSubscription, subscriptionId.ToString());
} }
public static NocrCallbackData ViewSubscription(long subscriptionId) public static NocrCallbackData ViewSubscription(long? subscriptionId = null)
{ {
return new NocrCallbackData(NocrState.ViewSubscription, subscriptionId.ToString()); return subscriptionId.HasValue ?
new NocrCallbackData(NocrState.ViewSubscription, subscriptionId.Value.ToString()):
new NocrCallbackData(NocrState.ViewSubscription);
} }
} }

View File

@ -4,9 +4,10 @@ public enum NocrState
{ {
// Commands // Commands
ActivateSubscription = 1, ActivateSubscription = 1,
DeactivateSubscription = 2, DeactivateSubscription,
DeleteSubscription = 3, DeleteSubscription,
// States // States
ViewSubscription = 4 Start,
ViewSubscription
} }

View File

@ -0,0 +1,69 @@
using Insight.Localizer;
using Insight.TelegramBot;
using Insight.TelegramBot.Keyboards;
using Insight.TelegramBot.Models;
using Nocr.TelegramClient.AppServices.Bots;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Nocr.TelegramClient.AppServices.Handlers.Messages.StartMessage;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
using Telegram.Bot.Types.ReplyMarkups;
namespace Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
public abstract class StartHandlerBase
{
protected IBot Bot { get; }
protected ILocalizer Localizer { get; }
protected IMessageDispatcherQueue MessageQueue { get; }
public StartHandlerBase(ILocalizer localizer, IMessageDispatcherQueue messageQueue, IBot bot)
{
Bot = bot ?? throw new ArgumentNullException(nameof(bot));
Localizer = localizer ?? throw new ArgumentNullException(nameof(localizer));
MessageQueue = messageQueue ?? throw new ArgumentNullException(nameof(messageQueue));
}
public Task Handle(Update update, CancellationToken cancellationToken = default)
{
long telegramId;
switch (update.Type)
{
case UpdateType.Message:
telegramId = update.Message.From.Id;
break;
case UpdateType.CallbackQuery:
telegramId = update.CallbackQuery.From.Id;
break;
default:
throw new ArgumentOutOfRangeException(nameof(update.Type), "Unsupported update type");
}
var message = new TextMessage(telegramId)
{
Text = Localizer.Get(nameof(StartMessageHandler), "Text"),
ParseMode = ParseMode.Html,
ReplyMarkup = GetKeyboard()
};
if (update.Type == UpdateType.CallbackQuery)
{
return Bot.EditMessageTextAsync(update.CallbackQuery.Message.MessageId, message, cancellationToken);
}
MessageQueue.Enqueue(message);
return Task.CompletedTask;
}
private IReplyMarkup GetKeyboard()
{
var markup = new VerticalKeyboardMarkup();
markup.Add(new InlineKeyboardButton(Localizer.Get(nameof(StartMessageHandler), "SubscriptionsButton"))
{
CallbackData = NocrCallbackData.ViewSubscription().ToString()
});
return markup.InlineKeyboardMarkup;
}
}

View File

@ -7,6 +7,7 @@ using Microsoft.Extensions.Logging;
using Nocr.TelegramClient.AppServices.Bots; using Nocr.TelegramClient.AppServices.Bots;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher; using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Nocr.TelegramClient.AppServices.TextSubscriptions; using Nocr.TelegramClient.AppServices.TextSubscriptions;
using Nocr.TelegramClient.AppServices.Users;
using Nocr.TextMatcher.Api.Contracts.TextMatches; using Nocr.TextMatcher.Api.Contracts.TextMatches;
using Nocr.TextMatcher.Api.Contracts.TextMatches.Dto; using Nocr.TextMatcher.Api.Contracts.TextMatches.Dto;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
@ -16,6 +17,7 @@ namespace Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
public abstract class ViewSubscriptionHandlerBase public abstract class ViewSubscriptionHandlerBase
{ {
protected IUsersService UsersService { get; }
protected ILogger Logger { get; } protected ILogger Logger { get; }
protected IBot Bot { get; } protected IBot Bot { get; }
protected ITextSubscriptionsController SubscriptionsController { get; } protected ITextSubscriptionsController SubscriptionsController { get; }
@ -23,8 +25,9 @@ public abstract class ViewSubscriptionHandlerBase
protected IMessageDispatcherQueue MessageQueue { get; } protected IMessageDispatcherQueue MessageQueue { get; }
protected ViewSubscriptionHandlerBase(ILogger logger, ILocalizer localizer, IMessageDispatcherQueue messageQueue, protected ViewSubscriptionHandlerBase(ILogger logger, ILocalizer localizer, IMessageDispatcherQueue messageQueue,
IBot bot, ITextSubscriptionsController subscriptionsController) IBot bot, IUsersService usersService, ITextSubscriptionsController subscriptionsController)
{ {
UsersService = usersService ?? throw new ArgumentNullException(nameof(usersService));
Logger = logger ?? throw new ArgumentNullException(nameof(logger)); Logger = logger ?? throw new ArgumentNullException(nameof(logger));
Bot = bot ?? throw new ArgumentNullException(nameof(bot)); Bot = bot ?? throw new ArgumentNullException(nameof(bot));
SubscriptionsController = SubscriptionsController =
@ -33,26 +36,53 @@ public abstract class ViewSubscriptionHandlerBase
MessageQueue = messageQueue ?? throw new ArgumentNullException(nameof(messageQueue)); MessageQueue = messageQueue ?? throw new ArgumentNullException(nameof(messageQueue));
} }
public async Task SendSubscriptionMessage(long receiverId, TextSubscriptionData subscription, public async Task SendSubscriptionMessage(long receiverId, long? subscriptionId,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var message = await GetMessage(receiverId, subscription, cancellationToken); var message = await GetMessage(receiverId, subscriptionId, cancellationToken);
MessageQueue.Enqueue(message); MessageQueue.Enqueue(message);
} }
public async Task EditSubscriptionMessage(long receiverId, int messageId, long subscriptionId, public async Task EditSubscriptionMessage(long receiverId, int messageId, long? subscriptionId,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var subscription = await SubscriptionsController.GetById(subscriptionId, cancellationToken); var message = await GetMessage(receiverId, subscriptionId, cancellationToken);
var message = await GetMessage(receiverId, subscription, cancellationToken);
await Bot.EditOrSendTextMessage(messageId, message, Logger, cancellationToken); await Bot.EditOrSendTextMessage(messageId, message, Logger, cancellationToken);
} }
private async Task<TextMessage> GetMessage(long receiverId, TextSubscriptionData subscription, private async Task<TextMessage> GetMessage(long receiverId, long? subscriptionId,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var subscriptions = await SubscriptionsController.GetByUserId(subscription.UserId, cancellationToken); // note(nazarovsa): Works only if receiverId is if of an user. If channel - refactor arguments
var user = await UsersService.GetByIdentity(receiverId, cancellationToken);
if (user == null)
{
throw new NotImplementedException($"User with telegramId {receiverId} not found");
}
var subscriptions = await SubscriptionsController.GetByUserId(user.Id, cancellationToken);
if (!subscriptions.Any())
{
throw new NotImplementedException($"There is no subscriptions for user with id {user.Id}");
}
var ordered = subscriptions.OrderBy(x => x.Id).ToList(); var ordered = subscriptions.OrderBy(x => x.Id).ToList();
TextSubscriptionData? subscription = null;
if (subscriptionId.HasValue)
{
subscription = subscriptions.FirstOrDefault(x => x.Id == subscriptionId.Value);
if (subscription == null)
{
throw new NotImplementedException($"Subscription with id {subscriptionId.Value} not found");
}
}
else
{
subscription = ordered.First();
}
var indexOf = ordered.FindIndex(x => x.Id == subscription.Id); var indexOf = ordered.FindIndex(x => x.Id == subscription.Id);
long? prevId = indexOf > 0 ? ordered[indexOf - 1].Id : null; long? prevId = indexOf > 0 ? ordered[indexOf - 1].Id : null;
long? nextId = indexOf < ordered.Count - 1 ? ordered[indexOf + 1].Id : null; long? nextId = indexOf < ordered.Count - 1 ? ordered[indexOf + 1].Id : null;
@ -95,7 +125,7 @@ public abstract class ViewSubscriptionHandlerBase
var deleteButtonText = Localizer.Get("Buttons", "Delete"); var deleteButtonText = Localizer.Get("Buttons", "Delete");
var markup = new VerticalKeyboardMarkup(); var markup = new VerticalKeyboardMarkup();
var row = new List<InlineKeyboardButton>(2); var row = new List<InlineKeyboardButton>(2);
if (prevId.HasValue) if (prevId.HasValue)
{ {
@ -122,10 +152,14 @@ public abstract class ViewSubscriptionHandlerBase
? NocrCallbackData.DeactivateSubscription(textSubscription.Id).ToString() ? NocrCallbackData.DeactivateSubscription(textSubscription.Id).ToString()
: NocrCallbackData.ActivateSubscription(textSubscription.Id).ToString() : NocrCallbackData.ActivateSubscription(textSubscription.Id).ToString()
}); });
markup.Add(new InlineKeyboardButton(deleteButtonText) markup.Add(new InlineKeyboardButton(deleteButtonText)
{ CallbackData = NocrCallbackData.DeleteSubscription(textSubscription.Id).ToString() }); { CallbackData = NocrCallbackData.DeleteSubscription(textSubscription.Id).ToString() });
markup.Add(new InlineKeyboardButton(Localizer.Get("Buttons", "Back"))
{
CallbackData = new NocrCallbackData(NocrState.Start).ToString()
});
return markup; return markup;
} }

View File

@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
using Nocr.TelegramClient.AppServices.Bots; using Nocr.TelegramClient.AppServices.Bots;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher; using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers; using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
using Nocr.TelegramClient.AppServices.Users;
using Nocr.TextMatcher.Api.Contracts.TextMatches; using Nocr.TextMatcher.Api.Contracts.TextMatches;
using Telegram.Bot.Types; using Telegram.Bot.Types;
@ -17,8 +18,9 @@ public class ActivateSubscriptionHandler : ViewSubscriptionHandlerBase, IMatchin
ILocalizer localizer, ILocalizer localizer,
IMessageDispatcherQueue messageQueue, IMessageDispatcherQueue messageQueue,
IBot bot, IBot bot,
IUsersService usersService,
ITextSubscriptionsController subscriptionsController) ITextSubscriptionsController subscriptionsController)
: base(logger, localizer, messageQueue, bot, subscriptionsController) : base(logger, localizer, messageQueue, bot, usersService, subscriptionsController)
{ {
} }

View File

@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
using Nocr.TelegramClient.AppServices.Bots; using Nocr.TelegramClient.AppServices.Bots;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher; using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers; using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
using Nocr.TelegramClient.AppServices.Users;
using Nocr.TextMatcher.Api.Contracts.TextMatches; using Nocr.TextMatcher.Api.Contracts.TextMatches;
using Telegram.Bot.Types; using Telegram.Bot.Types;
@ -19,8 +20,9 @@ public class DeactivateSubscriptionHandler : ViewSubscriptionHandlerBase,
ILocalizer localizer, ILocalizer localizer,
IMessageDispatcherQueue messageQueue, IMessageDispatcherQueue messageQueue,
IBot bot, IBot bot,
IUsersService usersService,
ITextSubscriptionsController subscriptionsController) ITextSubscriptionsController subscriptionsController)
: base(logger, localizer, messageQueue, bot, subscriptionsController) : base(logger, localizer, messageQueue, bot, usersService, subscriptionsController)
{ {
} }

View File

@ -8,8 +8,10 @@ using Nocr.TelegramClient.AppServices.Bots;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher; using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers; using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
using Nocr.TelegramClient.AppServices.Handlers.CallbackQueries.DeactivateSubscription; using Nocr.TelegramClient.AppServices.Handlers.CallbackQueries.DeactivateSubscription;
using Nocr.TelegramClient.AppServices.Users;
using Nocr.TextMatcher.Api.Contracts.TextMatches; using Nocr.TextMatcher.Api.Contracts.TextMatches;
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegram.Bot.Types.ReplyMarkups;
namespace Nocr.TelegramClient.AppServices.Handlers.CallbackQueries.DeleteSubscription; namespace Nocr.TelegramClient.AppServices.Handlers.CallbackQueries.DeleteSubscription;
@ -20,8 +22,9 @@ public class DeleteSubscriptionHandler : ViewSubscriptionHandlerBase,
ILocalizer localizer, ILocalizer localizer,
IMessageDispatcherQueue messageQueue, IMessageDispatcherQueue messageQueue,
IBot bot, IBot bot,
ITextSubscriptionsController subscriptionsController) IUsersService usersService,
: base(logger, localizer, messageQueue, bot, subscriptionsController) ITextSubscriptionsController subscriptionsController)
: base(logger, localizer, messageQueue, bot, usersService, subscriptionsController)
{ {
} }
@ -53,10 +56,16 @@ public class DeleteSubscriptionHandler : ViewSubscriptionHandlerBase,
var message = new TextMessage(from) var message = new TextMessage(from)
{ {
Text = Localizer.Get(nameof(DeleteSubscriptionHandler), "Text") Text = Localizer.Get(nameof(DeleteSubscriptionHandler), "Text")
.FormatWith(new { Id = subscriptionId }) .FormatWith(new { Id = subscriptionId }),
ReplyMarkup = new InlineKeyboardMarkup(
new InlineKeyboardButton(Localizer.Get("Buttons", "Back"))
{
CallbackData = NocrCallbackData.ViewSubscription().ToString()
})
}; };
await Bot.EditOrSendTextMessage(update.CallbackQuery.Message.MessageId, message, Logger, CancellationToken.None); await Bot.EditOrSendTextMessage(update.CallbackQuery.Message.MessageId, message, Logger,
CancellationToken.None);
} }
private void SendErrorMessage(long from) private void SendErrorMessage(long from)

View File

@ -0,0 +1,15 @@
using Insight.Localizer;
using Insight.TelegramBot;
using Insight.TelegramBot.Handling.Handlers;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
namespace Nocr.TelegramClient.AppServices.Handlers.CallbackQueries.Start;
public class StartHandler : StartHandlerBase, IMatchingUpdateHandler<StartMatcher>
{
public StartHandler(ILocalizer localizer, IMessageDispatcherQueue messageQueue, IBot bot)
: base(localizer, messageQueue, bot)
{
}
}

View File

@ -0,0 +1,12 @@
using Insight.TelegramBot.Handling.Matchers.CallbackQueryMatchers;
using Nocr.TelegramClient.AppServices.Bots;
namespace Nocr.TelegramClient.AppServices.Handlers.CallbackQueries.Start;
public class StartMatcher : StateCallbackQueryMatcher<NocrState>
{
public StartMatcher()
{
ExpectingState = NocrState.Start;
}
}

View File

@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
using Nocr.TelegramClient.AppServices.Bots; using Nocr.TelegramClient.AppServices.Bots;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher; using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers; using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
using Nocr.TelegramClient.AppServices.Users;
using Nocr.TextMatcher.Api.Contracts.TextMatches; using Nocr.TextMatcher.Api.Contracts.TextMatches;
using Telegram.Bot.Types; using Telegram.Bot.Types;
@ -17,8 +18,9 @@ public class ViewSubscriptionHandler : ViewSubscriptionHandlerBase, IMatchingUpd
ILocalizer localizer, ILocalizer localizer,
IMessageDispatcherQueue messageQueue, IMessageDispatcherQueue messageQueue,
IBot bot, IBot bot,
IUsersService usersService,
ITextSubscriptionsController subscriptionsController) : ITextSubscriptionsController subscriptionsController) :
base(logger, localizer, messageQueue, bot, subscriptionsController) base(logger, localizer, messageQueue, bot, usersService, subscriptionsController)
{ {
} }
@ -27,13 +29,10 @@ public class ViewSubscriptionHandler : ViewSubscriptionHandlerBase, IMatchingUpd
var callbackData = NocrCallbackData.Parse(update.CallbackQuery.Data); var callbackData = NocrCallbackData.Parse(update.CallbackQuery.Data);
var from = update.CallbackQuery.From.Id; var from = update.CallbackQuery.From.Id;
if (callbackData.Args.Count != 1 || !long.TryParse(callbackData.Args.First(), out var subscriptionId)) long? subscriptionId = null;
if (callbackData.Args.Count != 0 && long.TryParse(callbackData.Args.First(), out var subscriptionIdFromMessage))
{ {
Logger.LogWarning( subscriptionId = subscriptionIdFromMessage;
"Не удалось извлечь идентификатор подписки. CallbackData: {@CallbackData}, ChatId: {ChatId}, MessageId {MessageId}",
callbackData, from, update.CallbackQuery.Message.Chat.Id);
SendErrorMessage(from);
return;
} }
await EditSubscriptionMessage(from, update.CallbackQuery.Message.MessageId, subscriptionId, cancellationToken); await EditSubscriptionMessage(from, update.CallbackQuery.Message.MessageId, subscriptionId, cancellationToken);

View File

@ -1,33 +1,16 @@
using Insight.Localizer; using Insight.Localizer;
using Insight.TelegramBot;
using Insight.TelegramBot.Handling.Handlers; using Insight.TelegramBot.Handling.Handlers;
using Insight.TelegramBot.Models;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher; using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Telegram.Bot.Types; using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
using Telegram.Bot.Types.Enums;
namespace Nocr.TelegramClient.AppServices.Handlers.Messages.StartMessage; namespace Nocr.TelegramClient.AppServices.Handlers.Messages.StartMessage;
public class StartMessageHandler : IMatchingUpdateHandler<StartMessageMatcher>
public class StartMessageHandler : StartHandlerBase, IMatchingUpdateHandler<StartMessageMatcher>
{ {
private readonly ILocalizer _localizer; public StartMessageHandler(ILocalizer localizer, IMessageDispatcherQueue messageQueue, IBot bot)
private readonly IMessageDispatcherQueue _messageQueue; :base(localizer, messageQueue, bot)
public StartMessageHandler(ILocalizer localizer, IMessageDispatcherQueue messageQueue)
{ {
_localizer = localizer ?? throw new ArgumentNullException(nameof(localizer));
_messageQueue = messageQueue ?? throw new ArgumentNullException(nameof(messageQueue));
}
public Task Handle(Update update, CancellationToken cancellationToken = default)
{
var telegramId = update.Message.From.Id;
var message = new TextMessage(telegramId)
{
Text = _localizer.Get(nameof(StartMessageHandler), "Text"),
ParseMode = ParseMode.Html
};
_messageQueue.Enqueue(message);
return Task.CompletedTask;
} }
} }

View File

@ -17,8 +17,6 @@ namespace Nocr.TelegramClient.AppServices.Handlers.Messages.SubscribeMessage;
public class SubscribeMessageHandler : ViewSubscriptionHandlerBase, IMatchingUpdateHandler<SubscribeMessageMatcher> public class SubscribeMessageHandler : ViewSubscriptionHandlerBase, IMatchingUpdateHandler<SubscribeMessageMatcher>
{ {
private readonly IUsersService _usersService;
/// <summary> /// <summary>
/// Regex to match command "/subscribe @username match_type keywords". <br/> /// Regex to match command "/subscribe @username match_type keywords". <br/>
/// For instance, "/subscribe @baraholka 1 обувь ботинки сапоги" will create match for a current user with type "All" and pattern "обувь ботинки сапоги". /// For instance, "/subscribe @baraholka 1 обувь ботинки сапоги" will create match for a current user with type "All" and pattern "обувь ботинки сапоги".
@ -34,9 +32,8 @@ public class SubscribeMessageHandler : ViewSubscriptionHandlerBase, IMatchingUpd
IUsersService usersService, IUsersService usersService,
IBot bot, IBot bot,
ITextSubscriptionsController subscriptionsController) ITextSubscriptionsController subscriptionsController)
: base(logger, localizer, messageQueue, bot, subscriptionsController) : base(logger, localizer, messageQueue, bot, usersService, subscriptionsController)
{ {
_usersService = usersService ?? throw new ArgumentNullException(nameof(usersService));
} }
public async Task Handle(Update update, CancellationToken cancellationToken = default) public async Task Handle(Update update, CancellationToken cancellationToken = default)
@ -65,7 +62,7 @@ public class SubscribeMessageHandler : ViewSubscriptionHandlerBase, IMatchingUpd
var template = match.Groups[3].Value; var template = match.Groups[3].Value;
var user = await _usersService.GetOrCreate(receiverId, update.Message.From.Username, cancellationToken); var user = await UsersService.GetOrCreate(receiverId, update.Message.From.Username, cancellationToken);
var subscriptionId = await SubscriptionsController.Create(new CreateTextSubscriptionRequest var subscriptionId = await SubscriptionsController.Create(new CreateTextSubscriptionRequest
{ {
UserId = user.Id, UserId = user.Id,
@ -80,7 +77,6 @@ public class SubscribeMessageHandler : ViewSubscriptionHandlerBase, IMatchingUpd
.FormatWith(new { Id = subscriptionId }) .FormatWith(new { Id = subscriptionId })
}); });
var subscription = await SubscriptionsController.GetById(subscriptionId, CancellationToken.None); await SendSubscriptionMessage(receiverId, subscriptionId, CancellationToken.None);
await SendSubscriptionMessage(receiverId, subscription, CancellationToken.None);
} }
} }

View File

@ -1,40 +0,0 @@
using Insight.Localizer;
using Insight.TelegramBot;
using Insight.TelegramBot.Handling.Handlers;
using Microsoft.Extensions.Logging;
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
using Nocr.TelegramClient.AppServices.Handlers.BaseHandlers;
using Nocr.TelegramClient.AppServices.Users;
using Nocr.TextMatcher.Api.Contracts.TextMatches;
using Telegram.Bot.Types;
namespace Nocr.TelegramClient.AppServices.Handlers.Messages.SubscriptionsMessage;
public class SubscriptionsMessageHandler : ViewSubscriptionHandlerBase,
IMatchingUpdateHandler<SubscriptionsMessageMatcher>
{
private readonly IUsersService _usersService;
public SubscriptionsMessageHandler(
ILogger<SubscriptionsMessageHandler> logger,
ILocalizer localizer,
IMessageDispatcherQueue messageQueue,
IUsersService usersService,
IBot bot,
ITextSubscriptionsController subscriptionsController)
: base(logger, localizer, messageQueue, bot, subscriptionsController)
{
_usersService = usersService ?? throw new ArgumentNullException(nameof(usersService));
}
public async Task Handle(Update update, CancellationToken cancellationToken = default)
{
var telegramId = update.Message.From.Id;
var user = await _usersService.GetOrCreate(telegramId, update.Message.From.Username, cancellationToken);
var subscriptions = await SubscriptionsController.GetByUserId(user.Id, cancellationToken);
var subscription = subscriptions.MinBy(x => x.Id);
await SendSubscriptionMessage(telegramId, subscription, CancellationToken.None);
}
}

View File

@ -1,11 +0,0 @@
using Insight.TelegramBot.Handling.Matchers.TextMatchers;
namespace Nocr.TelegramClient.AppServices.Handlers.Messages.SubscriptionsMessage;
public class SubscriptionsMessageMatcher : TextStartWithUpdateMatcher
{
public SubscriptionsMessageMatcher()
{
Template = "/subscriptions";
}
}

View File

@ -5,6 +5,8 @@ namespace Nocr.TelegramClient.AppServices.Users;
public interface IUsersService public interface IUsersService
{ {
public Task<UserData> GetOrCreate(long telegramId, string? username, CancellationToken cancellationToken = default); public Task<UserData> GetOrCreate(long telegramId, string? username, CancellationToken cancellationToken = default);
public Task<UserData?> GetByIdentity(long telegramId, CancellationToken cancellationToken = default);
public Task<UserData?> GetById(long id, CancellationToken cancellationToken = default); public Task<UserData?> GetById(long id, CancellationToken cancellationToken = default);
} }

View File

@ -13,9 +13,11 @@ public sealed class UsersService : IUsersService
_usersController = usersController ?? throw new ArgumentNullException(nameof(usersController)); _usersController = usersController ?? throw new ArgumentNullException(nameof(usersController));
} }
public async Task<UserData> GetOrCreate(long telegramId, string? username, CancellationToken cancellationToken = default) public async Task<UserData> GetOrCreate(long telegramId, string? username,
CancellationToken cancellationToken = default)
{ {
var user = await _usersController.GetByIdentity(UserIdentityType.TelegramId, telegramId.ToString(), cancellationToken); var user = await _usersController.GetByIdentity(UserIdentityType.TelegramId, telegramId.ToString(),
cancellationToken);
if (user == null) if (user == null)
{ {
await _usersController.Create(new CreateUserRequest await _usersController.Create(new CreateUserRequest
@ -32,6 +34,11 @@ public sealed class UsersService : IUsersService
return user; return user;
} }
public Task<UserData?> GetByIdentity(long telegramId, CancellationToken cancellationToken = default)
{
return _usersController.GetByIdentity(UserIdentityType.TelegramId, telegramId.ToString(), cancellationToken);
}
public Task<UserData?> GetById(long id, CancellationToken cancellationToken = default) public Task<UserData?> GetById(long id, CancellationToken cancellationToken = default)
{ {
return _usersController.GetById(id, cancellationToken); return _usersController.GetById(id, cancellationToken);

View File

@ -25,5 +25,9 @@
<Content Include="Resources" /> <Content Include="Resources" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="Resources\Handlers\TelegramHandlers\Messages\StartMessage\StartMessageHandler.ru-ru.json" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,5 @@
{
"Text": "Привет! Я, Nocr 🤖!",
"SubscriptionsButton": "Подписки 📩"
}