からめもぶろぐ。

俺たちは雰囲気で OAuth をやっている

Power Automate の承認ワークフローを API から取得する

Power Automate の承認ワークフローは便利な機能ですが、残念ながら「自分にきた承認の一覧を確認する」というのが Power Automate のサイト (https://flow.microsoft.com) からしか行うことができません。例えば SharePoint などからも見られるようになると利便性が向上すると考える方もいるかと思います。Power Automate の承認ワークフローのデータは Dataverse に保存されるので、Power Apps、Power Automate、Dynamics 365 などのライセンスを持っているユーザーであれば、REST API を使ってデータを取ることができます。しかし、Office 365 や Microsoft 365 のライセンスのユーザーは REST API を使うことができません。

とはいえ、Office 365 や Microsoft 365 のユーザーでも Power Automate のサイトからであれば、承認ワークフローのデータを見ることができるので、なんとかできないかと頑張ってみました。この方法は docs がないため現時点では公式に推奨されている方法ではありません。試す場合は自己責任でお願いします。

調べてみる

なにはともあれ F12 開発者ツールで Power Automate のサイトから呼んでいる API を覗いてみるとこんな感じのエンドポイントを叩いているのがわかります。

https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/{{envname}}/approvalViews?api-version=2016-11-01&$filter=properties%2FuserRole%20eq%20%27Approver%27

Authorization ヘッダーの JWT をデコードしてみます。aud (Audience) が https://service.flow.microsoft.com/ になっていますね。

{
  "aud": "https://service.flow.microsoft.com/",
  "iss": "https://sts.windows.net/a380c832-56bb-4e90-836c-b45ca50c74a1/",
  ...
}

Azure AD PowerShell で該当する Azure AD アプリケーションを特定します。アプリケーション (クライアント) ID が「7df0a125-d3be-4c96-aa54-591f83ff541c」であることがわかります。*1

PS> Get-AzureADServicePrincipal -All $true | ?{ $_.ServicePrincipalNames -contains "https://service.flow.microsoft.com/" }

ObjectId                             AppId                                DisplayName
--------                             -----                                -----------
9faf35a1-cbbf-43a9-a6a2-c65918318858 7df0a125-d3be-4c96-aa54-591f83ff541c Microsoft Flow Service

続いてアクセス許可の一覧を抜き出します。Approvals.Read.All というアクセス許可がなんかそれっぽい気がしますね。

AdminConsentDescription : Allow applications to write plans
AdminConsentDisplayName : Allow applications to write plans
Id                      : 27c61d54-eb42-4315-8793-6e5715a19746
IsEnabled               : True
Type                    : User
UserConsentDescription  : Allow applications to write plans
UserConsentDisplayName  : Allow applications to write plans
Value                   : Flows.Write.Plans

AdminConsentDescription : Allow the application read only permission for flow
AdminConsentDisplayName : Allow the application read only permission for flow
Id                      : 0b575251-2c95-46df-bc75-c8c43e6b7116
IsEnabled               : True
Type                    : User
UserConsentDescription  : Allow the application read only permission for flow
UserConsentDisplayName  : Allow the application read only permission for flow
Value                   : Flows.Read.Plans

AdminConsentDescription : Allow the application to read flows
AdminConsentDisplayName : Allow the application to read flows
Id                      : e45c5562-459d-4d1b-8148-83eb1b6dcf83
IsEnabled               : True
Type                    : User
UserConsentDescription  : Allow the application to read flows
UserConsentDisplayName  : Allow the application to read flows
Value                   : Flows.Read.All

AdminConsentDescription : Allow the application to create and edit flows
AdminConsentDisplayName : Allow the application to manage flows
Id                      : 30b2d850-00c3-4802-b7ae-ece9af9de5c6
IsEnabled               : True
Type                    : User
UserConsentDescription  : Allow the application to create and edit flows
UserConsentDisplayName  : Allow the application to manage flows
Value                   : Flows.Manage.All

AdminConsentDescription : Allow the application to read activities
AdminConsentDisplayName : Allow the application to read activities
Id                      : 822a9cde-503a-472d-a530-d1dc9cd0d52b
IsEnabled               : True
Type                    : User
UserConsentDescription  : Allow the application to read activities
UserConsentDisplayName  : Allow the application to read activities
Value                   : Activity.Read.All

AdminConsentDescription : Allow the application to read approvals
AdminConsentDisplayName : Allow the application to read approvals
Id                      : e9cbd5de-0031-493e-8fb1-60712d03cc8b
IsEnabled               : True
Type                    : User
UserConsentDescription  : Allow the application to read approvals
UserConsentDisplayName  : Allow the application to read approvals
Value                   : Approvals.Read.All

AdminConsentDescription : Allow the application to manage approvals
AdminConsentDisplayName : Allow the application to manage approvals
Id                      : d05743e4-fb24-4dff-8a33-0f6c73c964bd
IsEnabled               : True
Type                    : User
UserConsentDescription  : Allow the application to manage approvals
UserConsentDisplayName  : Allow the application to manage approvals
Value                   : Approvals.Manage.All

AdminConsentDescription : Access Microsoft Flow as signed in user
AdminConsentDisplayName : Access Microsoft Flow as signed in user
Id                      : 44d8c55c-9ffc-4546-883e-9041b5bb0b01
IsEnabled               : True
Type                    : Admin
UserConsentDescription  : Allow access to all features in Microsoft Flow
UserConsentDisplayName  : Access Microsoft Flow as signed in user
Value                   : User

試してみる

Azure ポータルで Azure AD に新しいアプリケーションを作成します。[API のアクセス許可] を見ると「Flow Service」というのがあります。

f:id:karamem0:20211117104741p:plain

「Approvals.Read.All」を選択します。

f:id:karamem0:20211117104753p:plain

追加できました。これで API が呼べるようになります。

f:id:karamem0:20211117104903p:plain

試しに Postman を使って API を呼んでみます。200 OK が返ってきます。

f:id:karamem0:20211117104915p:plain

レスポンスの JSON はこんな感じ。ちゃんと取れてますね。

{
    "value": [
        {
            "name": "026092a1-3e66-48a3-bc89-60b80d187f7d",
            "id": "/providers/Microsoft.ProcessSimple/environments/Default-.../approvalViews/026092a1-3e66-48a3-bc89-60b80d187f7d",
            "type": "/providers/Microsoft.ProcessSimple/environments/approvalViews",
            "properties": {
                "type": "Basic",
                "isActive": false,
                "userRoles": [
                    "Owner",
                    "Approver"
                ],
                "owner": {
                    "id": "8f7f93f0-...",
                    "type": "User",
                    "tenantId": "a380c832-..."
                },
                "title": "承認リクエスト from Takashi Shinohara",
                "result": "Approve",
                "allowCancel": true,
                "creationDate": "2021-11-11T23:20:52Z",
                "dueDate": "9999-12-31T23:59:59Z",
                "expirationDate": "9999-12-31T23:59:59Z",
                "completionDate": "2021-11-11T23:37:31Z",
                "approvers": [
                    "8f7f93f0-..."
                ],
                "principals": [
                    {
                        "id": "8f7f93f0-...",
                        "displayName": "Takashi Shinohara",
                        "email": "takashi.shinohara@example.onmicrosoft.com",
                        "type": "User",
                        "tenantId": "a380c832-...",
                        "userPrincipalName": "takashi.shinohara@example.onmicrosoft.com"
                    }
                ],
                "priority": "Medium",
                "requestType": "Basic"
            }
        }
    ]
}

まとめ

「Approvals.Manage.All」を使えば API からの承認や却下もできそうです。繰り返しますが docs では公開されていない機能のようなので自己責任でお願いしたいですが、ちゃんと公開されたらとても便利そうですね。

*1:オブジェクト ID はテナントごとに異なります。