public AliceResponse HandleRequest(AliceRequest request) { // start if (request.IsEnter()) { var currentTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); var resp = request.State.User.LastEnter < currentTime - 30 * 24 * 3600000L ? Phrases.FirstRun.Generate(request) : Phrases.Hi.Generate(request); resp.UserStateUpdate.LastEnter = currentTime; return(resp); } // help command if (request.HasIntent(Intents.YandexHelp1) || request.HasIntent(Intents.YandexHelp2)) { return(Phrases.Help.Generate(request)); } // exit if (request.HasIntent(Intents.Exit)) { var exit = Phrases.Exit.Generate(request); exit.Response.EndSession = true; return(exit); } // by letters if (request.HasIntent(Intents.ByLetters)) { var w = request.GetSlot(Intents.ByLetters, Slots.Word); var accent = -1; if (w.IsNullOrEmpty() && !request.State.Session.LastForm.IsNullOrEmpty()) { w = request.State.Session.LastForm; accent = request.State.Session.LastFormAccent; } else if (!w.IsNullOrEmpty() && _nMorph.WordExists(w)) { request.State.Session.Clear(); request.State.Session.LastWord = w; } return(ReadByLetters(w, accent).Generate(request)); } // has word var filler = new [] { "слово", "слова", "слов", "словом" }; // workaround var startsFromFiller = request.Request.Nlu.Tokens.Count == 2 && filler.Contains(request.Request.Nlu.Tokens[0]); var hasWord = request.HasSlot(Intents.Main, Slots.Word) || request.Request.Nlu.Tokens.Count == 1 || startsFromFiller; var changeForm = Slots.GrammemeSlots.Any(s => request.HasSlot(Intents.Main, s)); // no word / unknown command if ( !hasWord && ( request.State.Session.LastWord.IsNullOrEmpty() || (!changeForm && !request.HasIntent(Intents.ByLetters)) ) ) { return(Phrases.UnknownCommand.Generate(request)); } // word command if (hasWord) { request.State.Session.LastWord = request.HasSlot(Intents.Main, Slots.Word) ? request.GetSlot(Intents.Main, Slots.Word) : startsFromFiller ? request.Request.Nlu.Tokens[1] : request.Request.Nlu.Tokens.First(); } // word not exists if (!_nMorph.WordExists(request.State.Session.LastWord)) { var resp = Phrases.UnknownWord(request.State.Session.LastWord).Generate(request); request.State.Session.Clear(); return(resp); } // word exists, find it var words = _nMorph.WordInfo(request.State.Session.LastWord); // get all slots var pos = ParseEnum <Pos>(request, Slots.Pos); var number = ParseEnum <Number>(request, Slots.Number); var gender = ParseEnum <Gender>(request, Slots.Gender); var @case = ParseEnum <Case>(request, Slots.Case); var tense = ParseEnum <Tense>(request, Slots.Tense); var person = ParseEnum <Person>(request, Slots.Person); // filter by pos if possible if (pos != Pos.None && words.Any(w => w.Tag.Pos == pos)) { words = words.Where(w => w.Tag.Pos == pos).ToArray(); } // find forms var exactForms = new List <(Word, WordForm)>(); var nonExactForms = new List <(Word, WordForm)>(); foreach (var w in words) { if (!changeForm) { // get form from input word var formsFound = w.ExactForms(request.State.Session.LastWord); exactForms.AddRange(formsFound.Select(f => (w, f))); } else { // get form from input data var form = w.ClosestForm(gender, @case, number, tense, person, true); if (form != null) { exactForms.Add((w, form)); } else { form = w.ClosestForm(gender, @case, number, tense, person, false); nonExactForms.Add((w, form)); } } } // no forms found if (exactForms.Count == 0 && nonExactForms.Count == 0) { return(Phrases.UnknownForm.Generate(request)); } // read all found forms var response = Phrases.StandardButtons; var formsToRead = exactForms; if (exactForms.Count == 0) { formsToRead = nonExactForms; response += Phrases.NonExactForms; } request.State.Session.LastForm = formsToRead.First().Item2.Word; request.State.Session.LastFormAccent = formsToRead.First().Item2.GetAccentIndex(); for (var i = 0; i < formsToRead.Count; i++) { var(w, f) = formsToRead[i]; response += ReadSingleForm(w, f, i == formsToRead.Count - 1); } return(response.Generate(request)); }