complete the basic dialog flow

This commit is contained in:
Slavasil 2025-04-20 18:42:08 +03:00
parent 3fac697963
commit b4dd14ed2b
3 changed files with 121 additions and 2 deletions

View File

@ -4,6 +4,7 @@ internal class DialogData
{
public DialogState state;
public string? inputPictureFilename;
public string? inputTitle;
}
enum DialogState

View File

@ -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;
}
}

View File

@ -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>