了解 Power Automate 定义

2025-06-10

了解 Power Automate 定义

Power Automate 构建于 Azure Logic Apps 之上,因此它们共享相同的定义架构。该定义是一个 JSON 对象,其中包含 Power Automate/Logic Apps 完成所有操作所需的信息。

微软提供了一些关于该定义的优秀文档(https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-workflow-definition-language),但我想更详细地介绍一下 Power Automate。这篇博客可能并不适合所有人,但如果你是那种需要打开旧烤面包机才能了解其工作原理的孩子,那么这篇文章可能适合你。

这里需要注意的是,定义通常不会单独传播,它通常还包括“属性”、“连接引用”等,所以我将从更高的层次开始,并将它们包含在博客中,所有这些组合通常称为定义文件或客户端数据。

本博客将涵盖:

  1. 如何看待定义
  2. 钥匙
  3. 顶级键
  4. 触发器
  5. 行动
  6. 变体

1. 如何查看 Definition/clientdata

Power Automate 将定义模式转换为我们的流程,以便我们可以编辑它,所以不太容易看到它,但有几种方法。

API
通过 flow api:



https://us.api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/{ENVIRONMENT_ID}/flows/{FLOW_ID_FROM_URL}?api-version=2016-11-01&$expand=swagger,properties.connectionreferences.apidefinition,properties.definitionSummary.operations.apiOperation,operationDefinition,plan,properties.throttleData,properties.estimatedsuspensiondata


Enter fullscreen mode Exit fullscreen mode

Chrome 开发工具
此处显示在 Chrome Dev 工具中

和 Dataverse api:



https://{URL_ENVIRONMENT_DYNAMICS_URL}/api/data/v9.2/workflows?$filter=resourceid eq '{FLOW_ID_FROM_URL}'


Enter fullscreen mode Exit fullscreen mode

数据宇宙 API
定义在“客户端数据”字段中,但仅适用于解决方案感知流程


使用 Dataverse 列表在工作流(流程)表中列出行,从而实现 Power Automate 。不过,这也仅适用于解决方案感知流程。

流程获取定义

AutoReview
AutoReview 是我为代码审查创建的免费 Chrome 扩展程序,它还包含查看客户端数据的功能(在当前打开的流程或导出的 zip 文件中)。https
://chromewebstore.google.com/detail/autoreview-for-power-auto/laaendfpgmhjilhjkbebekgdgfjaajif

自动审核

Power Automate Tools
是另一个 Chrome 扩展程序,但它允许您直接编辑架构定义(非常酷😎)。https
://chromewebstore.google.com/detail/power-automate-tools/jccblbmcghkddifenlocnjfmeemjeacc

电力自动化工具

导出
遗留文件和解决方案导出 zip 文件均包含定义文件

2. 钥匙

定义键的当前版本是https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json。访问定义的不同位置会影响其他内容,只有定义是一致的。因此,有很多键,但以下是我认为比较重要的键的列表:

  • 姓名
  • ID
  • 类型
  • 连接参考
  • 被管理
  • 属性/apiId
  • 属性/显示名称
  • 属性/定义
  • 定义/元数据
  • 定义/$schema
  • 定义/参数
  • 定义/触发器
  • 定义/行动

父母/钥匙

3. 顶级键

顶级键是流的元数据,而不是实际定义的一部分,它们提供有关流的信息,但实际上并不是流的一部分。

名称
示例:name": "4b569087-cf7a-18bc-dfb4-f9b31fd7e635"
这是流程 ID,它会在 URL 中显示,并在工作流表(解决方案感知)中显示为资源 ID。这不是工作流表的 GUID(workflowid),而是 Power Automate 中的 GUID。

Id
示例:id": "/providers/Microsoft.ProcessSimple/environments/Default-6b6c3ede-aa0d-4268-a46f-96b7621b13a8/flows/4b569087-cf7a-18bc-dfb4-f9b31fd7e635"
流程的相对 URL 路径(环境 ID 和流程名称)

类型
"type": "Microsoft.Flow/flows",
逻辑应用或流程

是否受管
isManaged": false
是受管解决方案中的流程。

