HTTP 函数不等待响应

问题描述 投票:0回答:1

我正在经历一生中最糟糕的时光,试图让这个电源自动流程发挥作用。

我制作了一个 Power Automate 流程,用于从发票中提取采购订单。收件箱中的每封新电子邮件都会触发它。我正在循环浏览 pdf 附件,调用 AI 构建器从发票中提取信息,并获取采购订单。

我需要更准确的选项来查找采购订单,因此我将提取采购订单的逻辑移至 API 调用。现在,流程只需将 pdf 发送到端点,我就可以处理 C# 中的所有功能,并返回必要的详细信息,以便流程可以继续。

此 API 调用在 Postman 中大约需要 20 秒。 当我尝试在流程中调用它时,它超时了。

我在 API 上附加了一个调试器,我发现当我等待 AI 客户端的响应时,Flow 正在重新发送请求。这会导致无限循环。 我知道对端点的调用正在工作,因为我可以在 AI 调用之前返回 OK 响应,并且它可以工作。

如何让我的 HTTP 请求等待这个结果? 或者是客户端 AI 调用的异步性问题? 我注意到,当我调试时,我的断点总是在第一次调用 aiClient 时丢失,这是调用中的第一个异步操作。

An image of the HTTP action in Power Automate Flow

这是 Power Automate 中 HTTP 调用的代码视图

    "inputs": {
        "method": "POST",
        "uri": "REDACTED",
        "headers": {
            "Connection": "keep-alive",
            "Accept": "*/*",
            "Host": "REDACTED",
            "Accept-Encoding": "gzip, deflate, br"
        },
        "body": {
            "$content-type": "multipart/form-data",
            "$multipart": [
                {
                    "headers": {
                        "Content-Disposition": "form-data; name=\"invoicePdf\"; filename=\"invoicePdf.pdf\""
                    },
                    "body": "@outputs('Get_file_content')"
                }
            ]
        },
        "authentication": {
            "type": "Basic",
            "username": "REDACTED",
            "password": "REDACTED"
        }
    },
    "operationOptions": "DisableAsyncPattern",
    "metadata": {
        "operationMetadataId": "38dae010-f79b-4c3e-ae7c-22a6047b4151"
    }
}

这是我的带有 ai 调用的 C# 方法:

        {
            // Check if a file was uploaded
            if (invoicePdf == null || invoicePdf.Length == 0)
            {
                return BadRequest("No file uploaded.");
            }

            // Check if the file is a PDF
            if (!invoicePdf.FileName.EndsWith(".pdf"))
            {
                return BadRequest("Only PDF files are allowed.");
            }

            AzureKeyCredential credential = new AzureKeyCredential(AppSettings.AzureAiServiceKey);
            DocumentAnalysisClient aiClient = new DocumentAnalysisClient(new Uri(AppSettings.AzureAiServiceEndpoint), credential);

            //var operation = await aiClient.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-invoice", invoicePdf.OpenReadStream());
            var invoiceOperation = aiClient.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-invoice",
                invoicePdf.OpenReadStream(), new AnalyzeDocumentOptions
                {
                    Pages = { "1-2" }
                }).Result;

            var invoiceResult = invoiceOperation.Value;

            //check default area
            for (int i = 0; i < invoiceResult.Documents.Count; i++)
            {
                var document = invoiceResult.Documents[i];

                //try to find the purchase order from the default area
                if (document.Fields.ContainsKey("PurchaseOrder"))
                {
                    document.Fields.TryGetValue("PurchaseOrder", out var purchaseOrderObject);

                    var purchaseOrderValue = purchaseOrderObject.Content;
                    var purchaseOrderConfidence = purchaseOrderObject.Confidence;

                    var sanitizedPurchaseOrderValue = SanitizePurchaseOrder(purchaseOrderValue);

                    return Ok(new
                    {
                        Found = true,
                        PurchaseOrderValue = sanitizedPurchaseOrderValue,
                        PurchaseOrderConfidence = purchaseOrderConfidence,
                        FoundIn = "Default Location"
                    });
                }
            }

            var layoutOperation = aiClient.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-document",
                invoicePdf.OpenReadStream(), new AnalyzeDocumentOptions
                {
                    Pages = { "1-2" }
                }).Result;

            var layoutResult = layoutOperation.Value;
            DocumentKeyValuePair? poKeyValuePair;

            poKeyValuePair = layoutResult.KeyValuePairs.FirstOrDefault(x => firstPriorityKeys.Contains(x.Key.Content));
            if (poKeyValuePair == null)
            {
                poKeyValuePair = layoutResult.KeyValuePairs.FirstOrDefault(x => secondPriorityKeys.Contains(x.Key.Content));
                if (poKeyValuePair == null)
                {
                    poKeyValuePair = layoutResult.KeyValuePairs.FirstOrDefault(x => thirdPriorityKeys.Contains(x.Key.Content));
                    if (poKeyValuePair == null)
                    {
                        poKeyValuePair = layoutResult.KeyValuePairs.FirstOrDefault(x => fourthPriorityKeys.Contains(x.Key.Content));
                        if (poKeyValuePair == null)
                        {
                            poKeyValuePair = layoutResult.KeyValuePairs.FirstOrDefault(x => fifthPriorityKeys.Contains(x.Key.Content));
                        }
                    }
                }
            }

            if (poKeyValuePair != null)
            {
                var sanitizedPurchaseOrderValue = SanitizePurchaseOrder(poKeyValuePair.Value.Content);

                return Ok(new
                {
                    Found = true,
                    PurchaseOrderValue = sanitizedPurchaseOrderValue,
                    PurchaseOrderConfidence = poKeyValuePair.Confidence,
                    FoundIn = $"{poKeyValuePair.Key.Content} (KVP)"
                });
            }

            //check plain text with regex
            Regex regex =
                new Regex(@"([Pp][Oo]|[Pp][Uu][Rr][Cc][Hh][Aa][Ss][Ee]\s?[Oo][Rr][Dd][Ee][Rr]).{0,3}(\d{7})");
            Match match = regex.Match(layoutResult.Content);
            if (match.Success)
            {
                var foundPo = match.Value;
                var sanitizedPurchaseOrderValue = SanitizePurchaseOrder(foundPo);

                return Ok(new
                {
                    Found = true,
                    PurchaseOrderValue = sanitizedPurchaseOrderValue,
                    PurchaseOrderConfidence = 0.5,
                    FoundIn = "Plain Text Regex Parse"
                });

            }

            return Ok(new
            {
                Found = false
            });
        }

总结

  • Power Automate Flow 的 HTTP 调用不等待响应
  • 它可以在 Postman 中使用,但需要大约 20 秒
  • 有没有办法让 Flow 等待此响应?
c# asp.net-core-webapi power-automate azure-form-recognizer
1个回答
0
投票

多么令人沮丧……我找到了解决方法。

我已更新我的端点以接收 Base64 编码的字符串。

我已更新到 Power Automate 流程以使用获取附件 (V2) 调用,而不是使用新电子邮件触发器的附件。

出于某种原因,它现在可以工作了...我不知道触发器中的附件和呼叫中的附件之间有什么不同,但切换它已经起作用了。

我相当有信心问题是从触发器获取附件,而不是获取附件(V2)调用

© www.soinside.com 2019 - 2024. All rights reserved.