【Lambda,Python】RSSの更新をメーリングアドレスで一斉通知する方法

書くこと

みなさんRSSは使ってますか? WEBサイトやブログなどの更新を通知してくれる技術のことですね。

RSSって何?RSSの仕組みを理解し、RSSリーダー「Feedly」を使ってみよう!

RSSとは「Really Simple Syndication」、または「Rich Site Summary」の略語※で、Webサイトのニュースやブログなどの、更新情報の日付やタイトル、その内容の要約などを配信するため技術のことです。RSSは、XML形式で記述されており、RSSリーダーと呼ばれるツールを使用することで、様々なサイトの更新情報や新着情報を自動的に取得することができます。

株式会社アーティス

RSSを使って更新を取得するためにはRSSリーダーを使います。

上の記事で紹介されているFeedlyもそのひとつです。(僕はInoreaderを使っていますが。。)

RSSリーダーを使用しないと通知を取得できないですが、メール更新一斉に通知する方法を考えてみました。

図解

仕組みを図解すると以下のとおりです。

なぜこのようなことを考えたか

障害情報などもRSSで取得できることは多々あります。たとえばAWS Service Health Dashboard

メーリングアドレスを使えば、異なる部署会社間をまたいで障害情報共有できます

所属する組織が違う場合、同じRSSリーダーを共有で使うことはなかなかできないと思います。

なのでメールで一斉通知する方法を考えてみました。

使用するAWSサービス

  • Lambda
    Pythonを組み込み、RSSフィードから更新をチェックするプログラムを実装します。そしてRSSに更新があった場合SESを呼び出します。
  • SES
    Pythonから呼び出され、RSSの更新をメールで通知するために使用します。
  • Amazon EventBridge
    Lambdaを定期的にトリガーするために使用します。また今回は、「定数 (JSON テキスト)」を使用して更新間隔(秒)をLambdaのPythonに渡すこともやってみます。

今回更新チェックするRSS

AWS Service Health DashboardAsia/TokyoリージョンのEC2のRSSをチェックしたいと思います。

上のリンクをクリックして、[Asia Pacific]のタブをクリックし、「Amazon Elastic Compute Cloud (Tokyo)」の行のRSSのアイコンをクリックします。

そうすると以下のようなXMLで構造化されたページが表示されます。(文字化けする場合はダウンロードしてエディタで開いて見てください)

