diff --git a/src/FillInTheTextBot.Messengers.Yandex/YandexService.cs b/src/FillInTheTextBot.Messengers.Yandex/YandexService.cs index 62b4b5bf..4586622d 100644 --- a/src/FillInTheTextBot.Messengers.Yandex/YandexService.cs +++ b/src/FillInTheTextBot.Messengers.Yandex/YandexService.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Threading.Tasks; using FillInTheTextBot.Services; +using FillInTheTextBot.Services.Extensions; using Microsoft.Extensions.Logging; using Yandex.Dialogs.Models; using Yandex.Dialogs.Models.Input; @@ -30,26 +32,22 @@ protected override Models.Request Before(InputModel input) var request = input.ToRequest(); input.TryGetFromUserState(Models.Request.IsOldUserKey, out bool isOldUser); - request.IsOldUser = isOldUser; - if (input.TryGetFromUserState(Models.Response.NextTextIndexStorageKey, out object nextTextIndex) != true) - { - input.TryGetFromApplicationState(Models.Response.NextTextIndexStorageKey, out nextTextIndex); - } - - request.NextTextIndex = Convert.ToInt32(nextTextIndex); - input.TryGetFromSessionState(Models.Response.ScopeStorageKey, out string scopeKey); - request.ScopeKey = scopeKey; - if (request.NewSession == true) - { - var contexts = GetContexts(input); + input.TryGetFromSessionState(Models.Response.CurrentTextKey, out string currentText); + request.CurrentText = currentText; - request.RequiredContexts.AddRange(contexts); - } + input.TryGetFromUserState(Models.Response.PassedTextsKey, out object passedTexts); + request.PassedTexts = passedTexts.ToString().Deserialize() + .Where(s => !string.IsNullOrEmpty(s)).ToList(); + + if (request.NewSession != true) return request; + + var contexts = GetContexts(input); + request.RequiredContexts.AddRange(contexts); return request; } @@ -74,8 +72,9 @@ protected override Task AfterAsync(InputModel input, Models.Respons output.AddToUserState(Models.Request.IsOldUserKey, true); - output.AddToUserState(Models.Response.NextTextIndexStorageKey, response.NextTextIndex); - output.AddToApplicationState(Models.Response.NextTextIndexStorageKey, response.NextTextIndex); + output.AddToSessionState(Models.Response.CurrentTextKey, response.CurrentText); + + output.AddToUserState(Models.Response.PassedTextsKey, response.PassedTexts); output.AddToSessionState(Models.Response.ScopeStorageKey, response.ScopeKey); diff --git a/src/FillInTheTextBot.Models/Request.cs b/src/FillInTheTextBot.Models/Request.cs index 8cdfcbb5..0c46cb56 100644 --- a/src/FillInTheTextBot.Models/Request.cs +++ b/src/FillInTheTextBot.Models/Request.cs @@ -35,6 +35,10 @@ public Request() public int NextTextIndex { get; set; } + public string CurrentText { get; set; } + + public ICollection PassedTexts { get; set; } + public string ScopeKey { get; set; } public Appeal Appeal { get; set; } diff --git a/src/FillInTheTextBot.Models/Response.cs b/src/FillInTheTextBot.Models/Response.cs index 83a05195..984df333 100644 --- a/src/FillInTheTextBot.Models/Response.cs +++ b/src/FillInTheTextBot.Models/Response.cs @@ -6,6 +6,8 @@ public class Response { public static string NextTextIndexStorageKey => nameof(NextTextIndex).ToUpper(); public static string ScopeStorageKey => nameof(ScopeKey).ToUpper(); + public static string PassedTextsKey => nameof(PassedTexts).ToUpper(); + public static string CurrentTextKey => nameof(CurrentText).ToUpper(); public Response() { @@ -26,8 +28,12 @@ public Response() public int NextTextIndex { get; set; } + public string CurrentText { get; set; } + + public IList PassedTexts { get; set; } + public string ScopeKey { get; set; } - + public IDictionary Emotions { get; set; } } } \ No newline at end of file diff --git a/src/FillInTheTextBot.Models/TextsOverException.cs b/src/FillInTheTextBot.Models/TextsOverException.cs new file mode 100644 index 00000000..8732a36d --- /dev/null +++ b/src/FillInTheTextBot.Models/TextsOverException.cs @@ -0,0 +1,9 @@ +using System; + +namespace FillInTheTextBot.Models +{ + public class TextsOverException : Exception + { + + } +} \ No newline at end of file diff --git a/src/FillInTheTextBot.Services/ConversationService.cs b/src/FillInTheTextBot.Services/ConversationService.cs index 838a408f..d86f4ce3 100644 --- a/src/FillInTheTextBot.Services/ConversationService.cs +++ b/src/FillInTheTextBot.Services/ConversationService.cs @@ -15,11 +15,13 @@ public class ConversationService : IConversationService private readonly IDialogflowService _dialogflowService; private readonly IRedisCacheService _cache; + private readonly Random _random; public ConversationService(IDialogflowService dialogflowService, IRedisCacheService cache) { _dialogflowService = dialogflowService; _cache = cache; + _random = Random.Shared; } public async Task GetResponseAsync(Request request) @@ -31,8 +33,9 @@ public async Task GetResponseAsync(Request request) Text = dialog?.Response, Finished = dialog?.EndConversation ?? false, Buttons = dialog?.Buttons, - ScopeKey = dialog?.ScopeKey - + ScopeKey = dialog?.ScopeKey, + CurrentText = request.CurrentText, + PassedTexts = request.PassedTexts.ToList() }; var resetTextIndex = string.Empty; @@ -41,7 +44,7 @@ public async Task GetResponseAsync(Request request) if (isGotResetParameter && string.Equals(resetTextIndex, bool.TrueString, StringComparison.InvariantCultureIgnoreCase)) { - request.NextTextIndex = 0; + request.PassedTexts.Clear(); } if (string.Equals(dialog?.Action, "GetText")) @@ -58,8 +61,6 @@ public async Task GetResponseAsync(Request request) response.Emotions = GetEmotions(dialog); - response.NextTextIndex = request.NextTextIndex; - response.Text = GetResponseText(request.Appeal, response.Text); response.Buttons = GetButtonsFromPayload(response.Buttons, dialog?.Payload, request.Source); @@ -67,7 +68,7 @@ public async Task GetResponseAsync(Request request) response.Text = texts.Text; response.AlternativeText = texts.AlternativeText; - TrySetSavedText(request.SessionId, dialog, texts); + TrySetSavedText(request.SessionId, dialog, texts, response); return response; } @@ -109,7 +110,10 @@ private async Task GetText(Request request, string startText, string t { using (Tracing.Trace()) { - var response = new Response(); + var response = new Response + { + PassedTexts = request.PassedTexts.ToList() + }; if (string.IsNullOrEmpty(textKey)) { @@ -124,7 +128,21 @@ private async Task GetText(Request request, string startText, string t return response; } - textKey = GetTextKey(request, texts); + try + { + textKey = GetTextKey(request.PassedTexts, texts); + + response.CurrentText = textKey; + } + catch (TextsOverException e) + { + if (!string.IsNullOrEmpty(request.CurrentText)) + { + textKey = "texts-over"; + } + + response.PassedTexts.Clear(); + } } } @@ -146,21 +164,24 @@ private async Task GetText(Request request, string startText, string t } } - private string GetTextKey(Request request, string[] texts) + private string GetTextKey(ICollection passedTexts, string[] texts) { - string textKey; - - var index = request.NextTextIndex++; - - if (index >= texts.Length) + if (passedTexts.Count >= texts.Length) { - textKey = "texts-over"; + throw new TextsOverException(); } - else + + if (passedTexts.Count == 0) { - textKey = texts[index]; + return texts.FirstOrDefault(); } + var candidateTexts = texts.Except(passedTexts).ToList(); + + var candidateIndex = _random.Next(candidateTexts.Count); + + var textKey = candidateTexts[candidateIndex]; + return textKey; } @@ -272,7 +293,7 @@ private ICollection