Pythonで登録したRSSの新着記事をSlackで受け取るツールを作成してみた
定期購読したいサイトのRSS登録を行い、
新着記事が存在した場合はそれをSlackへ通知するツールをPythonで作成してみました。
機能
ソースはgithubにも上げているので詳しくはそちらを参照下さい。 github.com
RSS登録機能
Slack上からスラッシュコマンドで新規RSSを登録する機能
RSS情報はRedisのハッシュを使って以下のように管理
('RSSから取得したブログタイトル', 'url', 'スラッシュコマンドから受け取ったRSSURL') ('RSSから取得したブログタイトル', 'previous_time', '最後に取得した最新記事の作成日時')
ここに登録したprevious_time
より作成日時が新しい記事のみ取得してSlackへ送信しています。
登録コマンドで送られてくるRSSURLのチェック
# URL形式チェック if re.match(r'^https?:\/\/', url): rss = feedparser.parse(url) … else: msg = 'URLは http://、https:// から記述してください。'
http://
、https://
で始まる文字列でない場合はエラーメッセージを返却
RSSを読み込んだ結果の判定も実施
rss = feedparser.parse(url) # パースが成功している場合のみ処理を行う if rss.bozo == 0: title = rss.feed.title self.redis.add(title, url, self.time_format(rss.entries[1].published)) msg = 'RSS登録完了: {}'.format(title) else: # パースに失敗した場合はエラーを出力して処理続行 print('url: {}, error: {}'.format(url, rss.bozo_exception)) msg = 'URLが存在しないか、またはRSSとして読み取り出来ませんでした。'
feedparser
から返却されるbozo
で判定
bozo
が0ならパース成功、
bozo
が1ならパース失敗
RSS一覧表示機能
Slack上からスラッシュコマンドで登録されているRSSの一覧表示を行う機能
# RSSの一覧を表示 msg = 'RSSList : \n - ' + '\n - '.join([key.decode() for key in self.redis.get_key_all()])
Redisからkeyの一覧を取得してmsgに詰めているだけです。
見た目が悪かったので1タイトルずつ改行して表示させています。
RSS削除機能
Slack上からスラッシュコマンドで登録されているRSSを削除する機能
一覧表示機能で登録されているRSSを確認して削除するイメージです。
# RSS削除を実施 title = params[b'text'][0].decode() self.redis.delete(title) msg = 'RSS削除完了: {}'.format(title)
スラッシュコマンドで受け取ったタイトルをkeyにしてRedisから削除しているだけです。
新着記事通知機能
登録されているRSSを順番に読み込んでいき、
新着記事が存在する場合のみSlackへ通知を行っています。
登録されているkey分繰り返し処理
# 登録されたRSS数分処理を行う for key in self.redis.get_key_all(): # RSSのURL、最後に取得した記事の作成日時を取得 rss_config_dict = self.redis.get(key) url = rss_config_dict[b'url'].decode() # RSS読み取り rss = feedparser.parse(url) …
Redisから取り出したkeyに紐付くRSSURLを読み込んでパースしています。
Slackへ送信するattachments
を作成
def create_attachments(self, rss, last_items, key): """取得した記事からattachmentsを生成""" attachments = [] for i in range(last_items, -1, -1): # 取得した記事の作成日時を保存 published = rss.entries[i].published self.redis.update_previous_time(key, self.time_format(published)) summary = rss.entries[i].summary # 投稿した記事をattachmentに追加 attachments.append( { 'title' : '<{}|{}>'.format(rss.entries[i].link, rss.entries[i].title), # タイトルと記事のリンク 'text' : re.compile(r'<[^>]*?>').sub('', summary) if summary is not None else '', # 記事のサマリー 'footer' : self.time_format(published) # 記事の投稿時間 } ) return attachments
last_items
には取得する新着記事が1件の場合は0、2件の場合は1が入ってくるイメージです。
Redisのprevious_time
を記事の作成日時で更新します。
これで次回実行時に同じ記事を取得しないようにしています。
Slackへ送信しているのはtitle
、link
、summary
、published
のみです。
それをスレッド化して送信すると以下のようになります。
スレッドを開くと以下のようになっています。
こんな感じでSlackからブログの購読が可能になりました。
自分はこれをcronで毎朝7時に実行されるようにして通知を受け取っています。