Add feedback (#9)
Reviewed-on: #9 Co-authored-by: Sergey Nazarov <insight.appdev@gmail.com> Co-committed-by: Sergey Nazarov <insight.appdev@gmail.com>
This commit is contained in:
parent
82b3de207b
commit
b678675851
@ -8,6 +8,11 @@ public class NocrCallbackData : CallbackData<NocrState>
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NocrCallbackData Start()
|
||||||
|
{
|
||||||
|
return new NocrCallbackData(NocrState.Start);
|
||||||
|
}
|
||||||
|
|
||||||
public static NocrCallbackData ActivateSubscription(long subscriptionId)
|
public static NocrCallbackData ActivateSubscription(long subscriptionId)
|
||||||
{
|
{
|
||||||
return new NocrCallbackData(NocrState.ActivateSubscription, subscriptionId.ToString());
|
return new NocrCallbackData(NocrState.ActivateSubscription, subscriptionId.ToString());
|
||||||
@ -29,4 +34,9 @@ public class NocrCallbackData : CallbackData<NocrState>
|
|||||||
new NocrCallbackData(NocrState.ViewSubscription, subscriptionId.Value.ToString()):
|
new NocrCallbackData(NocrState.ViewSubscription, subscriptionId.Value.ToString()):
|
||||||
new NocrCallbackData(NocrState.ViewSubscription);
|
new NocrCallbackData(NocrState.ViewSubscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NocrCallbackData Feedback()
|
||||||
|
{
|
||||||
|
return new NocrCallbackData(NocrState.Feedback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -9,5 +9,6 @@ public enum NocrState
|
|||||||
|
|
||||||
// States
|
// States
|
||||||
Start,
|
Start,
|
||||||
ViewSubscription
|
ViewSubscription,
|
||||||
|
Feedback
|
||||||
}
|
}
|
||||||
@ -4,7 +4,6 @@ using Insight.TelegramBot.Keyboards;
|
|||||||
using Insight.TelegramBot.Models;
|
using Insight.TelegramBot.Models;
|
||||||
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.Messages.StartMessage;
|
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
using Telegram.Bot.Types.ReplyMarkups;
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
@ -63,6 +62,11 @@ public abstract class StartHandlerBase
|
|||||||
{
|
{
|
||||||
CallbackData = NocrCallbackData.ViewSubscription().ToString()
|
CallbackData = NocrCallbackData.ViewSubscription().ToString()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
markup.Add(new InlineKeyboardButton(Localizer.Get(nameof(StartHandlerBase), "FeedbackButton"))
|
||||||
|
{
|
||||||
|
CallbackData = NocrCallbackData.Feedback().ToString()
|
||||||
|
});
|
||||||
|
|
||||||
return markup.InlineKeyboardMarkup;
|
return markup.InlineKeyboardMarkup;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -158,7 +158,7 @@ public abstract class ViewSubscriptionHandlerBase
|
|||||||
|
|
||||||
markup.Add(new InlineKeyboardButton(Localizer.Get("Buttons", "Back"))
|
markup.Add(new InlineKeyboardButton(Localizer.Get("Buttons", "Back"))
|
||||||
{
|
{
|
||||||
CallbackData = new NocrCallbackData(NocrState.Start).ToString()
|
CallbackData = NocrCallbackData.Start().ToString()
|
||||||
});
|
});
|
||||||
|
|
||||||
return markup;
|
return markup;
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
using Insight.Localizer;
|
||||||
|
using Insight.TelegramBot;
|
||||||
|
using Insight.TelegramBot.Handling.Handlers;
|
||||||
|
using Insight.TelegramBot.Models;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Nocr.TelegramClient.AppServices.Bots;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
|
||||||
|
namespace Nocr.TelegramClient.AppServices.Handlers.CallbackQueries.Feedback;
|
||||||
|
|
||||||
|
public class FeedbackHandler : IMatchingUpdateHandler<FeedbackMatcher>
|
||||||
|
{
|
||||||
|
private readonly ILogger<FeedbackHandler> _logger;
|
||||||
|
private readonly ILocalizer _localizer;
|
||||||
|
private readonly IBot _bot;
|
||||||
|
|
||||||
|
public FeedbackHandler(ILogger<FeedbackHandler> logger, ILocalizer localizer, IBot bot)
|
||||||
|
{
|
||||||
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
|
_localizer = localizer ?? throw new ArgumentNullException(nameof(localizer));
|
||||||
|
_bot = bot ?? throw new ArgumentNullException(nameof(bot));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Handle(Update update, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
// TODO: Check, that other messages sent to chat, no to one, who clicks
|
||||||
|
var message = new TextMessage(update.CallbackQuery.Message.Chat.Id)
|
||||||
|
{
|
||||||
|
Text = _localizer.Get(nameof(FeedbackHandler), "Text"),
|
||||||
|
ReplyMarkup = new InlineKeyboardMarkup(new InlineKeyboardButton(_localizer.Get("buttons", "back"))
|
||||||
|
{
|
||||||
|
CallbackData = NocrCallbackData.Start().ToString()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return _bot.EditOrSendTextMessage(update.CallbackQuery.Message.MessageId, message, _logger, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using Insight.TelegramBot.Handling.Matchers.CallbackQueryMatchers;
|
||||||
|
using Nocr.TelegramClient.AppServices.Bots;
|
||||||
|
|
||||||
|
namespace Nocr.TelegramClient.AppServices.Handlers.CallbackQueries.Feedback;
|
||||||
|
|
||||||
|
public sealed class FeedbackMatcher : StateCallbackQueryMatcher<NocrState>
|
||||||
|
{
|
||||||
|
public FeedbackMatcher()
|
||||||
|
{
|
||||||
|
ExpectingState = NocrState.Feedback;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
using Insight.Localizer;
|
using Insight.Localizer;
|
||||||
using Insight.TelegramBot;
|
using Insight.TelegramBot;
|
||||||
using Insight.TelegramBot.Handling.Handlers;
|
using Insight.TelegramBot.Handling.Handlers;
|
||||||
using Insight.TelegramBot.Models;
|
|
||||||
using Microsoft.Extensions.Logging;
|
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;
|
||||||
|
|||||||
@ -0,0 +1,76 @@
|
|||||||
|
using FormatWith;
|
||||||
|
using Insight.Localizer;
|
||||||
|
using Insight.TelegramBot.Handling.Handlers;
|
||||||
|
using Insight.TelegramBot.Models;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Nocr.TelegramClient.AppServices.Bots;
|
||||||
|
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
|
||||||
|
using Nocr.TelegramClient.AppServices.Options;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
|
|
||||||
|
namespace Nocr.TelegramClient.AppServices.Handlers.Messages.FeedbackMessage;
|
||||||
|
|
||||||
|
public sealed class FeedbackMessageHandler : IMatchingUpdateHandler<FeedbackMessageMatcher>
|
||||||
|
{
|
||||||
|
private readonly ILogger<FeedbackMessageHandler> _logger;
|
||||||
|
private readonly ILocalizer _localizer;
|
||||||
|
private readonly IMessageDispatcherQueue _messageDispatcherQueue;
|
||||||
|
private readonly AdministrationOptions _administrationOptions;
|
||||||
|
|
||||||
|
public FeedbackMessageHandler(ILogger<FeedbackMessageHandler> logger, ILocalizer localizer,
|
||||||
|
IMessageDispatcherQueue messageDispatcherQueue, IOptionsSnapshot<AdministrationOptions> administrationOptions)
|
||||||
|
{
|
||||||
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
|
_localizer = localizer ?? throw new ArgumentNullException(nameof(localizer));
|
||||||
|
_messageDispatcherQueue =
|
||||||
|
messageDispatcherQueue ?? throw new ArgumentNullException(nameof(messageDispatcherQueue));
|
||||||
|
_administrationOptions =
|
||||||
|
administrationOptions.Value ?? throw new ArgumentNullException(nameof(administrationOptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Handle(Update update, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var from = update.Message.From;
|
||||||
|
var feedbackText = update.Message.Text
|
||||||
|
.Replace("/feedback", string.Empty)
|
||||||
|
.Trim(' ');
|
||||||
|
|
||||||
|
var message = new TextMessage(from.Id)
|
||||||
|
{
|
||||||
|
Text = _localizer.Get(nameof(FeedbackMessageHandler), "Text"),
|
||||||
|
ReplyMarkup = new InlineKeyboardMarkup(new InlineKeyboardButton(_localizer.Get("buttons", "back"))
|
||||||
|
{
|
||||||
|
CallbackData = NocrCallbackData.Start().ToString()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
_messageDispatcherQueue.Enqueue(message);
|
||||||
|
|
||||||
|
foreach (var feedbackReceiverId in _administrationOptions.FeedbackReceiverIds)
|
||||||
|
{
|
||||||
|
var feedbackMessage = new TextMessage(feedbackReceiverId)
|
||||||
|
{
|
||||||
|
Text = _localizer.Get(nameof(FeedbackMessageHandler), "FeedbackText")
|
||||||
|
.FormatWith(new
|
||||||
|
{
|
||||||
|
FromId = from.Id,
|
||||||
|
FromUsername = string.IsNullOrWhiteSpace(from.Username) ? "anonymous" : $"@{from.Username}",
|
||||||
|
Text = feedbackText
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_messageDispatcherQueue.Enqueue(feedbackMessage);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "Failed to send feedback message to {FeedbackReceiverId}", feedbackReceiverId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using Insight.TelegramBot.Handling.Matchers.TextMatchers;
|
||||||
|
|
||||||
|
namespace Nocr.TelegramClient.AppServices.Handlers.Messages.FeedbackMessage;
|
||||||
|
|
||||||
|
public sealed class FeedbackMessageMatcher : TextStartWithUpdateMatcher
|
||||||
|
{
|
||||||
|
public FeedbackMessageMatcher()
|
||||||
|
{
|
||||||
|
Template = "/feedback";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
namespace Nocr.TelegramClient.AppServices.Options;
|
||||||
|
|
||||||
|
public sealed class AdministrationOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Список telegram идентификаторов для получения отзывов
|
||||||
|
/// </summary>
|
||||||
|
public long[] FeedbackReceiverIds { get; set; } = Array.Empty<long>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Список telegram идентификаторов для получения обновлений
|
||||||
|
/// </summary>
|
||||||
|
public long[] UpdateReceiverIds { get; set; } = Array.Empty<long>();
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
|
using Nocr.TelegramClient.AppServices.Bots.MessageDispatcher;
|
||||||
|
using Nocr.TelegramClient.AppServices.Handlers.Messages.FeedbackMessage;
|
||||||
using Nocr.TelegramClient.AppServices.Options;
|
using Nocr.TelegramClient.AppServices.Options;
|
||||||
using Nocr.TelegramClient.AppServices.TextSubscriptions.Handlers;
|
using Nocr.TelegramClient.AppServices.TextSubscriptions.Handlers;
|
||||||
using Nocr.TelegramClient.AppServices.Users;
|
using Nocr.TelegramClient.AppServices.Users;
|
||||||
@ -23,6 +24,8 @@ public static class ServiceCollectionExtensions
|
|||||||
services.AddRebusHandler<TextSubscriptionMatchedHandler>();
|
services.AddRebusHandler<TextSubscriptionMatchedHandler>();
|
||||||
services.AddHttpClient();
|
services.AddHttpClient();
|
||||||
|
|
||||||
|
services.Configure<AdministrationOptions>(configuration.GetSection(nameof(AdministrationOptions)));
|
||||||
|
|
||||||
services.Configure<UsersRestEaseOptions>(configuration.GetSection(nameof(UsersRestEaseOptions)));
|
services.Configure<UsersRestEaseOptions>(configuration.GetSection(nameof(UsersRestEaseOptions)));
|
||||||
services.AddScoped<IUsersController>(ctx =>
|
services.AddScoped<IUsersController>(ctx =>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"Text": "Привет! Я, Nocr 🤖!",
|
"Text": "Привет! Я, Nocr 🤖!",
|
||||||
|
|
||||||
"SubscriptionsButton": "Подписки 📩"
|
"SubscriptionsButton": "Подписки 📩",
|
||||||
|
"FeedbackButton": "Оставить отзыв 🙋"
|
||||||
}
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Text": "Чтобы оставить отзыв или пожелание по улучшению отправьте команду /feedback в формате `/feedback текст отзыва`. Например, /feeback Классный бот! Спасибо!"
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"Text": "Благодарим за отзыв!",
|
||||||
|
|
||||||
|
"FeedbackText": "#feedback\nПолучен отзыв от: {FromId} ({FromUsername})\n<i>{Text}</i>"
|
||||||
|
}
|
||||||
@ -22,5 +22,13 @@
|
|||||||
"Path": "Resources",
|
"Path": "Resources",
|
||||||
"Pattern": "",
|
"Pattern": "",
|
||||||
"ReadNestedFolders": "true"
|
"ReadNestedFolders": "true"
|
||||||
|
},
|
||||||
|
"AdministrationOptions": {
|
||||||
|
"FeedbackReceiverIds": [
|
||||||
|
-4202454237
|
||||||
|
],
|
||||||
|
"UpdateReceiverIds": [
|
||||||
|
-4202454237
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user