Microsoft FlowでGraphを叩いて結果をExcelに入れるまで


Microsoft FlowでGraphを叩いて結果をExcelに入れるまで

仕事で必要が生じたというか使えたら効率化図れるので提案したいなぁと思い形にしたことを結果を。(正確には現段階で採用になっていませんがw)

概要

社内でMicrosoft Teamsを利用していて現在作成されているチーム一覧を毎月作成しているのでそれを自動化する。
方法としてTeamsのチーム一覧はGraphで抽出する。GraphはFlowから呼ぶ。Excelへの転記もFlowから行う。一連の作業をFlowにスケジューリングする。
出来上がったFlowは以下のようになる。

方法

Excel操作
ExcelのブックをFlowで作成する方法はあるかどうか不明だが少なくとも僕は知らない。よって予め用意しておく。
Excelへの転記はシート上にテーブルを予め作成しておく必要がある。作成の際は先頭の一行目だけを定義するように(ここではまった!)。
またExcelのシート上にテーブルを作成する方法が用意はされているが、動的にテーブルを定義しFlow上で得られた結果を挿入する方法がわからなかった。よって一旦内容をクリアして再度記載する方法を採る。
「表内に存在する行を一覧表示」アクションで行を全て取得。順番に「行を削除」アクションで消していく。この際、「表内に存在する行を一覧表示」アクションを定義し、その次に「Apply to each」ではなく「行を削除」アクションを定義しキー値を設定する。すると自動的に「Apply to each」が定義される(割とはまった箇所。「Apply to each」アクションの同様ケースは後段にもある)。
行の削除にあたって、キー項目を設けておくことがポイントである。「行を削除」アクションでは指定した行が存在しないとエラーとなる。

Graphの叩き方とデータの取得
Flowには予めTeams用のアクションが用意されていてこれらを使うって間に合う作業ならGraphは要らない。しかしTeamsのチーム一覧を取得する場合Flowのアクションでは自分が参加しているチームの一覧しか取得できない。しかし今回は作成されている全てのチームを取得したい。よって、Graphを使う必要がある。

FlowからGraphを利用する方法については
Microsoft Flow 用に Microsoft Graph JSON バッチ カスタム コネクタを作成する
が最も有益。
1.Graphを利用するには最初に登録を行う。
2.実際にAPIを叩く際には認証が必要。その為のコネクタを作る。

カスタムコネクタを作成したら実際にGraphを叩く。Flowから叩く場合は「MS Graph バッチコネクタ」というアクションを利用する。
先のページでは一つのアクションで連続してGraphを叩く例が記載されているが今回は一回で間に合う。

組織の Microsoft Teams 内のすべてのチームのリストを作成する
に載っている
ベータ版の API を使用してグループのリストを取得する

を利用する。バッチコネクタのbodyには以下のように定義する。

{
  "requests": [
    {
      "url": "/groups?$filter=resourceProvisioningOptions/Any(x:x eq 'Team')",
      "method": "GET",
      "id": 1
    }
  ]
}

テストを実行し後に、バッチコネクタを開くと「出力」という欄が表示される。FlowからバッチコネクタでGraphを叩いた結果である。

この結果をExcelに転記したいがご覧の通りJSONなので「JSONの解析」というアクションで扱える情報にする。「JSONの解析」はどのような形式のJSONを解析するかをスキーマとして定義する必要がある。

その方法は先のバッチコネクタの「出力」を「サンプルのペイロードを使用してスキーマを生成する」で読み込ませる方法が一番確実である。
長いが引用。

