public static async Task <string> Run([QueueTrigger("scrape")] string json, ILogger logger) { logger.LogInformation($"LuisFunction invoked:\n{json}"); var luisInput = JsonConvert.DeserializeObject <LuisInput>(json); var missingPerson = new MissingPerson { SourceUrl = luisInput.SourceUrl, TweetUrl = luisInput.TweetUrl, TwitterProfileUrl = luisInput.TwitterProfileUrl, Summary = luisInput.Summary ?? "", ShortSummary = luisInput.ShortSummary ?? "", UserLocation = luisInput.UserLocation }; string shortSummary = luisInput.ShortSummary; if (!string.IsNullOrEmpty(shortSummary)) { string[] sentences = Regex.Split(shortSummary, @"(?<=[\.!\?])\s+"); List <LuisV2Entity> allEntities = new List <LuisV2Entity>(); foreach (string batch in BatchSentences(sentences, 500).Take(3)) { logger.LogInformation($"Sending LUIS query \"{batch}\"."); var luisResult = await GetLuisResult(batch, logger); if (luisResult != null) { if (luisResult.TopScoringIntent.Intent == "GetDescription") { allEntities.AddRange(luisResult.Entities); } } else { logger.LogWarning("LUIS did not return entities to process."); } } MapLuisResultToMissingPerson(missingPerson, allEntities, logger); } else { logger.LogWarning($"LUIS skipped tweet {luisInput.TweetUrl} due to missing short summary."); } var result = JsonConvert.SerializeObject(missingPerson); logger.LogInformation($"result:\n{result}"); return(result); }
private static void MapLuisResultToMissingPerson(MissingPerson missingPerson, List <LuisV2Entity> entities, ILogger logger) { //construct the missing person record from the LUIS result, some properties are constructed from a combination of luis results // select the best name from the names that are returned using heuristic var nameEntity = entities.FirstOrDefault(f => f.Type == "builtin.personName" && f.Entity.Contains(' ') && f.Role == "subject") ?? entities.FirstOrDefault(f => f.Type == "builtin.personName" && f.Entity.Contains(' ') && f.Role == null) ?? entities.SelectTopScore("Name"); string personName = nameEntity?.Entity; if (!string.IsNullOrEmpty(personName)) { var myTi = new CultureInfo("en-US", false); personName = myTi.TextInfo.ToTitleCase(personName); } missingPerson.Name = personName; // Select the best report location var cityEntity = //entities.FirstOrDefault(f => f.Type == "builtin.geographyV2.city") ?? entities.SelectTopScore("City"); missingPerson.City = cityEntity?.Entity; missingPerson.Province = entities.FirstOrDefault(f => f.Type == "provinceV2")?.Resolution.FirstOrDefaultElement() ?? entities.SelectTopScore("Province")?.Entity; var age = entities.SelectTopScoreInt("Age") ?? entities.FirstOrDefault(f => f.Type == "builtin.age")?.FirstOrDefaultAgeResolution() ?? entities.FirstOrDefault(f => f.Type == "ageV2")?.EntityAsInt(); missingPerson.Age = age.GetValueOrDefault(0); missingPerson.Gender = entities.FirstOrDefault(f => f.Type == "genderV2")?.Resolution.FirstOrDefaultElement() ?? entities.SelectTopScore("Gender")?.Entity; missingPerson.Ethnicity = entities.FirstOrDefault(f => f.Type == "ethnicityV2")?.Resolution.FirstOrDefaultElement() ?? entities.SelectTopScore("Ethnicity")?.Entity; missingPerson.MissingSince = entities.SelectTopScoreDateTime("MissingSince"); missingPerson.Height = entities.SelectTopScore("Height")?.Entity; missingPerson.Weight = entities.SelectTopScore("Weight")?.Entity; // if a found entity exists then the result is missingPerson.Found = entities.Exists(w => w.Type == "Found") || string.Equals(entities.FirstOrDefault(f => f.Type == "locatedV2")?.Resolution.FirstOrDefaultElement(), "Located", StringComparison.OrdinalIgnoreCase) ? 1 : 0; }