やりたいこと
「Qiita organizationページの更新をSlackで通知させる」で紹介した通り、SlackのRSSアプリがイケていなかったので、Qiita organazationからSlackへ投稿したい情報をパース / 投稿するbotを作る。
仕様
bot仕様を掻い摘んで説明します。
- RSSフィールド取得先URLは以下の通りとする
http://qiita.com/organizations/<organization名>/activities.atom
- 前回の投稿通り、organazationページからatomを取得します
- 1時間毎にatomをパースし、メッセージを投稿する
- atomの確認頻度は1時間毎とします
- 1時間の内、複数の投稿があった場合は記事毎にメッセージを投稿するようにします
- よって、直近1時間の投稿をお知らせする形になります
実装
Slack botでメッセージを投稿する方法はいくらでも情報があるので、atomのパースに焦点を当てて紹介していきます。
import feedparser
from datetime import datetime as dt
import datetime
import logging
def get_atom():
msg_arr = [] // botで投稿する文章は配列に格納し、1行ずつSlackへ投稿します
d_atom = feedparser.parse('http://qiita.com/organizations/<organization名>/activities.atom')
if len(d_atom['entries']) == 0:
msg_arr.append("ERROR:atom is invalid")
logging.error('atom is invalid')
return msg_arr
// 1時間前と現在の時刻をdatetimeで取得します
from_time = dt.now() - datetime.timedelta(hours=1)
to_time = dt.now()
// ここからatomを1行ずつ確認していきます
i = 0
while i < len(d_atom):
tdatetime = dt.strptime(d_atom['entries'][i]['published'], '%Y-%m-%dT%H:%M:%SZ')
// 投稿された時間が1時間以内でない場合、以降の行も同様になるので、ループから抜けます
if not from_time <= tdatetime <= to_time:
break
// テキストに挿入する情報を取得します
author = d_atom['entries'][i]['author']
published = d_atom['entries'][i]['published']
link = d_atom['entries'][i]['link']
title = d_atom['entries'][i]['title']
// formatを使うのをサボったのですが、formatを使用した方が良いですね…
msg = tdatetime.strftime("%Y-%m-%d %H:%M") + "に" + author + "さんの記事が投稿されました。\r\nタイトル:<" + link + "|" + title + ">"
msg_arr.append(msg)
i += 1
return msg_arr
課題点
実際に動作確認をしてみたところ、アドベンドカレンダーの公開を検知できないという課題が見つかったので、今後対処してきたいです。
アドベンドカレンダーは7:00に公開されますが、どうやらatomのpublishedは限定公開した時間になってしまうようです。(で、合っていると思う…)
改良案として、更新時間を変数に格納しておき、1時間おきに差分があった場合は更新を通知する、という方法を考えています。