2019年2月20日水曜日

特定の Web サイトが更新されたかを Logic Apps/Flow でチェックする

Logic Apps や Flow を使って、特定の Web サイトが更新されたかを検知したいことがあります。RSS が提供されていれば、それをもとに判断できるのですが、Web サイトしか情報がない場合には簡単に行えません。思いつく方法の一つとしては、どこか別のストレージに保存しておき、それと比較する方法がありますが、今回はストレージを利用せずに比較する方法を作成してみました。


Logic Apps と Flow は、通常のアプリケーションや API とは異なる性質があります。それは、長期間実行中の状態になることもよしとする、というものです。通常であれば、処理はできるだけ短時間で終了させるのが正しいとされていますが、Logic Apps や Flow ではその限りではありません。Logic Apps であれば最大 90 日、Flow の場合でも 30 日の間、実行中となってよい仕組みになっています。これは Flow でよく利用される承認機能(Approvalコネクタ)が良い例で、承認を依頼してから終了するまで数日かかることは普通の事です。この考え方を持っていると、今回のように処理がシンプルに行えることもあります。

全体の LogicFlow は以下の様に作成しました。

トリガには、要求(HTTP Request)トリガを利用します。そしてまずは対象となるサイトを HTTP コネクタで取得します。今回、検知しようとしたサイトは Microsoft Flow の Release Note サイト( https://docs.microsoft.com/ja-jp/business-applications-release-notes/powerplatform/released-versions/flow )です。前日に取得した内容と、当日取得した内容を比較して、違いがあれば更新された、という判定を行っています。

ただし、今回のこのサイトは、内部に動的に生成された URL を持つ隠し項目が埋められており、アクセスするタイミングによっては毎回 URL が異なるものが存在していました。そのため、更新日を表していた meta タグの値に限定させて判定を行わせています。このようなものが埋め込まれていないのであれば、HTTP コネクタで取得した値をそのまま比較しても問題はありません。

meta タグに限定させている箇所は、次のように処理を行っています。

先に、HTTP コネクタで取得した HTML の内容を、uriComponent 関数を利用してエンコードを行っています。これは、内部で改行コードなど、Logic Apps や Flow でそのままでは扱えない文字があるためです。例えば \r\n は改行を表しますが、uriComponent 関数を利用すると %0D%0A という文字列になります。その変換結果に対し、行単位に配列へ分割します。この場合 split 関数に指定するのは、先ほど例に挙げた改行コードとなります。


split(uriComponent(body('FlowReleaseNoteを取得')),'%0D%0A')

変換した配列から、meta タグとなっている箇所を抽出します。


equals(startsWith(item(), uriComponent('<meta name=\"updated_at\"')), true)

startsWith 関数は「~で始まるか」を判定する関数です。これを利用して、meta タグを記載しているもののみに、配列を限定させます。今回は、更新日を表す meta データが、updated_at という名前で設定されているのが解析できましたので、その要素のみに限定を行い、フィルタリングした結果をそのまま配列な変数へと設定します。

初回起動時は、比較対象となる前回の結果がありませんので、IF コネクタで判定を行います。前回データは HTTP Request トリガに渡してもらう形になりますので、トリガに何もデータがわたってきていない=前回データがない、という判定です。

前回データが存在した場合、今回取得したデータと比較するために、同じ形となるよう配列変数に設定します。そして配列変数をそれぞれ比較し、違いがあれば更新があった、なければ同一として判定しています。

そして最後に、1日処理を待機させ、その後に今回取得したデータを添付し自分自身を呼び出しています。こうすることで、今回取得したデータを次回処理に引き継ぐことが可能です。特に外部ストレージを経由しなくても、必要情報を受け渡すことができますので、色々とアレンジして利用してみるとよさそうです。

0 件のコメント:

コメントを投稿