この<item>〜</item>がひとつのRSS更新(投稿)となります。以下の5つの要素が確認できると思います。

  1. <title>〜</title>
  2. <link>〜</link>
  3. <pubDate>〜</pubDate>
  4. <guid>〜</guid>
  5. <description>〜</description>
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title><![CDATA[Amazon Elastic Compute Cloud (Tokyo) Service Status]]></title>
    <link>http://status.aws.amazon.com/</link>
    <language>en-us</language>
    <lastBuildDate>Mon, 22 Nov 2021 00:05:34 PST</lastBuildDate>
    <generator>AWS Service Health Dashboard RSS Generator</generator>
    <description><![CDATA[Amazon Elastic Compute Cloud (Tokyo) Service Status]]></description>
    <ttl>5</ttl>
    <!-- You seem to care about knowing about your events, why not check out https://docs.aws.amazon.com/health/latest/ug/getting-started-api.html -->

	 
	 <item>
	  <title><![CDATA[Service is operating normally: [RESOLVED] インスタンスの障害について | Instance impairments]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 19 Feb 2021 12:54:00 PST</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1613768040</guid>
	  <description><![CDATA[(5:54AM JST)日本時間 02/19 11:01 PM から、AP-NORTHEAST-1 リージョンのうちの1つのアベイラビリティーゾーンの一部の区画で室温の上昇を確認いたしました。日本時間 02/19 11:03 PM から、室温が上昇した結果として、一部の EC2インスタンスが影響を受け、一部のEBSボリュームではパフォーマンスが低下しました。根本的な原因は、影響を受けたアベイラビリティーゾーンのセクション内の冷却システムへの電力の喪失であり、すでに回復済みです。日本時間 02/20 03:30 AM までに、電力は冷却システム内のほとんどのユニットで復旧し、室温は通常のレベルに戻りました。日本時間 02/20 04:00 AM までに、EC2 インスタンスと EBS ボリュームの回復が始まり、日本時間 02/20 05:30 AM 時点で、影響を受けた EC2 インスタンスと EBS ボリュームの大部分は通常通り動作しております。一部のインスタンスとボリュームは、イベントによって影響を受けたハードウェア上でホストされていました。引き続き影響を受けたすべてのインスタンスとボリュームの復旧に取り組み、Personal Health Dashboard を通じて、現在も影響を受けているお客様に対し通知を行います。即時の復旧が必要な場合は、影響を受けているインスタンスまたはボリュームを置き換えていただくことをお勧めします。| Starting at 6:01 AM PST, we experienced an increase in ambient temperatures within a section of a single Availability Zone within the AP-NORTHEAST-1 Region. Starting at 6:03 AM PST, some EC2 instances were impaired and some EBS volumes experienced degraded performance as a result of the increase in temperature. The root cause was a loss of power to the cooling system within a section of the affected Availability Zone, which engineers worked to restore. By 10:30 AM PST, power had been restored to the majority of the units within the cooling system and temperatures were returning to normal levels. By 11:00 AM PST, EC2 instances and EBS volumes had begun to recover and by 12:30 PM PST, the vast majority of affected EC2 instances and EBS volumes were operating normally. A small number of remaining instances and volumes are hosted on hardware which was adversely affected by the event. We continue to work to recover all affected instances and volumes and have opened notifications for the remaining impacted customers via the Personal Health Dashboard. For immediate recovery, we recommend replacing any remaining affected instances or volumes, if possible.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] インスタンスの障害について | Instance impairments]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 19 Feb 2021 12:09:00 PST</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1613765340</guid>
	  <description><![CDATA[(5:09AM JST)アベイラビリティゾーン (apne1-az1) で影響を受けた一部の区画の室温は安定し、通常のレベルに戻りました。多くの EC2インスタンスは回復済みとなっております。多くの EBSボリュームも回復済みですが、残りの少数のボリュームの復旧作業に引き続き取り組んでおります。| Temperatures within the affected section of the Availability Zone (apne1-az1) remain stable and at normal levels. We have now recovered the vast majority of EC2 instances. The majority of EBS volumes have also recovered but there are a few that have required some engineering intervention that we are working on.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] インスタンスの障害について | Instance impairments]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 19 Feb 2021 11:26:00 PST</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1613762760</guid>
	  <description><![CDATA[(4:26AM JST) AP-NORTHEAST-1 リージョンのうちの 1 つのアベイラビリティーゾーン (apne1-az1) で影響を受けていた冷却サブシステムの電源が回復しました。現在、室温は通常レベルで運用されています。大部分の ES2 インスタンスと EBS ボリュームが復旧しておりますが、残りのインスタンスとボリュームの復旧作業に引き続き取り組んでいます。| We have now restored power to the cooling subsystem within the affected section of the Availability Zone (apne1-az1) in the AP-NORTHEAST-1 Region. Temperatures are now operating at normal levels. We are also seeing recovery for the majority of EC2 instances and EBS volumes and continue to work on the remaining instance and volumes.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] インスタンスの障害について | Instance impairments]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 19 Feb 2021 10:42:00 PST</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1613760120</guid>
	  <description><![CDATA[(3:42AM JST)AP-NORTHEAST-1 リージョンのうちの 1 つのアベイラビリティーゾーン (apne1-az1) のある一部の区画で影響を受けていた冷却ユニットの多くの電源が回復しました。室温は通常のレベルに近い状況まで戻り、ネットワーク、EC2 および EBS ボリュームの回復処理を開始しています。ネットワークはすでに回復し、EC2とEBSボリューム の回復処理に着手しております。回復処理が始まると再起動が発生するため、お客様にはお使いのインスタンスでアクションをとっていただく場合がございます。EBSボリュームに関しましては、ボリュームが回復するにつれ、degraded I/Oパフォーマンスが通常に戻ります。 ”stopping” もしくは ”shutting-down” のまま止まってしまっているインスタンスに関しましては、回復処理が進むにつれ、 ”stopped” もしくは “terminated” に戻ります。| We have now restored power to the majority of the cooling units within the affected section of the Availability Zone (apne1-az1) in the AP-NORTHEAST-1 Region. Temperatures are now close to normal levels and we have begun the process of restoring networking, EC2 instances and EBS volumes. The network has been restored within the affected section of the Availability Zone and we are now working on EC2 instances and EBS volumes. As they begin to recover, customers may need to take action on their instance as it will have experienced a reboot. For EBS volumes, degraded I/O performance will return to normal levels as volumes recover. For instances that are stuck “stopping” or “shutting-down”, these will return to the “stopped” or “terminated” state as recovery proceeds.
]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] インスタンスの障害について | Instance impairments]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 19 Feb 2021 09:43:00 PST</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1613756580</guid>
	  <description><![CDATA[(2:43AM JST)AP-NORTHEAST-1 リージョンのうちの 1 つのアベイラビリティーゾーン (apne1-az1) のある一部の区画での温度上昇に対処するために引き続き取り組んでいます。温度の上昇は当該セクション内の冷却装置への電力損失によって発生しました。当該セクション内のいくつかの冷却ユニットの電力はすでに復元しており、温度が低下し始めていることを確認しております。残りのオフラインの冷却ユニットは引き続き作業を続け、温度を通常レベルに戻します。温度が回復次第、影響を受ける EC2 インスタンスと EBS ボリュームが回復します。EC2 および EBS API を含むその他のシステムは、影響を受けるアベイラビリティーゾーン内で正常に動作しています。影響を受けた EC2 インスタンスおよび EBS ボリュームをお持ちのお客様は、影響を受けたアベイラビリティーゾーン、または AP-NORTHEAST-1 リージョン内の別のアベイラビリティーゾーンでインスタンスの再作成を試みることができます。| We continue to work on addressing the increase in ambient temperature affecting a small section of a single Availability Zone (apne1-az1) in the AP-NORTHEAST-1 region. The increase in temperature is caused by a loss of power to the cooling units within the affected section of the Availability Zone. We have now restored power to a number of the cooling units within this section of the Availability Zone and are starting to see temperatures decreasing. We will continue to work through the remaining cooling units that are still offline, which will return temperatures to normal levels. Once temperatures have recovered, we would expect to see affected EC2 instances and EBS volumes begin to recover. Other systems, including EC2 and EBS APIs, are operating normally within the affected Availability Zone. Customers with affected EC2 instances and EBS volumes can attempt to relaunch in the affected Availability Zone, or another Availability Zone within the AP-NORTHEAST-1 Region.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] インスタンスの障害について | Instance impairments]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 19 Feb 2021 08:40:00 PST</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1613752800</guid>
	  <description><![CDATA[(1:40AM JST)AP-NORTHEAST-1 リージョンのうちの 1 つのアベイラビリティーゾーン (apne1-az1) のある一部の区画での温度上昇に対処するために引き続き取り組んでいます。温度の上昇は、当該セクション内の冷却システムへの電力の損失によって発生しました。引き続き、電源の回復に取り組んでおりこれまでに冷却システムの 1つを正常に復旧させました。引き続き温度を通常レベルに復元し、影響を受けた EC2 インスタンスと EBS ボリュームの回復に取り組んでまいります。EC2 および EBS API を含むその他のシステムは、影響を受けたアベイラビリティーゾーン内で正常に動作しています。影響のあった EC2 インスタンスおよび EBS ボリュームをお持ちのお客様は、影響を受けたアベイラビリティーゾーン、または AP-NORTHEAST-1 リージョン内のその別のアベイラビリティーゾーンで再起動を試みることができます。 | We continue to work on addressing the increase in ambient temperature affecting a small section of a single Availability Zone (apne1-az1) in the AP-NORTHEAST-1 region. The increase in temperature is caused by a loss of power to the cooling systems within the affected section of the Availability Zone. We are working to restore power and have successfully brought online one of the cooling systems. We continue to work on restoring temperatures to normal levels and then recovering affecting EC2 instances and EBS volumes. Other systems, including EC2 and EBS APIs, are operating normally within the affected Availability Zone. Customers with affected EC2 instances and EBS volumes can attempt to relaunch in the affected Availability Zone, or another Availability Zone within the AP-NORTHEAST-1 Region. ]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] インスタンスの障害について | Instance impairments]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 19 Feb 2021 07:58:00 PST</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1613750280</guid>
	  <description><![CDATA[(12:58AM JST)現在、東京リージョン AP-NORTHEAST-1 における一つのアベイラビリティゾーン(apne1-az1)の一部で、周囲の温度が上昇している状況を確認いたしました。影響を受けているアベイラビリティーゾーンの一部 EC2 インスタンスでは、接続性の問題または温度上昇の影響に伴い、電源が切れている問題が発生しております。当該問題の影響により、一部 EBS ボリュームにてパフォーマンスが低下しております。本問題の根本原因を特定し、現在解決に向けて対応しております。東京リージョン AP-NORTHEAST-1 におけるその他アベイラビリティゾーンは、この問題の影響を受けておりません。 |  We can confirm that a small area of a single Availability Zone (apne1-az1) is experiencing an increase in ambient temperature in the AP-NORTHEAST-1 Region. Some EC2 instances within the affected section of the Availability Zone have experienced connectivity issues or have powered down as a result of the increasing temperatures. Some EBS volumes are also experiencing degraded performance as a result of the event. We have identified the root cause of the issue and are working towards resolution. Other Availability Zones within the AP-NORTHEAST-1 Region are not affected by this event.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] インスタンスの障害について | Instance impairments]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 19 Feb 2021 07:09:00 PST</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1613747340</guid>
	  <description><![CDATA[(12:09AM JST)現在、東京リージョン AP-NORTHEAST-1 のひとつのアベイラビリティゾーン apne1-az1 において、インスタンスに影響を及ぼす接続性の問題が発生しており、対応を行っております。 |  We are investigating connectivity issues affecting instances in a single Availability Zone (apne1-az1) in the AP-NORTHEAST-1 Region.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Service is operating normally: [RESOLVED] ネットワーク接続性の問題 | Network Connectivity Issues ]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Wed, 21 Oct 2020 21:15:00 PDT</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1603340100</guid>
	  <description><![CDATA[日本時間11:42から11:53の間、AP-NORTHEAST-1リージョンのアベイラビリティゾーン(APNE1-AZ2)における一部のインスタンスにおいて、ネットワーク接続性の問題がありました。また、日本時間11:42から13:09の間、同アベイラビリティゾーンにおける一部のEBSボリュームにおいて、ボリュームパフォーマンスの低下がありました。問題は解消し、現在正常に稼働しております | Between 7:42 PM PDT and 7:53 PM PDT we experienced network connectivity issues for some instances in a single Availability Zone (APNE1-AZ2) in the AP-NORTHEAST-1 Region. Between 7:42 PM and 9:09 PM PDT, we also had degraded volume performance for some EBS volumes in that Availability Zone. The issue has been resolved and the service is operating normally.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] ネットワーク接続性の問題 | Network Connectivity Issues ]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Wed, 21 Oct 2020 20:41:00 PDT</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1603338060</guid>
	  <description><![CDATA[一部のEC2インスタンスに影響を与えていたネットワーク接続性の問題は解消しました。AP-NORTHEAST-1リージョンのアベイラビリティゾーン(APNE1-AZ2)における一部のEBSボリュームのパフォーマンス低下の問題については、引き続き調査を行っております | The networking connectivity issues affecting some EC2 instances have been resolved but we continue to investigate degraded performance for some EBS volumes within the affected Availability Zone (APNE1-AZ2) in the AP-NORTHEAST-1 Region. ]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: [RESOLVED] ネットワーク接続性の問題 | Network Connectivity Issues ]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Wed, 21 Oct 2020 20:10:00 PDT</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1603336200</guid>
	  <description><![CDATA[AP-NORTHEAST-1リージョンのアベイラビリティゾーン(APNE1-AZ2)における一部のEC2インスタンスおよびEBSボリュームのパフォーマンス低下に関するネットワーク接続性の問題を調査しております。 | We are investigating network connectivity issues for some EC2 instances and degraded volume performance for some EBS volumes in a single Available Zone (APNE1-AZ2) in the AP-NORTHEAST-1 Region.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Service is operating normally: インスタンスの接続性について | Instance Availability]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 23 Aug 2019 04:18:35 PDT</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1566559115</guid>
	  <description><![CDATA[日本時間 2019年8月23日 12:36 より、AP-NORTHEAST-1 の単一のアベイラビリティゾーンで、一定の割合の EC2 サーバのオーバーヒートが発生しました。この結果、当該アベイラビリティゾーンの EC2 インスタンス及び EBS ボリュームのパフォーマンスの劣化が発生しました。このオーバーヒートは、影響を受けたアベイラビリティゾーン中の一部の冗長化された空調設備の管理システム障害が原因です。日本時間 15:21 に冷却装置は復旧し、室温が通常状態に戻り始めました。温度が通常状態に戻ったことで、影響を受けたインスタンスの電源が回復しました。日本時間 18:30 より大部分の EC2 インスタンスと EBS ボリュームは回復しました。 我々は残りの EC2 インスタンスと EBS ボリュームの回復に取り組んでいます。少数の EC2 インスタンスと EBS ボリュームが電源が落ちたハードウェア ホスト上に残されています。我々は影響をうけた全ての EC2 インスタンスと EBS ボリュームの回復のための作業を継続しています。 早期回復の為、可能な場合残された影響を受けている EC2 インスタンスと EBS ボリュームのリプレースを推奨します。いくつかの影響をうけた EC2 インスタンスはお客様側での作業が必要になる可能性がある為、 後ほどお客様個別にお知らせすることを予定しています。<br><br>詳細は <a href="https://aws.amazon.com/message/56489/">こちら</a> をご参照ください。追加のご質問がある場合は、<a href="https://aws.amazon.com/support">AWS サポート</a>までご連絡ください。 | Beginning at 8:36 PM PDT a small percentage of EC2 servers in a single Availability Zone in the AP-NORTHEAST-1 Region shutdown due to overheating. This resulted in impaired EC2 instances and degraded EBS volume performance for resources in the affected area of the Availability Zone. The overheating was caused by a control system failure that caused multiple, redundant cooling systems to fail in parts of the affected Availability Zone. The chillers were restored at 11:21 PM PDT and temperatures in the affected areas began to return to normal. As temperatures returned to normal, power was restored to the affected instances. By 2:30 AM PDT, the vast majority of instances and volumes had recovered. We have been working to recover the remaining instances and volumes. A small number of remaining instances and volumes are hosted on hardware which was adversely affected by the loss of power. We continue to work to recover all affected instances and volumes. For immediate recovery, we recommend replacing any remaining affected instances or volumes if possible. Some of the affected instances may require action from customers and we will be reaching out to those customers with next steps.<br><br>Additional details are available <a href="https://aws.amazon.com/message/56489/">here</a>. If you have additional questions, please contact <a href="https://aws.amazon.com/support">AWS Support</a>.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Informational message: インスタンスの接続性について | Instance Availability]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 23 Aug 2019 02:39:42 PDT</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1566553182</guid>
	  <description><![CDATA[The majority of impaired EC2 instances and EBS volumes experiencing degraded performance have now recovered. We continue to work on recovery for the remaining EC2 instances and EBS volumes that are affected by this issue. This issue affects EC2 instances and EBS volumes in a single Availability Zone in the AP-NORTHEAST-1 region.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Service degradation: インスタンスの接続性について | Instance Availability]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Fri, 23 Aug 2019 01:54:51 PDT</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1566550491</guid>
	  <description><![CDATA[Recovery is in progress for instance impairments and degraded EBS volume performance within a single Availability Zone in the AP-NORTHEAST-1 Region. We continue to work towards recovery for all affected instances and EBS volumes.]]></description>
	 </item>
         
	 <item>
	  <title><![CDATA[Service degradation: インスタンスの接続性について | Instance Availability]]></title>
	  <link>http://status.aws.amazon.com/</link>
	  <pubDate>Thu, 22 Aug 2019 23:40:01 PDT</pubDate>
	  <guid isPermaLink="false">http://status.aws.amazon.com/#ec2-ap-northeast-1_1566542401</guid>
	  <description><![CDATA[We are starting to see recovery for instance impairments and degraded EBS volume performance within a single Availability Zone in the AP-NORTHEAST-1 Region. We continue to work towards recovery for all affected instances and EBS volumes.]]></description>
	 </item>
        
  </channel>
</rss>

Lambdaに実装するPythonプログラム

全貌

Lambdaに実装するPythonの全体は以下のようになります。

####################################################
## AWS Service Health DashboardのEC2(Asia/Tokyo)の
## サービスステータスをチェックするPythonプログラム
####################################################
import xml.etree.ElementTree as ET
import json
import datetime
import urllib.request as URLB
import boto3
from botocore.exceptions import ClientError, ParamValidationError

## 変数設定
rss_url = "https://status.aws.amazon.com/rss/ec2-ap-northeast-1.rss" # 更新をチェックしたいRSSのURL
interval_sec = 900 # 更新をチェックする間隔(900秒=15分)


######################################
# RSS投稿のタイムゾーンをチェックして
# JTCに変換した日時を戻り値として返す
######################################
def Change_to_JTC(rss_date):
    try:
        date_split = rss_date.split(",")
        date_array = date_split[1].split(" ")
        date_MM = date_array[3] + "-" + date_array[2] + "-" + date_array[1] + " " + date_array[4]
        date_mm = datetime.datetime.strptime(date_MM, "%Y-%b-%d %H:%M:%S")
        
        if date_array[5] == "PST":
            delta_hours = datetime.timedelta(hours = 17)
            date_JST = date_mm + delta_hours
        elif date_array[5] == "PDT":
            delta_hours = datetime.timedelta(hours = 16)
            date_JST = date_mm + delta_hours

        return date_JST
    
    except ClientError as e:
        print("Error occured in Change_to_JTC.()")
        print(e.response["Error"]["Message"])
        exit()


###########################################################################
# AWS Service Health DashboardのEC2(Asia/Tokyo)のRSSの更新をチェック
# interval_sec以内の投稿の場合、"投稿日時"、"タイトル"、"リンク"、"説明文"を返す
###########################################################################
def Check_EC2_RSS(rss_url):
    try:
        feed = ET.fromstring(URLB.urlopen(rss_url).read())

        for item in feed.iter("item"):
            pubTitle = item[0].text
            pubDate = item[2].text
            pubGuid = item[3].text
            pubDescription = item[4].text
            
            if pubDate != "None":
                # RSS投稿日時をJTCに変換
                pubDate_JTC = Change_to_JTC(pubDate)

                # 現在日時を取得してJTCに変換
                nowDate_UTC = datetime.datetime.now()
                nowDate_JTC = nowDate_UTC + (datetime.timedelta(hours = 9))

                # RSS投稿日時から現在日時までの経過秒数を取得
                deltaDate = nowDate_JTC - pubDate_JTC 
                deltaSec = deltaDate.total_seconds()

                # 経過秒数が更新をチェックする間隔(900秒)以内のものか判定
                duration_sec = deltaSec - interval_sec
                if duration_sec <= 0:
                    # RSSの投稿日時、タイトル、リンク、説明文を返す
                    return pubDate_JTC, pubTitle, pubGuid, pubDescription
                
    except ClientError as e:
        print("Error occured in Check_EC2_RSS().")
        print(e.response["Error"]["Message"])
        exit()


########################################
# SESでメール送信をする関数
########################################
def Send_Mail(mail_body):
    sender = "XXXXX@gmail.com"
    toAddr = ["XXXXX@gmail.com"]
    ccAddr = ["XXXXX@outlook.com"]
    aws_region = "ap-northeast-1"
    charset = "UTF-8"
    client = boto3.client("ses", region_name = aws_region)

    try:
        response = client.send_email(
            Destination = {
                "ToAddresses": toAddr,
                "CcAddresses": ccAddr,
            },
            Message = {
                "Body": {
                    "Html": {
                        "Charset": charset,
                        "Data": mail_body,
                    },
                },
                "Subject": {
                    "Charset": charset,
                    "Data": "Asia/TokyoのEC2に何かあったみたいだよ。",
                },
            },
            Source = sender,
        )

    except ClientError as e:
        print("Error occured in SendMail().")
        print(e.response["Error"]["Message"])
        exit()
    else:
        print("SESからメールが送信されたよ。"),
        print(response["MessageId"])
    

########################################
# メイン処理
########################################
def lambda_handler(event, context):
    try:
        mail_item = Check_EC2_RSS(rss_url)
        
        if mail_item :
            #メール本文作成処理
            BODY = """
                    <html>
                        <head></head>
                            <body>
                                <p>
                                更新日時:{}<br>
                                タイトル:{}<br>
                                リンク  :{}<br>
                                説明文      :{}<br>
                                </p>
                            </body>
                    </html>
                    """
            mail_body = BODY.format(mail_item[0],
                                    mail_item[1],
                                    mail_item[2],
                                    mail_item[3])
            
            Send_Mail(mail_body)

    except ClientError as e:
        print("Error occured in lambda_handler().")  
        print(e.message)
        exit()

解説

ではPythonプログラムを解説していきます。

######################################
# RSS投稿のタイムゾーンをチェックして
# JTCに変換した日時を戻り値として返す
######################################
def Change_to_JTC(rss_date):
    try:
        date_split = rss_date.split(",")
        date_array = date_split[1].split(" ")
        date_MM = date_array[3] + "-" + date_array[2] + "-" + date_array[1] + " " + date_array[4]
        date_mm = datetime.datetime.strptime(date_MM, "%Y-%b-%d %H:%M:%S")
        
        if date_array[5] == "PST":
            delta_hours = datetime.timedelta(hours = 17)
            date_JST = date_mm + delta_hours
        elif date_array[5] == "PDT":
            delta_hours = datetime.timedelta(hours = 16)
            date_JST = date_mm + delta_hours

        return date_JST
    
    except ClientError as e:
        print("Error occured in Change_to_JTC.()")
        print(e.response["Error"]["Message"])
        exit()

結論からいうと、ここでは下記の変換を行っています。

曜日, DD 英語月 YYYY HH:MI:SS タイムゾーン → YYYY-MM-DD HH:MI:SS
例)Fri, 19 Feb 2021 12:54:00 PST → 2021-02-20 05:54:00

RSS上の日付を、YYYY-MM-DD HH:MI:SS形式の日付に変換しています。

理由は、YYYY-MM-DD HH:MI:SSの形式でないと、datetime.timedeltaなどで日付に対して時間を加えたり引いたりすることができません。

そして2つの日付を比較して、秒数などで時間差を出すこともできないため、このような変換を行う関数を作成しました。


###########################################################################
# AWS Service Health DashboardのEC2(Asia/Tokyo)のRSSの更新をチェック
# interval_sec以内の投稿の場合、"投稿日時"、"タイトル"、"リンク"、"説明文"を返す
###########################################################################
def Check_EC2_RSS(rss_url):
    try:
        feed = ET.fromstring(URLB.urlopen(rss_url).read())

        for item in feed.iter("item"):
            pubTitle = item[0].text
            pubDate = item[2].text
            pubGuid = item[3].text
            pubDescription = item[4].text
            
            if pubDate != "None":
                # RSS投稿日時をJTCに変換
                pubDate_JTC = Change_to_JTC(pubDate)

                # 現在日時を取得してJTCに変換
                nowDate_UTC = datetime.datetime.now()
                nowDate_JTC = nowDate_UTC + (datetime.timedelta(hours = 9))

                # RSS投稿日時から現在日時までの経過秒数を取得
                deltaDate = nowDate_JTC - pubDate_JTC 
                deltaSec = deltaDate.total_seconds()

                # 経過秒数が更新をチェックする間隔(900秒)以内のものか判定
                duration_sec = deltaSec - interval_sec
                if duration_sec <= 0:
                    # RSSの投稿日時、タイトル、リンク、説明文を返す
                    return pubDate_JTC, pubTitle, pubGuid, pubDescription
                
    except ClientError as e:
        print("Error occured in Check_EC2_RSS().")
        print(e.response["Error"]["Message"])
        exit()

更新をチェックしたいRSSのURL(ここではhttps://status.aws.amazon.com/rss/ec2-ap-northeast-1.rss)から、「<title>〜</title>」、「<pubDate>〜</pubDate>」、「<guid>〜</guid>」、「<description>〜</description>」でそれぞれ囲まれた部分を取り出し、変数に格納します。

「<pubDate>〜</pubDate>」で囲まれた投稿日時は、先ほどのChange_to_JTC関数によって日付の形式を変換し、現在日時とどれくらいの時間差(秒)があるか計算します。

そして現在から900秒以内の投稿であれば(interval_sec変数で900秒を指定している)、投稿の内容(タイトル、投稿日時、リンク(guid)、説明)を返します。


########################################
# SESでメール送信をする関数
########################################
def Send_Mail(mail_body):
    sender = "XXXXX@gmail.com"
    toAddr = ["XXXXX@gmail.com"]
    ccAddr = ["XXXXX@outlook.com"]
    aws_region = "ap-northeast-1"
    charset = "UTF-8"
    client = boto3.client("ses", region_name = aws_region)

    try:
        response = client.send_email(
            Destination = {
                "ToAddresses": toAddr,
                "CcAddresses": ccAddr,
            },
            Message = {
                "Body": {
                    "Html": {
                        "Charset": charset,
                        "Data": mail_body,
                    },
                },
                "Subject": {
                    "Charset": charset,
                    "Data": "Asia/TokyoのEC2に何かあったみたいだよ。",
                },
            },
            Source = sender,
        )

    except ClientError as e:
        print("Error occured in SendMail().")
        print(e.response["Error"]["Message"])
        exit()
    else:
        print("SESからメールが送信されたよ。"),
        print(response["MessageId"])

こちらはひとことで言えば、SESを呼び出してメールを送信する関数です。

宛先(TO、CC)や、送信元のメールアドレスを指定します。

メールのタイトルは、ここでは「Asia/TokyoのEC2に何かあったみたいだよ。」にしています。


########################################
# メイン処理
########################################
def lambda_handler(event, context):
    try:
        mail_item = Check_EC2_RSS(rss_url)
        
        if mail_item :
            #メール本文作成処理
            BODY = """
                    <html>
                        <head></head>
                            <body>
                                <p>
                                更新日時:{}<br>
                                タイトル:{}<br>
                                リンク  :{}<br>
                                説明文      :{}<br>
                                </p>
                            </body>
                    </html>
                    """
            mail_body = BODY.format(mail_item[0],
                                    mail_item[1],
                                    mail_item[2],
                                    mail_item[3])
            
            Send_Mail(mail_body)

    except ClientError as e:
        print("Error occured in lambda_handler().")  
        print(e.message)
        exit()

こちらがメイン処理の関数になります。つまりLambdaが実行されたらこれが一番最初に呼び出されます。

基本的に900秒以内の投稿があるかチェックする(前述した)関数を呼び出し、メール送信する関数(前述した)を呼び出してメールを送信します。

送信するメールの本文にRSS投稿を表示したいため、メール本文を作成する処理をここで入れています。(作成したメール本文はメール送信関数にわたす)

実際にやってみる

900秒以内に投稿されたRSSのチェックでは間隔が短すぎてメールが送信されません。

ここでは意図的にチェックする秒数の範囲を大きく広げて動作確認を行ってみたいと思います。

https://status.aws.amazon.com/rss/ec2-ap-northeast-1.rssの中の最新の投稿は、「Fri, 19 Feb 2021 12:54:00 PST」に投稿されたものです。

Fri, 19 Feb 2021 12:54:00 PST は YYYY-MM-DD HH:MI:SS にすると、2021-02-20 05:54:00 になります。

この記事を書いている今の日時は、2021年 11月27日 土曜日 12時58分05秒 となります。

この2つの日時の経過秒数は、24217445秒です。

なのでPythonプログラムのinterval_sec 変数に25000000を設定して実行してみようと思います。

では実行します。

ログは以下のようになりました。メールが送信されたようです。

メールを確認してみます。

届いています!

Amazon EventBridgeについて

EventBridgeについて触れていませんでしたが、これはただ単純にLambdaを定期的に実行するだけです。

例えばEventBridgeで15分間隔でLambdaを実行する場合は、Lambda内のPythonのinterval_sec変数には900(15分)を指定します。

こうすれば、15分間隔でRSSの更新をチェックし、900秒以内の投稿があった場合にはメールで一斉通知できることになります。

最後に

最後までお読みいただきありがとうございました。

いずれはAWS Service Health Dashboardも、WEB上でサブスクライブすればメールで受信できるようなりそうですが、そのような機能が無いRSSの場合には、今回のプログラムを使っていこうと思います。

また今回のプログラムを作るにあたって、XML構造の情報から値と取ってくることや、不規則な日付形式からJSTに変換をするなど、小技を身につけられたので良かったかなと。

今後ともよろしくお願いします。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

CAPTCHA