Slackに設定できるRSSのDiscord版を作りたく、自作した
主に欲しかったのはセキュリティ系の情報でRSSがちょうど良かった
XもRSSに対応してくれ
全てをRSSにしたいそんな気持ち
Stackは
Cloudflare Worker
Cron Trigger
Cloudflare D1
TypeScript
XMLのパースは [htmlparser2](https://github.com/fb55/htmlparser2)
実装は雑
RSS から定期的に記事を取ってきてDBに保存、差分があったら通知する
メインロジックはこれ
毎回INSERT OR IGNOREして、D1のmeta.changesが1だったら、保持して、Discordに投げている
const result = await env.DB.prepare(
"INSERT OR IGNORE INTO FeedItem (FeedId, Link, Title, PubDate) VALUES (?, ?, ?, ?)"
).bind(
feedsFromDB.results[0].id,
item.title || "",
item.pubDate ? item.pubDate.toISOString().slice(0, -5).replace("T", " ") : "",
).run()
if (result.meta.changes === 1) {
const feedItemFromDB = await env.DB.prepare('SELECT * FROM FeedItem WHERE Link = ?').bind(item.link).all<FeedItem>();
if (feedItemFromDB.results.length != 1) {
throw new Error(`something happened: ${JSON.stringify(feedItemFromDB)}`)
}
return feedItemFromDB.results[0];
}
Discordに投げるコードはこれ
const postDiscord = async (env: Bindings, feedItems: Array<FeedItem>) => {
const cotent = feedItems.map(feedItem => {
return `**${feedItem.Title}**\n\n \n${feedItem.Link}\n${feedItem.PubDate}`
}).join('\n\n')
const result = await fetch(env.DISCORD_WEBHOOK_URL, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
content: cotent
})
})
}
これを毎日JSTの12時に実行している
結果
こんな感じでいい感じにくる