连接参考


 javascript
"connectionReferences": {
      "shared_sharepointonline": {
        "connectionName": "shared-sharepointonl-594ec2f7-b783-4358-8a34-901d2cf18e0e",
        "source": "Invoker",
        "id": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline",
        "tier": "NotSpecified"
      }


Enter fullscreen mode Exit fullscreen mode

流程中使用的连接引用。connectionReference 通过第一个键(上例中为 shared_sharepointonline)链接到流程中的操作。当存在多个相同的连接时,它们的值会递增(例如 shared_sharepointonline、shared_sharepointonline_1、shared_sharepointonline_2 等等)。

connectionName 是实际连接引用的 GUID。id 是连接的类型,因此上图显示它是用于 SharePoint 的。Tier 会标记它是否为高级连接器。

以下都在属性键下,因此我用“顶级”对其进行了扩展:


"apiId": "/providers/Microsoft.PowerApps/apis/shared_logicflows"
Azure 上处理定义的ApiId App

DisplayName
"displayName": "demo",
所有菜单等中显示的流程的名称

定义



"definition": {
      "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "$connections": {
          "defaultValue": {},
          "type": "Object"
        },
        "$authentication": {
          "defaultValue": {},
          "type": "SecureObject"
        }
      },
      "triggers": {
        "When_an_item_is_created": {
          "recurrence": {
            "frequency": "Minute",
            "interval": 1
          },
          "splitOn": "@triggerOutputs()?['body/value']",
          "metadata": {
            "operationMetadataId": "44e16d66-9bad-4c13-b095-e0d1720f2a20"
          },
          "type": "OpenApiConnection",
          "inputs": {
            "host": {
              "apiId": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline",
              "connectionName": "shared_sharepointonline",
              "operationId": "GetOnNewItems"
            },
            "parameters": {
              "dataset": "https://37wcqv.sharepoint.com/sites/testsite",
              "table": "742435b6-7897-4636-ab8e-ec347405b9a6"
            },
            "authentication": "@parameters('$authentication')"
          }
        }
      },
      "actions": {
        "Compose": {
          "runAfter": {},
          "metadata": {
            "operationMetadataId": "d725af82-56c4-435c-bcea-dba38ddf4e02"
          },
          "type": "Compose",
          "inputs": "@triggerOutputs()?['body/Title']"
        }
      }
    },


Enter fullscreen mode Exit fullscreen mode

这是您的流程的内容,包括触发器、连接和您使用的操作。

4. 触发器

我们现在进入了定义键,第一个键是触发器(没错,是复数,因为在 Power Automate 中可能无法有多个触发器,但在 Logic Apps 中可以)。触发器模式有 3 个:

Instant
Instant(按钮/PowerApp/Copilot)具有标准输入模式,每个输入在属性中对应一个项目。项目名称按类型顺序排列,例如 text,text_1,text_2 或 number,number_1。


 javascript
