[Power Automate]RSSなしのWebサイトの更新を監視してチャットへ通知する【上級編】
はじめに
この記事は、[Power Automate]Webサイトに新しいページが追加されたらチャットへ通知する【初級編】 の続編です。
初級編の方が手軽な方法ですので、ぜひ初級編からご覧ください。
Webサイトやブログが更新されたことを検知する方法として、RSSフィードは非常に便利な存在です。しかし、昨今ではSNSで情報を追うユーザーも多いため、RSSフィードを提供しないWebサイトも増えてきました。特に企業サイトやニュースサイトでは、RSSを廃止している場合も少なくありません。
RSSフィードが提供されていないWebサイトやWebサービスのフィードを作成できる有料のツール(RSS.appなど)もありますが、有料のツールを導入するほどではないということもありますよね。
今回は、RSSフィードが提供されていないWebサイトの更新情報をPower Automateを使ってsitemap.xmlへ定期的にアクセスすることで監視し、更新されていた場合にチャットツールに通知する方法を解説します。
方針:RSSフィードの代わりにsitemap.xmlを使用する
この方法では、RSSフィードの代わりに多くのWebサイトが提供している sitemap.xml を利用します。sitemap.xml は、Webサイトに存在しているページ情報を一覧化したXMLファイルです。
sitemap.xmlとは?
Google検索セントラルによると、
サイト上のページや動画などのファイルについての情報や、各ファイルの関係を伝えるファイルです。Google などの検索エンジンは、このファイルを読み込んで、より効率的にクロールを行います。
サイトマップについて
sitemap.xmlを設置していなくても、気長に待っていればいつかクローラーが回ってきてくれますが、より効率的にクローリングしてもらうためにも多くのWebサイトがsitemap.xmlを設置しています。
世界で1番シェアの多いCMSであるWordPressでも、以前はプラグインでsitemap.xmlを作成することが多かったのですが、現在ではデフォルトの機能でsitemap.xmlが設置され、自動更新されるよう機能が実装されています。
参考:New XML Sitemaps Functionality in WordPress 5.5
RSSフィードが提供されていないwebサイトであっても、sitemap.xmlは設置されていることが多く、sitemap.xmlファイルの中のlastmod タグにはページの最終更新日が記載されているので、これを活用してWebサイトの更新を検知したいと思います。
事前の注意事項
リアルタイムな更新通知には向いていない
今回解説する方法では、RSSフィードを利用する方法とは異なって、Webサイトが更新されたことを即時に検知することはできません。タイムラグが多少あっても構わないからとにかく更新されたことが分かればOKという時向けですので、ご留意ください。
sitemap.xmlが自動で更新されるWebサイトである必要がある
昔から運営されているWebサイトなどの中にはsitemap.xmlが自動で更新されず、手動で更新しているサイトもあります。
手動でsitemap.xmlを更新しているサイトは、Webサイトの更新タイミングと連動していないので、Webサイトが更新されてもsitemap.xmlは更新されていない、という可能性が生じます。
自分で運営しているWebサイトでない限り、sitemap.xmlが自動で更新されるかどうか正確に把握することは難しいですが、sitemap.xmlが頻繁に更新されている場合には自動更新されていると考えてよいでしょう。反対にlastmodが古い日付のままになっている場合にはsitemap.xmlが長らく更新されていない可能性が高いので、今回紹介する方法で更新を検知することは難しいと判断していただければと思います。
事前準備
使用ツール
- Microsoft Power Automate
- Teams(この記事では通知先をTeamsにしますが、他のチャットツールでも構いません)
- sitemap.xml(今回は例としてZennのsitemap.xmlのURLを利用させていただきます)
事前に確認しておくべきこと
- Microsoft Power Automateにログインできることを確認しておく
- 更新を検知するWebサイトのsitemap.xml(設置されているか事前に確認)
- Teamsに必要に応じてチャネルなど投稿先を用意しておく
sitemap.xmlが設置されているか確認する方法
多くのWebサイトでは、example.com/sitemap.xmlというように、ドメイン直下にsitemap.xmlを格納していることが多いので、URLのドメイン名の後ろに/sitemap.xmlを付けて入力してみてください。WebサイトがWordPressでつくられている場合のパスは、デフォルトでは/wp-sitemap.xmlとなっています。
ただし、必ずしもsitemap.xmlという名称で置いてあるとは限らないので、上記の方法で見つからない場合にはサイトマップチェッカーのようなsitemap.xmlを探すツールを活用してみるのも一つの手です。
監視する対象が自社のサイトの場合は、サイト管理者に問い合わせてsitemap.xmlの格納場所を教えてもらいましょう。
作り方
今回はPower Automate に用意されているテンプレートではなく、自分で一からフローを作成していきます。
1. トリガーの指定
Power Automateのホーム画面から、
ホーム>作成>[スケジュール済み実行クラウドフロー]を選択>必要項目を記入>作成
- フロー名: 何でもOK。分かりやすい名前をつけましょう
- 開始日: 任意の日付
- 時間: 任意の時間
- 繰り返し間隔: 1日
今回は1日に1回、Webサイトのsitemap.xmlにアクセスして、更新されたWebページがないかチェックするフローにしたいと思います。
Webサイトの更新をなるべく即座に知りたい場合には、繰り返し間隔をもっと細かくすることで即時性を高めることができますが、サイトへの負荷を高めてしまいますし、Power Automate の実行回数も増えることになるので、この方法でやる場合には最大でも15分に1回程度にしておくのがいいかと思います。(そもそもサイトの更新を即時に知りたい場合には、今回の方法は向いていないのでRSS.appなどを利用してRSSフィードを作成するなどの別の方法にすることをお勧めします)
2. アクションの流れ
2-1.HTTPリクエストでsitemap.xmlを取得する
トリガーの下の+ボタンから「アクションの追加」をクリックし、検索窓に「HTTP」と入力し、ランタイムは「組み込み」を選択し、候補にでてくる「HTTP」アクションを選択します。
HTTPアクションに入力するのは、URLとMethodの2か所だけです。
URLに更新を監視したいWebサイトのsitemap.xmlのURL、Methodは「GET」を選択します。
2-2.取得したsitemap.xmlのデータをjson形式に変換する
次にHTTPリクエストで取得してきたデータをxml関数を使用してXMLとして認識させ、扱いやすくするためにXMLをJSONに変換します。
「アクションの追加」をクリックし、ランタイムの「組み込み」を選択、Data Operationの中から「作成」アクションを選択します。作成の入力欄から関数欄を選択し、次の関数を入力します。
json(xml(body('HTTP')))
※body('HTTP')部分は、「動的なコンテンツ」から2-1のHTTPの結果であるbodyを選択しても大丈夫です。
2-3.JSONデータの中から必要なオブジェクトだけ抽出してオブジェクト配列にする
JSON形式に変換した現時点でのデータは下記のようになっています。
{
"?xml": {
"@version": "1.0",
"@encoding": "UTF-8"
},
"urlset": {
"@xmlns": "http://www.sitemaps.org/schemas/sitemap/0.9",
"url": [
{
"loc": "https://zenn.dev",
"lastmod": "2024-12-06T03:00:02+09:00",
"changefreq": "always"
},
{
"loc": "https://zenn.dev/topics",
"lastmod": "2024-12-06T03:00:02+09:00",
"changefreq": "daily"
},
{
"loc": "https://zenn.dev/articles",
"lastmod": "2024-12-06T03:00:02+09:00",
"changefreq": "always"
},
{
"loc": "https://zenn.dev/articles/explore",
"lastmod": "2024-12-06T03:00:02+09:00",
"changefreq": "always"
},
...(中略)...
]
}
}
この中でWebサイトの更新を検知するのに必要なのは、lastmodとlocです。lastmodは更新日付、locは更新されたページのURLを表しています。つまり、"urlset"の中の"url"の中のデータだけが必要なので、その部分だけを抽出してオブジェクト配列にしておきましょう。
「変数を初期化する」アクションを選択し、次の内容を入力します。
設定項目 | 値 |
---|---|
Name | urlArray |
Type | [Array]を選択 |
Value | 下記の関数を入力 |
outputs('XMLをJSONにパースする')?['urlset']?['url']
※outputsの中の'XMLをJSONにパースする'の部分は、2-2で作成したアクションにつけた名称に差し替えてください。
これで実行すると、次のように不要なデータが入っていたJSONが、urlのみのすっきりしたオブジェクト配列の状態になります。
[
{
"loc": "https://zenn.dev",
"lastmod": "2024-12-06T03:00:02+09:00",
"changefreq": "always"
},
{
"loc": "https://zenn.dev/topics",
"lastmod": "2024-12-06T03:00:02+09:00",
"changefreq": "daily"
},
{
"loc": "https://zenn.dev/articles",
"lastmod": "2024-12-06T03:00:02+09:00",
"changefreq": "always"
},
{
"loc": "https://zenn.dev/articles/explore",
"lastmod": "2024-12-06T03:00:02+09:00",
"changefreq": "always"
},
...(中略)...
]
なぜオブジェクト配列の状態にするかというと、配列(アレイ)の状態にするとPower Automate の「アレイのフィルター処理」アクションを利用できるようになるためです。このアクションを使用すると、アレイ(配列)の中から条件に合致した値だけを取り出したアレイ(配列)を作ることができるようになります。
「アレイのフィルター処理」について詳しく知りたい方はこちらをご覧ください。
HTML→XML→JSONに変換する処理と一緒にオブジェクト配列にする処理を一緒にしてしまってもよいのですが、アクションの中身が複雑化してしまうのを避けるため段階的に行っています。
2-4.比較する日付を用意する
lastmodがこのフローを実行する前日の0:00以降からフローを実行する日付の0:00までの間であれば、昨日の間に更新されたものとして判定することにします。
昨日の日付と今日の日付は関数を使って作ることができますが、一つのアクションの中で書くと読みづらくなるのであらかじめ用意しておきましょう。
「作成」アクションを2つし、関数の入力欄にそれぞれ下記のように記入します。
※ここでは値を一時的に作りたいだけなので、「作成」アクションを使用しますが、「変数を初期化する」アクションを使用しても構いません。
昨日の日付
addDays(startOfDay(utcNow()), -1)
今日の日付
startOfDay(utcNow())
2-5.lastmodが昨日~今日の間に該当するデータだけを抽出する
アレイのフィルター処理アクションを使用して先ほど作成したurlArrayにフィルターをかけていきます。
アレイのフィルター処理は、基本モードでは条件を一つしか指定することができませんが、詳細設定モードにすると複数の条件を指定することもできます。今回は基本モードで条件を1つずつ指定し、アレイのフィルター処理を2回書く形でやりたいと思います。
2-5-1. 昨日の日付以降のデータだけ抽出する
設定項目 | 値 |
---|---|
From | 雷マークをクリックし、urlArrayを選択 |
左辺 | item()?['lastmod'] |
条件式 | [is greater than]を選択 |
右辺 | outputs('昨日の日付') |
2-5-2. 今日の日付より前のデータだけ抽出する
設定項目 | 値 |
---|---|
From | 雷マークをクリックし、2-5-1の結果であるbody('アレイのフィルター処理 - 昨日の日付と比較')を選択 |
左辺 | item()?['lastmod'] |
条件式 | [is less or equal to]を選択 |
右辺 | outputs('今日の日付') |
2-6.条件に合致したデータをTeamsに通知
lastmodが昨日~今日の間だったデータが2-5-2の結果の配列に入っているはずです。この配列の長さが1以上だったら条件に合致したデータが入っているのでTeamsに通知を送信し、配列の長さが0だったら条件に合致するデータが存在しなかったということなので何もせずにフローを終了します。
2-6-1.条件の指定
アクションを追加からControl配下にある「条件」アクションを選択し、条件アクションに下記の内容を入力します。
設定項目 | 値 |
---|---|
左辺 | length(body('アレイのフィルター処理_-_今日の日付と比較')) |
条件式 | [is greater than]を指定 |
右辺 | 0 |
2-6-2.繰り返し処理
現在条件に合致したデータは2-5-2の配列に入っているので、複数のデータがある可能性があります。
この配列に入っている値を一個ずつ取り出す必要があるので、For each(それぞれに適用する)アクションを使用して繰り返し処理を行います。
雷マークをクリックして、2-5-2の結果であるbody要素を選択します。
2-6-3.Teamsの送信先と投稿内容を設定する
今回は通知先としてTeamsのチャネルに送信しますが、別のチャットツールでも構いませんし、Teamsを使うとしてもチャネルではなく他の投稿先で構いません。ここはご自身の環境にあったツールをご利用ください。
Teamsの場合の設定手順です。
設定項目 | 値 |
---|---|
投稿者* | フローボット |
投稿先* | チャネル |
チーム* | 任意のチームを選択 |
チャネル* | 任意のチャネルを選択 |
メッセージ* | formatDateTime(items('それぞれに適用する')?['lastmod'],'yyyy/MM/dd')にWebページが更新されました!URL: items('それぞれに適用する')?['loc'] |
「それぞれに適用する」アクションに設定してある配列の値はitems()関数を使用して取り出すことができるので、どのオブジェクトのデータを取り出すかは?で指定しましょう。
また、lastmodに入っている日付データは"2024-12-06T03:00:02+09:00"のような形式なので、formatDateTime()関数を使用して読みやすい形式に直すとよいでしょう。
2-6-4.実行結果
昨日~今日の間に更新されたページがあった場合、下記の様なメッセージがTeamsに投稿されます。
まとめ
RSSフィードが提供されていないWebサイトであっても、sitemap.xmlへ定期的にアクセスする仕組みをPower Automateで作成することでサイトの更新を検知することが可能です。
ただし、この方法はあくまでもWebサイトの更新に連動してsitemap.xmlも更新される仕組みになっているWebサイトでしか使用できませんし、更新されたことを即時に通知するようなことには向いていませんのでその点はご了承ください。あくまでPower Automateを既に使っているユーザーがそれ以外のツールに課金することなく、簡易的にWebサイトの更新を検知できる仕組みになります。
簡易的とはいえ、日頃特定のトピックや特定のサイトで情報収集をしている方にとっては役立つフローだと思いますので、ぜひやってみてください。
Discussion