了解 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. 如何查看 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
和 Dataverse api:
https://{URL_ENVIRONMENT_DYNAMICS_URL}/api/data/v9.2/workflows?$filter=resourceid eq '{FLOW_ID_FROM_URL}'
使用 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"
}
流程中使用的连接引用。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']"
}
}
},
这是您的流程的内容,包括触发器、连接和您使用的操作。
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"
]
}
}
Schdeuled
Schedule 是最简单的,带有重复键设置频率和间隔,因此下面是每 20 分钟一次。
javascript
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Minute",
"interval": 20
},
"metadata": {
"operationMetadataId": "7331237b-733a-4f27-b47c-1858ff22e2b0"
},
"type": "Recurrence"
}
},
自动:
自动显示触发器名称作为主要键,重复频率是指检查事件的频率(不同的许可证、连接器甚至环境都会影响频率,这就是为什么有一个测试选项,因为它会将频率提升到秒级)。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')"
}
}
行动
作为参考,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')"
}
},
容器
容器是指包含内部操作的操作:作用域、条件、切换、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"
}
}
操作
操作是标准动作,如 setVariable 和 compose。
类型:操作类型
runAfter:与之前相同
输入:针对每个操作的操作的输入
javscript
Select": {
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "Select",
"inputs": {
"from": "@outputs('Get_items')?['body/value']",
"select": {
"@{item()?['Title']}": "test"
}
}
}
我对 JSON 的定义只是皮毛(而且我肯定有些地方写错了,因为很多内容都是从四处打探中推断出来的)。理解它或许并非必要,但我发现,当事情不如预期时,这些知识非常有用。而且,深入了解事情的运作机制也挺酷的,既然你已经读到了最后,我想你也一样。
鏂囩珷鏉ユ簮锛�https://dev.to/wyattdave/understanding-the-power-automate-definition-42po