"triggers": {
    "manual": {
        "metadata": {
            "operationMetadataId": "4c3b12d2-87bf-45e3-a766-9555de826c05"
        },
        "type": "Request",
        "kind": "Button",
        "inputs": {
            "schema": {
                "type": "object",
                "properties": {
                    "text": {
                        "title": "name",
                        "type": "string",
                        "x-ms-dynamically-added": true,
                        "description": "Please enter your input",
                        "x-ms-content-hint": "TEXT"
                    },
                    "boolean": {
                    "title": "Yes/No",
                    "type": "boolean",
                    "x-ms-dynamically-added": true,
                    "description": "Please select yes or no",
                    "x-ms-content-hint": "BOOLEAN"
                },
                "text_1": {
                    "title": "Input 1",
                    "type": "string",
                    "x-ms-dynamically-added": true,
                    "description": "Please enter your input",
                    "enum": [
                        "First option",
                        "Second option"
                    ],
                    "x-ms-content-hint": "TEXT"
                },
                "number": {
                    "title": "Number",
                    "type": "number",
                    "x-ms-dynamically-added": true,
                    "description": "Please enter a number",
                    "x-ms-content-hint": "NUMBER"
                },
                "date": {
                    "title": "Trigger date",
                    "type": "string",
                    "format": "date",
                    "x-ms-dynamically-added": true,
                    "description": "Please enter or select a date (YYYY-MM-DD)",
                    "x-ms-content-hint": "DATE"
                },
                "email": {
                    "title": "Email",
                    "type": "string",
                    "format": "email",
                    "x-ms-dynamically-added": true,
                    "description": "Please enter an e-mail address",
                    "x-ms-content-hint": "EMAIL"
                },
                "file": {
                    "title": "File Content",
                    "type": "object",
                    "x-ms-dynamically-added": true,
                    "description": "Please select file or image",
                    "x-ms-content-hint": "FILE",
                    "properties": {
                    "name": {
                        "type": "string"
                    },
                    "contentBytes": {
                        "type": "string",
                        "format": "byte"
                    }
                }
            }
        },
        "required": [
            "text",
            "boolean",
            "text_1",
            "number",
            "date",
            "email"
        ]
    }
}


Enter fullscreen mode Exit fullscreen mode

Schdeuled
Schedule 是最简单的,带有重复键设置频率和间隔,因此下面是每 20 分钟一次。


 javascript
"triggers": {
    "Recurrence": {
        "recurrence": {
            "frequency": "Minute",
            "interval": 20
        },
    "metadata": {
        "operationMetadataId": "7331237b-733a-4f27-b47c-1858ff22e2b0"
    },
        "type": "Recurrence"
    }
},


Enter fullscreen mode Exit fullscreen mode

自动:
自动显示触发器名称作为主要键,重复频率是指检查事件的频率(不同的许可证、连接器甚至环境都会影响频率,这就是为什么有一个测试选项,因为它会将频率提升到秒级)。splitOn
和安全输入等选项以及连接类型(OpenApiConnection)在触发器中显示为键。最后是参数,即连接的输入,下方是 SharePoint 站点和列表 ID。


 javascript
"triggers": {
    "When_an_item_is_created": {
        "recurrence": {
            "frequency": "Minute",
            "interval": 1
        },
        "splitOn": "@triggerOutputs()?['body/value']",
        "metadata": {
            "operationMetadataId": "51079ae2-e43a-4424-a687-d56dd5d511c5"
        },
        "type": "OpenApiConnection",
        "inputs": {
            "host": {
                "apiId": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline",
                "connectionName": "shared_sharepointonline",
                "operationId": "GetOnNewItems"
            },
        "parameters": {
            "dataset": "https://sharepoint.com/sites/Sites3/",
            "table": "7f8831ea-d237-412e-ac15-0f0777992d1f"
        },
        "authentication": "@parameters('$authentication')"
    }
}


Enter fullscreen mode Exit fullscreen mode

行动

作为参考,actions 是一个操作集合的键,因此任何操作键都在 action 键内,抱歉,我知道这可能没有意义

Actions 是流程中的所有操作。显然,这是最重要的,action 键有很多变体,但主要分为 3 个组:OpenApiConnection、Containers 和 Operations。Actions 是一个对象而不是数组,因此每个操作都是对象内的一个对象。它也是递归的,容器有自己的操作(稍后详述)。最需要注意的是运行顺序,这不是对象中的顺序,而是它们添加到流程中的顺序。运行顺序实际上是倒序的,它基于 runAfter 键。因此,理论上,您需要从最后一个操作开始,找到它之后运行的项目,然后沿着流程向上追溯。

您还可以查看操作的代码以了解所有内容。

窥视代码

OpenApiConnection
动作的名称是键,它有以下键:

  • runAfter:可以包含多个操作(分支合并)并具有一系列运行条件(成功、失败、超时、跳过)的对象。
  • metadata/operationMetadataId:如果是操作,例如 SharePoint GetItems 都将具有相同的 operationMetadataId。
  • 输入/主机/连接名称:这是用于链接到连接引用的引用,因此这是与 connectionReferences 键创建关系的关键。
  • 输入/主机/操作Id:api 操作的类型,例如 GetItem 将包括 SharePoint 获取项目、Excel 获取一行、Dataverse 通过 ID 获取一行。
  • 参数:操作内的所有输入,这通常不代表 UI,因此您可以选择一个文件名,但输入是一个文件 ID。
  • secureData:用于保护动作的输入/输出,它具有属性键,即输入/输出的数组。
  • 运行时配置:用于返回数组(如 GetItems/ListItems),仅在分页打开时显示,显示 minimumItemCount 键表示每页有多少行
  • retryPolicy:操作失败时将执行哪些重试操作(设置为默认值时不显示)。包含类型键(固定、无、指数),每种类型都会显示不同的输入

 JavaScript
"Get_a_row_by_ID": {
    "runAfter": {
        "List_rows": [
            "Succeeded"
        ]
    },
    "metadata": {
        "operationMetadataId": "bccfb3ea-e703-468d-a216-0b978ef670d9"
    },
    "type": "OpenApiConnection",
    "inputs": {
        "host": {
        "apiId": "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps",
        "connectionName": "shared_commondataserviceforapps",
        "operationId": "GetItem"
        },
        "retryPolicy": {
            "type": "fixed",
            "count": 1,
            "interval": "PT20S"
        },
        "parameters": {
            "entityName": "workflows",
            "recordId": "@outputs('List_rows')?['body/value'][0]?['workflowid']"
        },
        "authentication": "@parameters('$authentication')"
    }
},


Enter fullscreen mode Exit fullscreen mode

容器
容器是指包含内部操作的操作:作用域、条件、切换、ApplyToEach、DoUntil。它们略有不同,主要体现在内部的分支逻辑上。它们还会扰乱我们的运行顺序,因为它们破坏了每个分支中第一个操作的规则。这些操作按容器内的位置运行,而不是按 runAfer 运行(因为容器使用 runAfter 操作)。

  • 类型:容器类型
  • 动作:包含容器内的所有动作
  • runAfter:与之前相同
  • 表达式(不适用于范围):容器的输入
  • else(仅限条件):false 的分支,与动作相同的结构
  • case(仅限 switch):每个 switch 分支都位于 case 键中,包含 Case、Case 2 等以及一个 Default。每个 Case 都有另一个用于条件匹配的键 case,以及其自身的操作
  • foreach:(仅适用于每个)数组输入

 javascript
"Condition": {
    "actions": {
        "Get_a_row_by_ID": {
            "type": "OpenApiConnection",
                "inputs": {
                    "parameters": {
                    "entityName": "accounts",
                    "recordId": "12345"
                },
                "host": {
                    "apiId": "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps",
                    "connectionName": "shared_commondataserviceforapps",
                    "operationId": "GetItem"
                },
                "authentication": "@parameters('$authentication')"
            }
        }
    },
    "runAfter": {},
    "else": {
        "actions": {
            "Compose": {
            "type": "Compose",
            "inputs": "hello world"
            }
        }
    },
    "expression": {
        "and": [
            {
                "equals": [
                    "",
                    ""
                ]
            }
        ]
    },
        "type": "If"
    }
}


Enter fullscreen mode Exit fullscreen mode

操作
操作是标准动作,如 setVariable 和 compose。

类型:操作类型
runAfter:与之前相同
输入:针对每个操作的操作的输入


 javscript
Select": {
    "runAfter": {
        "For_each": [
            "Succeeded"
        ]
    },
    "type": "Select",
    "inputs": {
        "from": "@outputs('Get_items')?['body/value']",
        "select": {
            "@{item()?['Title']}": "test"
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

我对 JSON 的定义只是皮毛(而且我肯定有些地方写错了,因为很多内容都是从四处打探中推断出来的)。理解它或许并非必要,但我发现,当事情不如预期时,这些知识非常有用。而且,深入了解事情的运作机制也挺酷的,既然你已经读到了最后,我想你也一样。

鏂囩珷鏉ユ簮锛�https://dev.to/wyattdave/understanding-the-power-automate-definition-42po
PREV
12 种有害的认知偏差及其克服方法
NEXT
Power Automate - Switch、Condition 和 If()