{
    "type": "object",
    "properties": {
        "responses": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "status": {
                        "type": "integer"
                    },
                    "headers": {
                        "type": "object",
                        "properties": {
                            "Cache-Control": {
                                "type": "string"
                            },
                            "OData-Version": {
                                "type": "string"
                            },
                            "Content-Type": {
                                "type": "string"
                            }
                        }
                    },
                    "body": {
                        "type": "object",
                        "properties": {
                            "@@odata.context": {
                                "type": "string"
                            },
                            "@@odata.nextLink": {
                                "type": "string"
                            },
                            "value": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string"
                                        },
                                        "deletedDateTime": {},
                                        "classification": {},
                                        "createdDateTime": {
                                            "type": "string"
                                        },
                                        "displayName": {
                                            "type": "string"
                                        },
                                        "expirationDateTime": {},
                                        "externalGroupIds": {
                                            "type": "array"
                                        },
                                        "externalGroupProviderId": {},
                                        "externalGroupState": {},
                                        "groupTypes": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            }
                                        },
                                        "mail": {
                                            "type": "string"
                                        },
                                        "mailEnabled": {
                                            "type": "boolean"
                                        },
                                        "mailNickname": {
                                            "type": "string"
                                        },
                                        "membershipRule": {},
                                        "membershipRuleProcessingState": {},
                                        "membershipTypes": {
                                            "type": "array"
                                        },
                                        "onPremisesLastSyncDateTime": {},
                                        "onPremisesSecurityIdentifier": {},
                                        "onPremisesSyncEnabled": {},
                                        "preferredDataLocation": {},
                                        "preferredLanguage": {},
                                        "proxyAddresses": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            }
                                        },
                                        "renewedDateTime": {
                                            "type": "string"
                                        },
                                        "resourceBehaviorOptions": {
                                            "type": "array"
                                        },
                                        "resourceProvisioningOptions": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            }
                                        },
                                        "securityEnabled": {
                                            "type": "boolean"
                                        },
                                        "theme": {},
                                        "visibility": {
                                            "type": "string"
                                        },
                                        "onPremisesProvisioningErrors": {
                                            "type": "array"
                                        }
                                    },
                                    "required": [
                                        "id",
                                        "deletedDateTime",
                                        "classification",
                                        "createdDateTime",
                                        "description",
                                        "displayName",
                                        "expirationDateTime",
                                        "externalGroupIds",
                                        "externalGroupProviderId",
                                        "externalGroupState",
                                        "groupTypes",
                                        "mail",
                                        "mailEnabled",
                                        "mailNickname",
                                        "membershipRule",
                                        "membershipRuleProcessingState",
                                        "membershipTypes",
                                        "onPremisesLastSyncDateTime",
                                        "onPremisesSecurityIdentifier",
                                        "onPremisesSyncEnabled",
                                        "preferredDataLocation",
                                        "preferredLanguage",
                                        "proxyAddresses",
                                        "renewedDateTime",
                                        "resourceBehaviorOptions",
                                        "resourceProvisioningOptions",
                                        "securityEnabled",
                                        "theme",
                                        "visibility",
                                        "onPremisesProvisioningErrors"
                                    ]
                                }
                            }
                        }
                    }
                },
                "required": [
                    "id",
                    "status",
                    "headers",
                    "body"
                ]
            }
        }
    }
}

最後は解析結果をFlowで読み込んでExcelに転記する。結果のアイテムはN個なので「制御」の中の「Apply to each」を使い、「Apply to each」の結果をExcelに行を追加する「表に行を追加」というアクションに転記したい項目を渡す。
この時に戸惑うのは、欲しいデータは上記のスキーマの中のでいう「value」の中の 「Item」である。しかしそこで「Apply to each」の「以下の手順から出力を選択」に「value」を入れるとどうも上手くいかない。
結果として、まず「Apply to each」を一つ追加し「以下の手順から出力を選択」にJSONデータの先頭の「response」を指定、この「Apply to each」の中の「アクションの追加」で「表に行を追加」で用意したExcelファイル、データを転記したいテーブルを選択。すると先に用意したテーブルのカラムが表示される。ここでは「チームID」と「チーム名」であるが、最初の「チームID」を指定したところで上記のような「Apply to each」のネストが自動的に作られる。JSONのデータ構造から気を利かせてくれているようであるが、この手順を得るのに少々手こずった。

課題

Graphについては特に課題は残っていない。しかしExcel操作については上述している可能かどうかも解らないブックの生成や、アクションも用意されているテーブルの動的定義などが現在でも方法が不明である。

今回は結果をExcelに出力したがCSVにも出力してみた。こちらはまた後ほど。