Office 365 の障害情報は、Office 365 の管理者であれば Microsoft 365 管理センターから確認することができますが、毎回確認しにいくのも面倒ですし、管理者以外のユーザーとも共有しておきたいといった要望も出てくることがあります。

また、こうした障害情報は、現在プレビュー中の Office 365 Service Communications API を利用することで取得することができます。

Office 365 Service Communications API reference (Preview)
http://docs.microsoft.com/en-us/office/office-365-management-api/office-365-service-communications-api-reference

HTTP を利用した REST API で取得できるのであれば、Microsoft Flow の HTTP アクションを利用して要望が実現できそうだなと思い試してみました。

Azure AD にアプリを登録

まずは、Office 365 Service Communications API を利用できるように、Azure AD にアプリを登録します。

Azure の管理画面を開き、Azure Active Directory の [アプリの登録] から [新規登録] をクリックして始めます。今回の手順では「リダイレクト URI」の登録は不要でした。

[API のアクセス許可] では、最小限のものを設定したいので、「Microsoft.Graph」の「User.Read」は削除しておきます。

そして、[アクセス許可の追加] から、「Office 365 Management APIs」を選択し、「アプリケーションの許可」-「ServiceHealth」にある「ServiceHealth.Read」を選択します。

このアクセス許可には、管理者の同意が必要なので、今回は簡単に [<テナント名> に管理者の同意を与えます] をクリックしておきます。

あとは、[証明書とシークレット] から [新しいクライアント シークレット] により、「クライアント シークレット」を生成し、メモしておきます。

そのほか、[概要] から「アプリケーション(クライアント)ID」と「ディレクトリ(テナント)ID」を確認してメモしておきます。

Microsoft Flow の HTTP アクションを設定する

今回利用したい API のアクセス先は次のようになります。contoso.com の部分はテナントに合わせて変更します。

GET https://manage.office.com/api/v1.0/contoso.com/ServiceComms/Messages

Microsoft Flow の HTTP アクションでは、次のように設定できます。(ちなみに HTTP アクションは PREMIUM アクションのため、Flow プラン 1 以上の課金プランが必要です)

ただし、この API では、取得される情報に障害情報のほかにも、メッセージセンターに届く機能更新等の情報もすべて含まれているため、障害情報のみを取り出せるように「クエリ」を設定しておきます。次のように設定します。

「$filter」というクエリを追加し、値として「MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType’Incident’」を指定します。

ちなみにですが、「’Incident’」のほかには「’Unknown’」 「’PlannedMaintenance’」 「’MessageCenter’」が指定できるようです。

あとは、直近に情報が更新された障害情報のみを取得するために、「LastUpdatedTime」でフィルターをします。

たとえば、過去 3 時間以内に情報が更新された障害情報を取得する $filter クエリは次のようになります。

MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and LastUpdatedTime gt @{addHours(utcNow(),-3)}

あとは、先ほど Azure AD に登録したアプリの情報を認証情報として設定します。

このあたりの設定は、過去の記事をご参照ください。

Microsoft Flow の HTTP アクションにある Active Directory OAuth 認証で Microsoft Graph API を利用する
https://idea.tostring.jp/?p=3726

設定に問題がなければ、これで自身のテナントで発生している障害情報が取得できます。

戻り値の利用

今回利用する API は、JSON を結果として返してきます。そのため、HTTP アクションの後続処理として「JSON の解析」アクションを利用します。設定するスキーマの例は下記の通りです。

 {
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "value": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "AffectedWorkloadDisplayNames": {
                        "type": "array"
                    },
                    "AffectedWorkloadNames": {
                        "type": "array"
                    },
                    "Status": {
                        "type": "string"
                    },
                    "Workload": {
                        "type": "string"
                    },
                    "WorkloadDisplayName": {
                        "type": "string"
                    },
                    "ActionType": {},
                    "AffectedTenantCount": {
                        "type": "integer"
                    },
                    "AffectedUserCount": {},
                    "Classification": {
                        "type": "string"
                    },
                    "EndTime": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "Feature": {
                        "type": "string"
                    },
                    "FeatureDisplayName": {
                        "type": "string"
                    },
                    "UserFunctionalImpact": {
                        "type": "string"
                    },
                    "Id": {
                        "type": "string"
                    },
                    "ImpactDescription": {
                        "type": "string"
                    },
                    "LastUpdatedTime": {
                        "type": "string"
                    },
                    "MessageType": {
                        "type": "string"
                    },
                    "Messages": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "MessageText": {
                                    "type": "string"
                                },
                                "PublishedTime": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "MessageText",
                                "PublishedTime"
                            ]
                        }
                    },
                    "PostIncidentDocumentUrl": {},
                    "Severity": {
                        "type": "string"
                    },
                    "StartTime": {
                        "type": "string"
                    },
                    "Title": {
                        "type": "string"
                    }
                },
                "required": [
                    "AffectedWorkloadDisplayNames",
                    "AffectedWorkloadNames",
                    "Status",
                    "Workload",
                    "WorkloadDisplayName",
                    "ActionType",
                    "AffectedTenantCount",
                    "AffectedUserCount",
                    "Classification",
                    "EndTime",
                    "Feature",
                    "FeatureDisplayName",
                    "UserFunctionalImpact",
                    "Id",
                    "ImpactDescription",
                    "LastUpdatedTime",
                    "MessageType",
                    "Messages",
                    "PostIncidentDocumentUrl",
                    "Severity",
                    "StartTime",
                    "Title"
                ]
            }
        }
    }
} 

試してみると、EndTime というプロパティは、Null になっていることがあるので、Null を受け入れられるようにスキーマをちょっとだけ工夫しています。

フローの全体像

この処理をスケジュールで定期実行し、取得されたデータを他のサービスに流していきます。例えば次のようになります。

スケジュールでの定期実行の間隔と、$filter クエリの LastUpdatedTime のフィルターの値を揃えておくと良いかと思います。

動作を確認

今回は Twitter に書き込む処理にしたので、実行結果は次のようになりました。

上手い具合に障害の更新情報が自動投稿されるのを確認できました。

さいごに

今回は、Twitter が連携先でしたが、たとえば社内の IT チームで利用している Microsoft Teams のチームに自動投稿しても良いかもしれません。また、メッセージセンターに届くような今後の機能更新情報も取得できますので、新機能の情報として Yammer に投稿して社内で共有するなども良さそうです。

Office 365 Service Communications API については、まだプレビューではありますが、より詳細なサービスの正常性を取得できる API なども用意されているようです。

こうした API が利用できると、運用面で役に立つことがありそうですね。