public static IActionResult RunAcronymLinkerForLists([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
                                                             ILogger log,
                                                             ExecutionContext executionContext)
        {
            log.LogInformation("Link Acronyms List Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            AcronymLinker       acronymLinker = new AcronymLinker(executionContext.FunctionAppDirectory);
            WebApiSkillResponse response      = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                         (inRecord, outRecord) => {
                var words    = JsonConvert.DeserializeObject <JArray>(JsonConvert.SerializeObject(inRecord.Data["words"]));
                var acronyms = words
                               .Distinct()
                               .Select(jword =>
                {
                    var word = jword.Value <string>();
                    if (word.All(char.IsUpper) && acronymLinker.Acronyms.TryGetValue(word, out string description))
                    {
                        return(new { value = word, description });
                    }
                    return(null);
                })
                               .Where(acronym => acronym != null);

                outRecord.Data["acronyms"] = acronyms.ToArray();
                return(outRecord);
            });
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Entity Search Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            string bingApiKey = Environment.GetEnvironmentVariable(bingApiKeySetting, EnvironmentVariableTarget.Process);

            WebApiSkillResponse response = await WebApiSkillHelpers.ProcessRequestRecordsAsync(skillName, requestRecords,
                                                                                               async (inRecord, outRecord) => {
                var entityName = inRecord.Data["name"] as string;
                string uri     = bingApiEndpoint + "?q=" + Uri.EscapeDataString(entityName) + "&mkt=en-us&count=10&offset=0&safesearch=Moderate";

                IEnumerable <BingEntity> entities =
                    await WebApiSkillHelpers.Fetch <BingEntity>(uri, "Ocp-Apim-Subscription-Key", bingApiKey, "entities.value");

                ExtractTopEntityMetadata(entities, outRecord.Data);
                outRecord.Data["entities"] = entities;
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #3
0
        public async Task <IActionResult> RunVideoIndexer(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Video Indexer Custom Skill: C# HTTP trigger function processed a request");

            var skillName      = executionContext.FunctionName;
            var requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            var response = await WebApiSkillHelpers.ProcessRequestRecordsAsync(skillName,
                                                                               requestRecords,
                                                                               async (inRecord, outRecord) =>
            {
                var encodedVideoUrl = (string)inRecord.Data["metadata_storage_path"];
                var videoUrl        = UrlSafeBase64Decode(encodedVideoUrl);
                var videoName       = (string)inRecord.Data["metadata_storage_name"];
                var sasKey          = await _videoIndexerBlobClient.GetSasKey(videoUrl);
                var videoId         = await _videoIndexerClient.SubmitVideoIndexingJob(videoUrl + sasKey, encodedVideoUrl, videoName);
                log.LogInformation("Uploaded video {VideoName} - Video Id in indexer: {Id}", videoName, videoId);
                outRecord.Data["videoId"] = videoId;
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, TraceWriter log, ExecutionContext executionContext)
        {
            log.Info("C# HTTP trigger function processed a request.");
            string skillName = executionContext.FunctionName;

            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(req.CreateErrorResponse(HttpStatusCode.BadRequest, $"{skillName} - Invalid request record array."));
            }
            dynamic obj = requestRecords.First().Data.First().Value;

            string val = await MakeRequest(obj);

            ContentModerator     mod    = JsonConvert.DeserializeObject <ContentModerator>(val);
            WebApiResponseRecord output = new WebApiResponseRecord();

            output.RecordId    = requestRecords.First().RecordId;
            output.Data["PII"] = mod.PII;
            WebApiSkillResponse resp = new WebApiSkillResponse();

            resp.Values = new List <WebApiResponseRecord>();
            resp.Values.Add(output);
            return(req.CreateResponse(HttpStatusCode.OK, resp));
        }
        public static IActionResult RunAcronymLinker(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Link Acronyms Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            AcronymLinker       acronymLinker = new AcronymLinker(executionContext.FunctionAppDirectory);
            WebApiSkillResponse response      = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                         (inRecord, outRecord) => {
                string word = inRecord.Data["word"] as string;
                if (word.All(char.IsUpper) && acronymLinker.Acronyms.TryGetValue(word, out string description))
                {
                    outRecord.Data["acronym"] = new { value = word, description };
                }
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #6
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"GetMetaData - Invalid request record array."));
            }


            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords("GetMetaData", requestRecords,
                                                                                    (inRecord, outRecord) =>
            {
                var input1 = inRecord.Data["field_1"].ToString();
                var input2 = inRecord.Data["field_2"].ToString();

                outRecord.Data["output_field_1"] = input1;
                outRecord.Data["output_field_2"] = input2;
                return(outRecord);
            });

            return((ActionResult) new OkObjectResult(response));
        }
        public static IActionResult RunHocrGenerator(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("hOCR Generator Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null || requestRecords.Count() != 1)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array: Skill requires exactly 1 image per request."));
            }

            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) => {
                List <OcrImageMetadata> imageMetadataList = ((JArray)inRecord.Data["ocrImageMetadataList"]).ToObject <List <OcrImageMetadata> >();
                Dictionary <string, string> annotations   = ((JArray)inRecord.Data["wordAnnotations"])
                                                            .Where(o => o.Type != JTokenType.Null)
                                                            .GroupBy(o => o["value"].Value <string>())
                                                            .Select(g => g.First())
                                                            .ToDictionary(o => o["value"].Value <string>(), o => o["description"].Value <string>());

                List <HocrPage> pages = imageMetadataList
                                        .Select((imageMetadata, i) => new HocrPage(imageMetadata, i, annotations))
                                        .ToList();

                outRecord.Data["hocrDocument"] = new HocrDocument(pages);

                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #8
0
        public static IActionResult RunUploadToQnaMaker(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            [Queue("upload-to-qna"), StorageAccount("AzureWebJobsStorage")] ICollector <QnAQueueMessageBatch> msg,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("UploadToQnAMaker Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }
            var msgBatch = new QnAQueueMessageBatch();
            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) =>
            {
                string id          = (inRecord.Data.TryGetValue("id", out object idObject) ? idObject : null) as string;
                string blobName    = (inRecord.Data.TryGetValue("blobName", out object blobNameObject) ? blobNameObject : null) as string;
                string blobUrl     = (inRecord.Data.TryGetValue("blobUrl", out object blobUrlObject) ? blobUrlObject : null) as string;
                string sasToken    = (inRecord.Data.TryGetValue("sasToken", out object sasTokenObject) ? sasTokenObject : null) as string;
                long blobSizeInKBs = (inRecord.Data.TryGetValue("blobSize", out object blobSizeObject) ? (long)blobSizeObject : 0) / 1024;

                if (string.IsNullOrWhiteSpace(blobUrl))
                {
                    outRecord.Errors.Add(new WebApiErrorWarningContract()
                    {
                        Message = $"Parameter '{nameof(blobUrl)}' is required to be present and a valid uri."
                    });
                    return(outRecord);
                }

                string fileUri = WebApiSkillHelpers.CombineSasTokenWithUri(blobUrl, sasToken);

                if (!IsValidFile(blobName, blobSizeInKBs))
                {
                    log.LogError("upload-to-qna-queue-trigger: unable to extract qnas from this file " + blobName + " of size " + blobSizeInKBs);
                    outRecord.Data["status"] = "Failed";
                }
                else
                {
                    var queueMessage = new QnAQueueMessage
                    {
                        Id       = id,
                        FileName = blobName,
                        FileUri  = fileUri
                    };
                    msgBatch.Values.Add(queueMessage);
                    if (msgBatch.Values.Count >= 10)
                    {
                        msg.Add(msgBatch);
                        msgBatch.Values.Clear();
                    }
                    outRecord.Data["status"] = "InQueue";
                }
                return(outRecord);
            });
        public static IActionResult RunDecryptBlobFile(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("DecryptBlobFile Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            // Set up access to keyvault to retrieve the key to decrypt the document with
            // Requires that this Azure Function has access via managed identity to the Keyvault where the key is stored.
            var azureServiceTokenProvider1 = new AzureServiceTokenProvider();
            var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider1.KeyVaultTokenCallback));
            KeyVaultKeyResolver  cloudResolver = new KeyVaultKeyResolver(kv);
            BlobEncryptionPolicy policy        = new BlobEncryptionPolicy(null, cloudResolver);
            BlobRequestOptions   options       = new BlobRequestOptions()
            {
                EncryptionPolicy = policy
            };

            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) =>
            {
                string blobUrl  = (inRecord.Data.TryGetValue("blobUrl", out object blobUrlObject) ? blobUrlObject : null) as string;
                string sasToken = (inRecord.Data.TryGetValue("sasToken", out object sasTokenObject) ? sasTokenObject : null) as string;

                if (string.IsNullOrWhiteSpace(blobUrl))
                {
                    outRecord.Errors.Add(new WebApiErrorWarningContract()
                    {
                        Message = $"Parameter '{nameof(blobUrl)}' is required to be present and a valid uri."
                    });
                    return(outRecord);
                }

                CloudBlockBlob blob = new CloudBlockBlob(new Uri(WebApiSkillHelpers.CombineSasTokenWithUri(blobUrl, sasToken)));
                byte[] decryptedFileData;
                using (var np = new MemoryStream())
                {
                    blob.DownloadToStream(np, null, options, null);
                    decryptedFileData = np.ToArray();
                }
                FileReference decryptedFileReference = new FileReference()
                {
                    data = Convert.ToBase64String(decryptedFileData)
                };
                JObject jObject  = JObject.FromObject(decryptedFileReference);
                jObject["$type"] = "file";
                outRecord.Data["decrypted_file_data"] = jObject;
                return(outRecord);
            });
        public static async Task <IActionResult> RunAnalyzeForm(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Analyze Form Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            string formsRecognizerApiKey = Environment.GetEnvironmentVariable(formsRecognizerApiKeySetting, EnvironmentVariableTarget.Process);
            string modelId = Environment.GetEnvironmentVariable(modelIdSetting, EnvironmentVariableTarget.Process);

            WebApiSkillResponse response = await WebApiSkillHelpers.ProcessRequestRecordsAsync(skillName, requestRecords,
                                                                                               async (inRecord, outRecord) => {
                var formUrl      = inRecord.Data["formUrl"] as string;
                var formSasToken = inRecord.Data["formSasToken"] as string;

                // Fetch the document
                byte[] documentBytes;
                using (var webClient = new WebClient())
                {
                    documentBytes = await webClient.DownloadDataTaskAsync(new Uri(formUrl + formSasToken));
                }

                string uri = formsRecognizerApiEndpoint + "/models/" + Uri.EscapeDataString(modelId) + "/analyze";

                List <Page> pages =
                    (await WebApiSkillHelpers.FetchAsync <Page>(
                         uri,
                         apiKeyHeader: "Ocp-Apim-Subscription-Key",
                         apiKey: formsRecognizerApiKey,
                         collectionPath: "pages",
                         method: HttpMethod.Post,
                         postBody: documentBytes,
                         contentType))
                    .ToList();

                foreach (KeyValuePair <string, string> kvp in fieldMappings)
                {
                    var value = GetField(pages, kvp.Key);
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        outRecord.Data[kvp.Value] = value;
                    }
                }
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #11
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, TraceWriter log, ExecutionContext executionContext)
        {
            log.Info("C# HTTP trigger function processed a request.");
            string skillName = executionContext.FunctionName;

            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(req.CreateErrorResponse(HttpStatusCode.BadRequest, $"{skillName} - Invalid request record array."));
            }
            dynamic obj = requestRecords.First().Data.First().Value;

            if (obj.Length > 1024)
            {
                obj = obj.Substring(0, 1024);
            }

            string val = await MakeRequest(obj);

            ContentModerator mod = JsonConvert.DeserializeObject <ContentModerator>(val);

            bool requiresModeration = false;

            //Jon Dobrzeniecki helped with the code below, since may 2019 the CM API isn't returning the PII section if there is no data for it
            if (mod.PII != null)
            {
                if (mod.PII.Email.Length > 0)
                {
                    requiresModeration = true;
                }
                if (mod.PII.Address.Length > 0)
                {
                    requiresModeration = true;
                }
                if (mod.PII.IPA.Length > 0)
                {
                    requiresModeration = true;
                }
                if (mod.PII.Phone.Length > 0)
                {
                    requiresModeration = true;
                }
            }
            WebApiResponseRecord output = new WebApiResponseRecord();

            output.RecordId     = requestRecords.First().RecordId;
            output.Data["text"] = requiresModeration;

            WebApiSkillResponse resp = new WebApiSkillResponse();

            resp.Values = new List <WebApiResponseRecord>();
            resp.Values.Add(output);
            return(req.CreateResponse(HttpStatusCode.OK, resp));
        }
        public static async Task <IActionResult> RunCustomVision(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Custom Vision Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }


            var predictionUrl = Environment.GetEnvironmentVariable(customVisionPredictionUrlSetting, EnvironmentVariableTarget.Process);
            var predictionKey = Environment.GetEnvironmentVariable(customVisionApiKeySetting, EnvironmentVariableTarget.Process);
            var maxPages      = Convert.ToInt32(Environment.GetEnvironmentVariable(maxPagesSetting, EnvironmentVariableTarget.Process));

            if (maxPages == 0)
            {
                maxPages = 1;
            }
            var threshold = Convert.ToDouble(Environment.GetEnvironmentVariable(minProbabilityThresholdSetting, EnvironmentVariableTarget.Process));

            if (threshold == 0.0)
            {
                threshold = 0.5;
            }

            WebApiSkillResponse response = await WebApiSkillHelpers.ProcessRequestRecordsAsync(skillName, requestRecords,
                                                                                               async (inRecord, outRecord) => {
                var pages       = inRecord.Data["pages"] as JArray;
                var tags        = new List <string>();
                var predictions = new List <object>();
                foreach (var page in pages.Take(maxPages))
                {
                    var pageBinaryData  = Convert.FromBase64String(page.ToString());
                    var pagePredictions = await GetPredictionsForImageAsync(pageBinaryData, predictionUrl, predictionKey);

                    var analyzeResult = JsonConvert.DeserializeObject <AnalyzeResult>(pagePredictions);
                    var pageTags      = analyzeResult.Predictions.Where(p => p.Probability >= threshold).Select(p => p.TagName).Distinct();
                    tags.AddRange(pageTags);
                }

                outRecord.Data["tags"] = tags.Distinct().ToArray();
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
        public static IActionResult RunProjection(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log, ExecutionContext executionContext)
        {
            log.LogInformation("Projection: C# HTTP trigger function processed a request.");
            string skillName = executionContext.FunctionName;

            log.LogInformation($"REQUEST: {new StreamReader(req.Body).ReadToEnd()}");
            req.Body.Position = 0;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }
            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) =>
            {
                Conversation[] turns       = JsonConvert.DeserializeObject <Conversation[]>(inRecord.Data["conversation"].ToString());
                List <Conversation> output = turns.ToList <Conversation>();
                if (output == null || output.All(x => x == null))
                {
                    outRecord.Data["result"]  = null;
                    outRecord.Data["summary"] = null;
                    return(outRecord);
                }
                var sortedList = output.OrderBy(foo => foo.offset).ToList();
                ConversationSummary summary = new ConversationSummary();
                summary.Turns = turns.Length;
                if (sortedList.Where(c => c.speaker == "1").FirstOrDefault() == null)
                {
                    summary.AverageSentiment = 0;
                    summary.LowestSentiment  = 0;
                    summary.HighestSentiment = 0;
                    summary.MaxChange        = new Tuple <int, float>(0, 0.0f);
                }
                else
                {
                    summary.AverageSentiment = sortedList.Where(c => c.speaker == "1").Select(a => a.sentiment).Average();
                    summary.LowestSentiment  = sortedList.Where(c => c.speaker == "1").Select(a => a.sentiment).Min();
                    summary.HighestSentiment = sortedList.Where(c => c.speaker == "1").Select(a => a.sentiment).Max();
                    //summary.MaxChange = ConversationSummary.MaxDiff(sortedList.Where(c => c.speaker == "1").Select(a => a.sentiment).ToList());
                    summary.Moment = ConversationSummary.GetKeyMoment(sortedList);
                }
                outRecord.Data["result"]  = sortedList;
                outRecord.Data["summary"] = summary;
                return(outRecord);
            });

            log.LogInformation(JsonConvert.SerializeObject(response));
            return(new OkObjectResult(response));
        }
        public static IActionResult RunGetFileExtension(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
            ExecutionContext executionContext, ILogger log)
        {
            var config = new ConfigurationBuilder()
                         .SetBasePath(executionContext.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();

            string skillName = executionContext.FunctionName;

            log.LogInformation($"{skillName} Custom Skill: C# HTTP trigger function processed a request.");

            var requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            var response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                    (inRecord, outRecord) =>
            {
                try
                {
                    var documentName = inRecord.Data["documentName"] as string;
                    var extension    = "";
                    var fileName     = "";

                    if (!string.IsNullOrWhiteSpace(documentName))
                    {
                        extension = Path.GetExtension(documentName);
                        fileName  = Path.GetFileNameWithoutExtension(documentName);
                    }

                    outRecord.Data.Add("extension", extension);
                    outRecord.Data.Add("fileName", fileName);
                }
                catch (Exception e)
                {
                    outRecord.Errors.Add(new WebApiErrorWarningContract {
                        Message = e.ToString()
                    });
                }

                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
        public static async Task <IActionResult> RunStoreImage(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Image Store Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null || requestRecords.Count() != 1)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array: Skill requires exactly 1 image per request."));
            }

            string blobStorageConnectionString = Environment.GetEnvironmentVariable(blobStorageConnectionStringSetting, EnvironmentVariableTarget.Process);
            string blobContainerName           = String.IsNullOrEmpty(req.Headers[blobContainerHeaderName])
                ? Environment.GetEnvironmentVariable(blobStorageContainerNameSetting, EnvironmentVariableTarget.Process)
                : (string)req.Headers[blobContainerHeaderName];

            if (String.IsNullOrEmpty(blobStorageConnectionString) || String.IsNullOrEmpty(blobContainerName))
            {
                return(new BadRequestObjectResult($"{skillName} - Information for the blob storage account is missing"));
            }
            var imageStore = new BlobImageStore(blobStorageConnectionString, blobContainerName);

            WebApiSkillResponse response = await WebApiSkillHelpers.ProcessRequestRecordsAsync(skillName, requestRecords,
                                                                                               async (inRecord, outRecord) => {
                var imageData = inRecord.Data["imageData"] as string;
                var imageName = inRecord.Data["imageName"] as string;
                if (String.IsNullOrEmpty(imageName))
                {
                    imageName = Guid.NewGuid().ToString();
                }
                var mimeType = inRecord.Data["mimeType"] as string;
                if (String.IsNullOrEmpty(mimeType))
                {
                    mimeType = "image/jpeg";
                }
                string imageUri = await imageStore.UploadToBlobAsync(imageData, imageName, mimeType);
                outRecord.Data["imageStoreUri"] = imageUri;
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #16
0
        public static IActionResult RunKewit(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log, ExecutionContext executionContext)
        {
            log.LogInformation("Projection: C# HTTP trigger function processed a request.");
            string skillName = executionContext.FunctionName;

            log.LogInformation($"REQUEST: {new StreamReader(req.Body).ReadToEnd()}");
            req.Body.Position = 0;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }
            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) =>
            {
                string content = inRecord.Data["text"].ToString();
                string regex   = inRecord.Data["regex"].ToString();
                if (regex == null)
                {
                    regex = "^[A-Z]{2,5}$";
                }
                Regex rx = new Regex(regex);
                MatchCollection matches = rx.Matches(content);
                foreach (Match match in matches)
                {
                    GroupCollection groups = match.Groups;
                    Console.WriteLine("'{0}' repeated at positions {1} and {2}",
                                      groups["word"].Value,
                                      groups[0].Index,
                                      groups[1].Index);
                }
                var list = matches.Cast <Match>().Select(match => new { match.Value, match.Index }).ToList();
                outRecord.Data["matches"] = list;

                return(outRecord);
            });

            //log.LogInformation(JsonConvert.SerializeObject(response));
            return(new OkObjectResult(response));
        }
        public static async Task <IActionResult> RunDistinct(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Distinct Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            Thesaurus thesaurus = null;

            try
            {
                thesaurus = new Thesaurus(executionContext.FunctionAppDirectory);
            }
            catch (Exception e)
            {
                throw new Exception("Failed to read and parse thesaurus.json.", e);
            }
            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) =>
            {
                JArray wordsParameter = inRecord.Data.TryGetValue("words", out object wordsParameterObject) ?
                                        wordsParameterObject as JArray : null;
                if (wordsParameter is null)
                {
                    throw new ArgumentException("Input data is missing a `words` array of words to de-duplicate.", "words");
                }
                var words = wordsParameter.Values <string>();
                outRecord.Data["distinct"] = thesaurus.Dedupe(words);
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, TraceWriter log, ExecutionContext executionContext)
        {
            try
            {
                log.Info("C# HTTP trigger function processed a request.");

                string skillName = executionContext.FunctionName;

                IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);
                if (requestRecords == null)
                {
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, $"{skillName} - Invalid request record array."));
                }
                log.Info($"Content Moderator : {requestRecords.ToString()}");
                dynamic obj = requestRecords.First().Data.First().Value;
                log.Info($"Content Moderator : {obj.ToString()}");

                string val = await MakeRequest(obj);

                ContentModerator     mod    = JsonConvert.DeserializeObject <ContentModerator>(val);
                WebApiResponseRecord output = new WebApiResponseRecord();
                output.RecordId = requestRecords.First().RecordId;
                if (mod.PII.Email.Length > 0)
                {
                    output.Data["PII"] = mod.PII.Email.FirstOrDefault().Detected;
                }
                else
                {
                    output.Data["PII"] = null;
                }
                WebApiSkillResponse resp = new WebApiSkillResponse();
                resp.Values = new List <WebApiResponseRecord>();
                resp.Values.Add(output);
                return(req.CreateResponse(HttpStatusCode.OK, resp));
            }
            catch (System.Exception ex)
            {
                log.Info(ex.StackTrace);
            }
            return(null);
        }
        public static async Task <IActionResult> RunCustomEntityLookup(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Custom Entity Search function: C# HTTP trigger function processed a request.");

            if (_impl == null || executionContext.FunctionName == "unitTestFunction")
            {
                _impl = new CustomEntityLookupImplementation(CustomEntitiesDefinition.ParseCustomEntityDefinition(EntityDefinitionLocation));
            }

            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{executionContext.FunctionName} - Invalid request record array."));
            }

            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(executionContext.FunctionName, requestRecords,
                                                                                    (inRecord, outRecord) =>
            {
                if (!inRecord.Data.ContainsKey("text") || inRecord.Data["text"] == null)
                {
                    outRecord.Errors.Add(new WebApiErrorWarningContract {
                        Message = "Cannot process record without the given key 'text' with a string value"
                    });
                    return(outRecord);
                }

                string text = inRecord.Data["text"] as string;

                var foundEntities = _impl.GetCustomLookupResult(text, System.Threading.CancellationToken.None);

                outRecord.Data["entities"] = foundEntities;
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
        public static async Task <IActionResult> RunGeoPointFromName(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Geo Point From Name Custom skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            string azureMapsKey = Environment.GetEnvironmentVariable(azureMapsKeySetting, EnvironmentVariableTarget.Process);

            WebApiSkillResponse response = await WebApiSkillHelpers.ProcessRequestRecordsAsync(skillName, requestRecords,
                                                                                               async (inRecord, outRecord) => {
                var address = inRecord.Data["address"] as string;
                string uri  = azureMapsUri
                              + "?api-version=1.0&query=" + Uri.EscapeDataString(address)
                              + "&subscription-key=" + Uri.EscapeDataString(azureMapsKey);

                IEnumerable <Geography> geographies =
                    await WebApiSkillHelpers.FetchAsync <Geography>(uri, "results");

                if (geographies.FirstOrDefault() is Geography mainGeoPoint)
                {
                    outRecord.Data["mainGeoPoint"] = new {
                        Type        = "Point",
                        Coordinates = new double[] { mainGeoPoint.Position.Lon, mainGeoPoint.Position.Lat }
                    };
                }
                outRecord.Data["results"] = geographies;
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #21
0
        public static IActionResult RunTokenizer(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Tokenizer Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) =>
            {
                var text = new TextData {
                    Text = inRecord.Data["text"] as string
                };
                StopWordsRemovingEstimator.Language language =
                    MapToMlNetLanguage(inRecord.Data.TryGetValue("languageCode", out object languageCode) ? languageCode as string : "en");

                var mlContext           = new MLContext();
                IDataView emptyDataView = mlContext.Data.LoadFromEnumerable(new List <TextData>());
                EstimatorChain <StopWordsRemovingTransformer> textPipeline = mlContext.Transforms.Text
                                                                             .NormalizeText("Text", caseMode: TextNormalizingEstimator.CaseMode.Lower, keepDiacritics: true, keepPunctuations: false, keepNumbers: false)
                                                                             .Append(mlContext.Transforms.Text.TokenizeIntoWords("Words", "Text", separators: new[] { ' ' }))
                                                                             .Append(mlContext.Transforms.Text.RemoveDefaultStopWords("Words", language: language));
                TransformerChain <StopWordsRemovingTransformer> textTransformer   = textPipeline.Fit(emptyDataView);
                PredictionEngine <TextData, TransformedTextData> predictionEngine = mlContext.Model.CreatePredictionEngine <TextData, TransformedTextData>(textTransformer);

                outRecord.Data["words"] = predictionEngine.Predict(text).Words ?? Array.Empty <string>();
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #22
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)

        {
            log.LogInformation("ABBYY OCR Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            // Create the response record
            WebApiSkillResponse response = new WebApiSkillResponse();

            using (var ocrClient = GetOcrClientWithRetryPolicy())
            {
                List <Task> TaskList = new List <Task>();
                int         idx      = 0;
                foreach (var record in requestRecords)
                {
                    TaskList.Add(ProcessRecord(record, ocrClient, idx));
                    idx += 1;
                }
                Task.WaitAll(TaskList.ToArray());

                // Apply all the records from the concurrent bag
                foreach (var record in bag)
                {
                    response.Values.Add(record);
                }
            }

            return(new OkObjectResult(response));
        }
        public static async Task <IActionResult> RunJapaneseOCR(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("JapaneseOCR remove spaces Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) => {
                var inputText             = inRecord.Data["text"] as string;
                outRecord.Data["ocrtext"] = "";

                if (string.IsNullOrEmpty(inputText))
                {
                    return(outRecord);
                }

                // 正規表現で全角文字+半白スペースの場合、半角スペースのみを除去
                var newContent = Regex.Replace(inputText, @"([^\x01-\x7E])\x20", "$1");
                // 全角文字+ハイフン+半角スペースの場合、ハイフンを全角長音に変換し半角スペースを除去
                newContent = Regex.Replace(newContent, @"([^\x01-\x7E])-\x20?", "$1ー");

                log.LogInformation($"newContent:  {newContent}");

                outRecord.Data["ocrtext"] = newContent;

                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #24
0
        public static async Task <IActionResult> RunHelloWorld(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Hello World Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) => {
                var name = inRecord.Data["name"] as string;
                outRecord.Data["greeting"] = $"Hello, {name}";
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #25
0
        public static async Task <IActionResult> RunAnalyzeForm(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Analyze Form Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            string formsRecognizerEndpointUrl = Environment.GetEnvironmentVariable(formsRecognizerApiEndpointSetting, EnvironmentVariableTarget.Process).TrimEnd('/');
            string formsRecognizerApiKey      = Environment.GetEnvironmentVariable(formsRecognizerApiKeySetting, EnvironmentVariableTarget.Process);


            // string modelId = Environment.GetEnvironmentVariable(modelIdSetting, EnvironmentVariableTarget.Process);

            int retryDelay  = int.TryParse(Environment.GetEnvironmentVariable(retryDelaySetting, EnvironmentVariableTarget.Process), out int parsedRetryDelay) ? parsedRetryDelay : 1000;
            int maxAttempts = int.TryParse(Environment.GetEnvironmentVariable(maxAttemptsSetting, EnvironmentVariableTarget.Process), out int parsedMaxAttempts) ? parsedMaxAttempts : 100;

            Dictionary <string, string> fieldMappings = JsonConvert.DeserializeObject <Dictionary <string, string> >(
                File.ReadAllText($"{executionContext.FunctionAppDirectory}\\field-mappings.json"));

            WebApiSkillResponse response = await WebApiSkillHelpers.ProcessRequestRecordsAsync(skillName, requestRecords,
                                                                                               async (inRecord, outRecord) => {
                var formUrl      = inRecord.Data["formUrl"] as string;
                var formSasToken = inRecord.Data["formSasToken"] as string;
                string formUri   = WebApiSkillHelpers.CombineSasTokenWithUri(formUrl, formSasToken);

                // Create the job
                string jobId = await GetJobId(formsRecognizerEndpointUrl, formUri, formsRecognizerApiKey);

                // Get the results
                for (int attempt = 0; attempt < maxAttempts; attempt++)
                {
                    (string status, JToken result) = await GetJobStatus(jobId, formsRecognizerApiKey);
                    if (status == "failed")
                    {
                        var errors = result.SelectToken("analyzeResult.errors") as JArray;
                        outRecord.Errors.AddRange(errors.Children().Select(error => new WebApiErrorWarningContract
                        {
                            Message = error.SelectToken("message").ToObject <string>()
                        }));
                        return(outRecord);
                    }
                    if (status == "succeeded")
                    {
                        //List<Page> pages = result.SelectToken("analyzeResult.pageResults").ToObject<List<Page>>();


                        List <Page> pages = result.SelectToken("analyzeResult.readResults").ToObject <List <Page> >();


                        foreach (KeyValuePair <string, string> kvp in fieldMappings)
                        {
                            string value = GetField(pages, kvp.Key);
                            if (!string.IsNullOrWhiteSpace(value))
                            {
                                outRecord.Data[kvp.Value] = value;
                            }
                        }
                        return(outRecord);
                    }
                    await Task.Delay(retryDelay);
                }
                outRecord.Errors.Add(new WebApiErrorWarningContract
                {
                    Message = $"The forms recognizer did not finish the job after {maxAttempts} attempts."
                });
                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
Beispiel #26
0
        public static async Task <IActionResult> RunCustomEntitySearch(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            if (preLoadedWords == null)
            {
                preLoadedWords = WordLinker.WordLink(executionContext.FunctionAppDirectory, "csv").Words;
            }

            log.LogInformation("Custom Entity Search function: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) => {
                if (!inRecord.Data.ContainsKey("text") || inRecord.Data["text"] == null)
                {
                    outRecord.Errors.Add(new WebApiErrorWarningContract {
                        Message = "Cannot process record without the given key 'text' with a string value"
                    });
                    return(outRecord);
                }
                if (!inRecord.Data.ContainsKey("words") &&
                    (inRecord.Data.ContainsKey("synonyms") || inRecord.Data.ContainsKey("exactMatches") || inRecord.Data.ContainsKey("fuzzyMatchOffset")))
                {
                    outRecord.Errors.Add(new WebApiErrorWarningContract
                    {
                        Message = "Cannot process record without the given key 'words' in the dictionary"
                    });
                    return(outRecord);
                }
                string text = inRecord.Data["text"] as string;
                IList <string> words;
                if (inRecord.Data.ContainsKey("words") == true)
                {
                    words = inRecord.GetOrCreateList <List <string> >("words");
                }
                else
                {
                    outRecord.Warnings.Add(new WebApiErrorWarningContract
                    {
                        Message = "Used predefined key words from customLookupSkill configuration file " +
                                  "since no 'words' parameter was supplied in web request"
                    });
                    words = preLoadedWords;
                }
                Dictionary <string, string[]> synonyms = inRecord.GetOrCreateDictionary <Dictionary <string, string[]> >("synonyms");
                IList <string> exactMatches            = inRecord.GetOrCreateList <List <string> >("exactMatches");
                int offset         = (inRecord.Data.ContainsKey("fuzzyMatchOffset")) ? Math.Max(0, Convert.ToInt32(inRecord.Data["fuzzyMatchOffset"])) : 0;
                bool caseSensitive = (inRecord.Data.ContainsKey("caseSensitive")) ? (bool)inRecord.Data.ContainsKey("caseSensitive") : false;
                if (words.Count == 0 || (words.Count(word => !String.IsNullOrEmpty(word)) == 0))
                {
                    try
                    {
                        WordLinker userInput = WordLinker.WordLink(executionContext.FunctionDirectory, "json");
                        words         = userInput.Words;
                        synonyms      = userInput.Synonyms;
                        exactMatches  = userInput.ExactMatch;
                        offset        = (userInput.FuzzyMatchOffset >= 0) ? userInput.FuzzyMatchOffset : 0;
                        caseSensitive = userInput.CaseSensitive;
                        outRecord.Warnings.Add(new WebApiErrorWarningContract
                        {
                            Message = "Used predefined key words from customLookupSkill configuration file " +
                                      "since no 'words' parameter was supplied in web request"
                        });
                    }
                    catch (Exception)
                    {
                        outRecord.Errors.Add(new WebApiErrorWarningContract
                        {
                            Message = "Could not parse predefined words.json"
                        });
                        return(outRecord);
                    }
                }

                var entities      = new List <Entity>();
                var entitiesFound = new HashSet <string>();
                if (!string.IsNullOrWhiteSpace(text))
                {
                    foreach (string word in words)
                    {
                        if (string.IsNullOrEmpty(word))
                        {
                            continue;
                        }
                        int leniency         = (exactMatches != null && exactMatches.Contains(word)) ? 0 : offset;
                        string wordCharArray = (caseSensitive) ? CreateWordArray(word) : CreateWordArray(word.ToLower(CultureInfo.CurrentCulture));
                        if (leniency >= wordCharArray.Length)
                        {
                            outRecord.Warnings.Add(new WebApiErrorWarningContract
                            {
                                Message = @"The provided fuzzy offset of " + leniency + @", is larger than the length of the provided word, """ + word + @"""."
                            });
                            leniency = Math.Max(0, wordCharArray.Length - 1);
                        }
                        AddValues(word, text, wordCharArray, entities, entitiesFound, leniency, caseSensitive);
                        if (synonyms.TryGetValue(word, out string[] wordSynonyms))
                        {
                            foreach (string synonym in wordSynonyms)
                            {
                                leniency = (exactMatches != null && exactMatches.Contains(synonym)) ? 0 : offset;
                                string synonymCharArray = (caseSensitive) ? CreateWordArray(synonym) : CreateWordArray(synonym.ToLower(CultureInfo.CurrentCulture));
                                if (leniency >= synonym.Length)
                                {
                                    outRecord.Warnings.Add(new WebApiErrorWarningContract
                                    {
                                        Message = @"The provided fuzzy offset of " + leniency + @", is larger than the length of the provided synonym, """ + synonym + @"""."
                                    });
                                    leniency = Math.Max(0, synonymCharArray.Length - 1);
                                }
                                AddValues(synonym, text, synonymCharArray, entities, entitiesFound, leniency, caseSensitive);
                            }
                        }
                    }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            Microsoft.Azure.WebJobs.ExecutionContext executionContext)
        {
            log.LogInformation("LUIS-D Extractor and Classifier function");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }



            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) => {
                var text = inRecord.Data["text"] as string;
                Dictionary <string, string> luisQuery = new Dictionary <string, string>();
                luisQuery.Add("query", text);
                string luisInput = JsonConvert.SerializeObject(luisQuery);

                //call luis
                log.LogInformation("Sending the document to LUIS-D for classification and extraction");

                string operationId = null;
                using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, string.Format(LUISPredictionendpoint, LUISAppId)))
                {
                    requestMessage.Headers.Add("Ocp-Apim-Subscription-Key", LUISPredictionKey);
                    requestMessage.Content = new StringContent(luisInput);
                    requestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                    HttpResponseMessage response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult();

                    operationId = JsonConvert.DeserializeObject <Dictionary <string, string> >(response.Content.ReadAsStringAsync().GetAwaiter().GetResult())["operationId"];
                }


                log.LogInformation("Checking for classification and extraction status...");

                string status = null;
                do
                {
                    Thread.Sleep(1000);
                    using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, string.Format(LUISCheckOperationStatusEndpoint, LUISAppId, operationId)))
                    {
                        requestMessage.Headers.Add("Ocp-Apim-Subscription-Key", LUISPredictionKey);

                        HttpResponseMessage response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult();
                        status = JsonConvert.DeserializeObject <Dictionary <string, string> >(response.Content.ReadAsStringAsync().GetAwaiter().GetResult())["status"];
                    }

                    log.LogInformation($"Extraction status: {status}");
                }while (status != "succeeded" && status != "failed");



                if (status == "succeeded")
                {
                    LUISResult luisResult = null;
                    log.LogInformation("Downloading for classification and extraction results...");

                    using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, string.Format(LUISGetResultEndpoint, LUISAppId, operationId)))
                    {
                        requestMessage.Headers.Add("Ocp-Apim-Subscription-Key", LUISPredictionKey);

                        HttpResponseMessage response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult();
                        luisResult = JsonConvert.DeserializeObject <LUISResult>(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
                    }

                    Dictionary <string, object> output = new Dictionary <string, object>();

                    if (luisResult.prediction.classifiers != null && luisResult.prediction.classifiers.Count > 0)
                    {
                        outRecord.Data.Add("Class", luisResult.prediction.classifiers.First().Value);
                    }

                    foreach (var entity in luisResult.prediction.extractors)
                    {
                        if (entity.Key != "$instance")
                        {
                            outRecord.Data.Add(entity.Key, entity.Value);
                        }
                    }


                    outRecord.Data["result"] = "success";
                }
                else
                {
                    outRecord.Data["result"] = "failed";
                }


                return(outRecord);
            });

            return(new OkObjectResult(response));
        }
        public static async Task <IActionResult> RunSplitImageSkill(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext executionContext)
        {
            log.LogInformation("Split Image Custom Skill: C# HTTP trigger function processed a request.");

            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(new BadRequestObjectResult($"{skillName} - Invalid request record array."));
            }

            WebApiSkillResponse response = WebApiSkillHelpers.ProcessRequestRecords(skillName, requestRecords,
                                                                                    (inRecord, outRecord) => {
                var imageUrl = (inRecord.Data.TryGetValue("imageLocation", out object imageUrlObject) ? imageUrlObject : null) as string;
                var sasToken = (inRecord.Data.TryGetValue("imageLocation", out object sasTokenObject) ? sasTokenObject : null) as string;

                if (string.IsNullOrWhiteSpace(imageUrl))
                {
                    outRecord.Errors.Add(new WebApiErrorWarningContract()
                    {
                        Message = "Parameter 'imageUrl' is required to be present and a valid uri."
                    });
                    return(outRecord);
                }

                JArray splitImages = new JArray();

                using (WebClient client = new WebClient())
                {
                    byte[] fileData = executionContext.FunctionName == "unitTestFunction"
                                            ? fileData = File.ReadAllBytes(imageUrl)                                               // this is a unit test, find the file locally
                                            : fileData = client.DownloadData(new Uri(CombineSasTokenWithUri(imageUrl, sasToken))); // download the file from remote server

                    using (var stream = new MemoryStream(fileData))
                    {
                        var originalImage = Image.Load(stream);

                        // chunk the document up into pieces
                        // overlap the chunks to reduce the chances of cutting words in half
                        // (and not being able to OCR that data)
                        for (int x = 0; x < originalImage.Width; x += (MaxImageDimension - ImageOverlapInPixels))
                        {
                            for (int y = 0; y < originalImage.Height; y += (MaxImageDimension - ImageOverlapInPixels))
                            {
                                int startX = x;
                                int endX   = x + MaxImageDimension >= originalImage.Width
                                                ? originalImage.Width
                                                : x + MaxImageDimension;
                                int startY = y;
                                int endY   = y + MaxImageDimension >= originalImage.Height
                                                ? originalImage.Height
                                                : y + MaxImageDimension;

                                var newImageData = CropImage(originalImage, startX, endX, startY, endY);

                                var imageData       = new JObject();
                                imageData["$type"]  = "file";
                                imageData["data"]   = System.Convert.ToBase64String(newImageData);
                                imageData["width"]  = endX - startX;
                                imageData["height"] = endY - startY;
                                splitImages.Add(imageData);
                            }
                        }
                    }
                }

                outRecord.Data["splitImages"] = splitImages;
                return(outRecord);
            });
Beispiel #29
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, TraceWriter log, ILogger logger, ExecutionContext executionContext)
        {
            string skillName = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(req.CreateErrorResponse(HttpStatusCode.BadRequest, $"{skillName} - Invalid request record array."));
            }
            WebApiSkillResponse resp = new WebApiSkillResponse();

            resp.Values = new List <WebApiResponseRecord>();
            foreach (WebApiRequestRecord reqRec in requestRecords)
            {
                double lat                  = Convert.ToDouble(reqRec.Data["latitude"]);
                double lng                  = Convert.ToDouble(reqRec.Data["longitude"]);
                double review               = Convert.ToDouble(reqRec.Data["reviews_rating"]);
                string language             = (string)reqRec.Data["language"];
                WebApiResponseRecord output = new WebApiResponseRecord();
                try
                {
                    if (review > 5)
                    {
                        review = review / 2;
                    }

                    Address addr = await reverseGeocode(lat, lng, logger);

                    if (addr != null)
                    {
                        output.Data["state"]   = addr.adminDistrict;
                        output.Data["country"] = addr.countryRegion;
                    }
                    else
                    {
                        output.Data["state"]   = "UNKNOWN";
                        output.Data["country"] = "UNKNOWN";
                    }

                    output.RecordId = reqRec.RecordId;

                    output.Data["reviews_rating"] = review;


                    resp.Values.Add(output);
                }
                catch (System.Exception ex)
                {
                    log.Info($"EXCEPTION !!!! {ex.Message}");
                    log.Info(ex.StackTrace);
                    output.RecordId = reqRec.RecordId;
                    //output.Errors = new List<WebApiErrorWarningContract>();
                    //output.Errors.Add(new WebApiErrorWarningContract() { Message = ex.Message });
                    output.Data["state"]          = "UNKNOWN";
                    output.Data["country"]        = "UNKNOWN";
                    output.Data["reviews_rating"] = review;

                    resp.Values.Add(output);

                    return(req.CreateResponse(HttpStatusCode.OK, resp));
                }
            }



            log.Info($"Successful Run  returning {resp.Values.Count} records");
            return(req.CreateResponse(HttpStatusCode.OK, resp));
        }
Beispiel #30
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, TraceWriter log, ILogger logger, ExecutionContext executionContext)
        {
            WebApiResponseRecord output = new WebApiResponseRecord();
            string skillName            = executionContext.FunctionName;
            IEnumerable <WebApiRequestRecord> requestRecords = WebApiSkillHelpers.GetRequestRecords(req);

            if (requestRecords == null)
            {
                return(req.CreateErrorResponse(HttpStatusCode.BadRequest, $"{skillName} - Invalid request record array."));
            }
            try
            {
                List <string> customer = new List <string>();
                logger.LogInformation("Hello World");
                Conversation conversation = new Conversation();
                string       content      = (string)requestRecords.First().Data["content"];
                conversation.Turns = new List <Turn>();

                string[] lines = content.Split(new char[] { '\n' });
                int      i     = 0;
                foreach (string line in lines)
                {
                    if (i == 0)
                    {
                        i++;
                        continue;
                    }
                    string[] regexed = SplitCSV(line);
                    //string[] cols = line.Split(new char[] { ',' });
                    if (regexed.Length < 3)
                    {
                        continue;
                    }
                    conversation.Turns.Add(new Turn(regexed[2], regexed[1], Convert.ToInt32(regexed[0])));
                    if (regexed[1] == "customer")
                    {
                        customer.Add(regexed[2]);
                    }
                    i++;
                }
                conversation.Count = conversation.Turns.Count;

                output.RecordId             = requestRecords.First().RecordId;
                output.Data["conversation"] = conversation;
                output.Data["customer"]     = customer;
                WebApiSkillResponse resp = new WebApiSkillResponse();
                resp.Values = new List <WebApiResponseRecord>();
                resp.Values.Add(output);
                log.Info($"Successful Run  ");
                return(req.CreateResponse(HttpStatusCode.OK, resp));
            }
            catch (Exception ex)
            {
                log.Info($"Error:  {ex.Message}");
                log.Info(ex.StackTrace);
                output.RecordId = requestRecords.First().RecordId;
                output.Errors   = new List <WebApiErrorWarningContract>();
                output.Errors.Add(new WebApiErrorWarningContract()
                {
                    Message = ex.Message
                });

                WebApiSkillResponse resp = new WebApiSkillResponse();
                resp.Values = new List <WebApiResponseRecord>();
                resp.Values.Add(output);
                return(req.CreateResponse(HttpStatusCode.OK, resp));
            }
        }