complete the basic dialog flow
This commit is contained in:
parent
3fac697963
commit
b4dd14ed2b
@ -4,6 +4,7 @@ internal class DialogData
|
||||
{
|
||||
public DialogState state;
|
||||
public string? inputPictureFilename;
|
||||
public string? inputTitle;
|
||||
}
|
||||
|
||||
enum DialogState
|
||||
|
@ -7,6 +7,10 @@ internal static class Interactions
|
||||
public const string awaitingPictureMessage = "Привет. Я - бот, который умеет делать демотиваторы. Присылай картинку, а я скажу, что делать дальше. Или можешь нажать на кнопку в меню.";
|
||||
public const string sayHelloMessage = "Напиши \"привет\" или нажми на кнопку в меню, чтобы начать.";
|
||||
public const string sendPictureOrQuitMessage = "Пришли мне картинку для демотиватора, чтобы продолжить. Чтобы отменить, напиши \"назад\" или \"\"";
|
||||
public const string sendTitleOrQuitMessage = "Пришли мне текст для демотиватора, чтобы продолжить. Чтобы отменить, нажми на кнопку в меню.";
|
||||
public const string awaitingTitleMessage = "Шикарная картинка. Давай сделаем из неё крутой интернет-мэм для скуфов. Какой текст ты бы хотел видеть на нём? Можно написать две строки, тогда первая строка будет заголовком, а вторая под ним.";
|
||||
public const string showingResultMessage = "Вот такой демотиватор получился. Можно поменять цветовую схему, добавить водяной знак или оставить как есть.";
|
||||
public const string awaitingSubtitleMessage = "Найс. Напиши текст, который будет под заголовком, или точку (.), чтобы не добавлять его.";
|
||||
|
||||
public static readonly IReplyMarkup initialReplyMarkup = new ReplyKeyboardMarkup([[new KeyboardButton("▶️Начать")]]);
|
||||
public static readonly IReplyMarkup backButtonReplyMarkup = new ReplyKeyboardMarkup(new KeyboardButton("↩️Назад"));
|
||||
@ -14,6 +18,7 @@ internal static class Interactions
|
||||
|
||||
static readonly string[] helloWords = ["прив","привет","▶️начать","ку","хай","приветик","превед","привки","хаюхай","здравствуй","здравствуйте","здорово","дарова","дороу","здарова","здорова"];
|
||||
static readonly string[] cancelWords = ["↩️назад", "назад", "выйти", "отмена", "отменить", "отменяй", "галя", "галина", "стоп"];
|
||||
static readonly string cancelButtonText = "↩️Назад";
|
||||
|
||||
public static bool IsStartCommand(string message)
|
||||
{
|
||||
@ -31,4 +36,9 @@ internal static class Interactions
|
||||
string[] messageWords = message.ToLower().Split(new char[] { ' ', ',', '.', ';', '(', ')' });
|
||||
return cancelWords.Any(word => messageWords.Contains(word));
|
||||
}
|
||||
|
||||
public static bool IsCancelButton(string message)
|
||||
{
|
||||
return message == cancelButtonText;
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +131,49 @@ internal class TelegramBot
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DialogState.AwaitingTitle:
|
||||
{
|
||||
if (message.Text is { } messageText)
|
||||
{
|
||||
if (!Interactions.IsCancelButton(messageText))
|
||||
{
|
||||
await DialogHandleDemotivatorText(botClient, dialogData, message, messageText, cancellationToken);
|
||||
} else
|
||||
{
|
||||
DialogCancelDemotivatorCreation(dialogData);
|
||||
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.awaitingPictureMessage, replyMarkup: Interactions.quickActionReplyMarkup);
|
||||
}
|
||||
} else
|
||||
{
|
||||
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.sendTitleOrQuitMessage, replyMarkup: Interactions.backButtonReplyMarkup);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DialogState.AwaitingSubtitle:
|
||||
{
|
||||
if (message.Text is { } messageText)
|
||||
{
|
||||
if (!Interactions.IsCancelButton(messageText))
|
||||
{
|
||||
await DialogHandleDemotivatorSubtitle(botClient, dialogData, message, messageText, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
DialogCancelDemotivatorCreation(dialogData);
|
||||
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.awaitingPictureMessage, replyMarkup: Interactions.quickActionReplyMarkup);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DialogState.ShowingResult:
|
||||
{
|
||||
bool replied = false;
|
||||
if (message.Text is { } messageText)
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,20 +189,85 @@ internal class TelegramBot
|
||||
response.EnsureSuccessStatusCode();
|
||||
(string tempFileName, FileStream tempFile) = temp.newTemporaryFile("pic", pictureExtension);
|
||||
await response.Content.CopyToAsync(tempFile);
|
||||
tempFile.Close();
|
||||
tempFile.Dispose();
|
||||
logger.Info($"Файл картинки {tempFileName} загружен от пользователя {message.From.FirstName}[{message.From.Id}]");
|
||||
dialogData.inputPictureFilename = tempFileName;
|
||||
dialogData.state = DialogState.AwaitingTitle;
|
||||
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.awaitingTitleMessage, replyMarkup: Interactions.backButtonReplyMarkup);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Ошибка при скачивании картинки от пользователя: " + e.GetType().Name + ": " + e.Message);
|
||||
logger.Error(e.StackTrace ?? "");
|
||||
_ = botClient.SendTextMessageAsync(message.Chat.Id, "Ошибка :(");
|
||||
dialogData.state = DialogState.Initial;
|
||||
await botClient.SendTextMessageAsync(message.Chat.Id, "Ошибка :(");
|
||||
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.awaitingPictureMessage, replyMarkup: Interactions.quickActionReplyMarkup);
|
||||
}
|
||||
}
|
||||
|
||||
async Task DialogHandleDemotivatorText(ITelegramBotClient botClient, DialogData dialogData, Message message, string text, CancellationToken cancellationToken)
|
||||
{
|
||||
string[] lines = text.Split('\n');
|
||||
string title;
|
||||
string? subtitle = null;
|
||||
if (lines.Length > 1)
|
||||
{
|
||||
title = lines[0];
|
||||
subtitle = string.Join(' ', lines.Skip(1));
|
||||
} else
|
||||
{
|
||||
title = lines.First();
|
||||
}
|
||||
|
||||
if (subtitle != null)
|
||||
{
|
||||
logger.Info($"Генерирую простой демотиватор: [\"{title}\", \"{subtitle}\"]");
|
||||
MemoryStream demotivator = DemotivatorGen.MakePictureDemotivator(
|
||||
dialogData.inputPictureFilename!,
|
||||
[new DemotivatorText() { Title = title, Subtitle = subtitle }],
|
||||
DemotivatorGen.DefaultStyle());
|
||||
DialogFinishDemotivatorCreation(dialogData);
|
||||
await botClient.SendPhotoAsync(message.Chat.Id, new InputFile(demotivator, "dem.png"), caption: Interactions.showingResultMessage, cancellationToken: cancellationToken);
|
||||
demotivator.Dispose();
|
||||
} else
|
||||
{
|
||||
logger.Info($"Пользователь ввёл заголовок: \"{title}\"");
|
||||
dialogData.inputTitle = title;
|
||||
dialogData.state = DialogState.AwaitingSubtitle;
|
||||
await botClient.SendTextMessageAsync(message.Chat.Id, Interactions.awaitingSubtitleMessage, replyMarkup: Interactions.backButtonReplyMarkup, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
async Task DialogHandleDemotivatorSubtitle(ITelegramBotClient botClient, DialogData dialogData, Message message, string subtitle, CancellationToken cancellationToken)
|
||||
{
|
||||
subtitle = subtitle != "." ? subtitle.Replace('\n', ' ') : "";
|
||||
string title = dialogData.inputTitle!;
|
||||
|
||||
logger.Info($"Генерирую простой демотиватор: [\"{title}\", \"{subtitle}\"]");
|
||||
MemoryStream demotivator = DemotivatorGen.MakePictureDemotivator(
|
||||
dialogData.inputPictureFilename!,
|
||||
[new DemotivatorText() { Title = title, Subtitle = subtitle }],
|
||||
DemotivatorGen.DefaultStyle());
|
||||
DialogFinishDemotivatorCreation(dialogData);
|
||||
await botClient.SendPhotoAsync(message.Chat.Id, new InputFile(demotivator, "dem.png"), caption: Interactions.showingResultMessage, cancellationToken: cancellationToken);
|
||||
demotivator.Dispose();
|
||||
}
|
||||
|
||||
void DialogCancelDemotivatorCreation(DialogData dialogData)
|
||||
{
|
||||
dialogData.state = DialogState.AwaitingPicture;
|
||||
if (dialogData.inputPictureFilename != null)
|
||||
temp.deleteTemporaryFile(dialogData.inputPictureFilename);
|
||||
}
|
||||
|
||||
void DialogFinishDemotivatorCreation(DialogData dialogData)
|
||||
{
|
||||
dialogData.state = DialogState.ShowingResult;
|
||||
if (dialogData.inputPictureFilename != null)
|
||||
temp.deleteTemporaryFile(dialogData.inputPictureFilename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обработчик исключений, возникших при работе бота
|
||||
/// </summary>
|
||||
|
Loading…
Reference in New Issue
Block a user