GASでRSSフィードを取得してDiscordに投稿する
DiscordにはMonitoRSSというBotがあるが、無料では最大で5フィードまでしか購読できないので、Google Apps Scriptを使って自作してみた。
※SlackにもRSSというAppがあり、こちらは制限なし
Webhook
投稿したいチャンネルの設定からIntegrations > Create Webhookを選択してWebhook URLを生成してコピーする。
※Botの名前やアイコン画像を適宜変更する
スプレッドシートを用意
まず購読したいフィードや取得した記事を管理するスプレッドシートを用意して、以下のようにシート名を変更して、購読したいフィードを記載する。
feedsシート
購読するRSSフィードを定義するシート。任意のフィード名(投稿時にハイライト)とRSSリンクを記載する。
A列:RSSフィード名
B列:RSSリンク
articlesシート
このシートは、定期実行でそれぞれのフィードから記事を取得して、自動的に新規記事の行が挿入される。
A列:RSSフィード名
B列:記事タイトル
C列:記事リンク
D列:記事の掲載日時(yyyy-MM-dd'T'HH:mm:ssXXX)
スクリプト
スプレッドシートの拡張機能でApps Scriptを編集する。
フィード定義を取得する
/**
* フィード定義を取得
*/
function getFeeds() {
// feedsシートのA1:B最終行を取得する
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('feeds');
const lastRow = sheet.getDataRange().getLastRow();
const values = sheet.getRange(1,1,lastRow,2).getValues();
const feeds = [];
values.forEach((value) => {
const feed = {};
feed["name"] = value[0];
feed["link"] = value[1];
feeds.push(feed);
});
return feeds
}
RSSフィードから記事を取得する
/**
* RSSフィードから記事を取得する
*/
function getArticles() {
// フィード定義を取得
const feeds = getFeeds();
for (const feed of feeds) {
// RSSの読み込み
let xml = UrlFetchApp.fetch(feed.link).getContentText();
let document = XmlService.parse(xml);
let items = document.getRootElement().getChild('channel').getChildren('item');
// スプレッドシートからデータを取得
let articlesSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('articles');
let lastRow = articlesSheet.getDataRange().getLastRow();
let urls = articlesSheet.getRange(1, 3, lastRow).getValues();
// 新しい記事かどうかを古いアイテム(記事)から比較するため
items.reverse();
// RSSから取得したデータと比較と保存
for (var item of items) {
let title = item.getChild('title').getText();
let link = item.getChild('link').getValue();
let pubDate = Utilities.formatDate(new Date(item.getChild('pubDate').getValue()), "JST", "yyyy-MM-dd'T'HH:mm:ssXXX");
// URLが一致しないときは新しいデータ
if (urls.some(url => url[0] === link)) {
continue;
}
// スプレッドシートへの保存
articlesSheet.appendRow([feed.name, title, link, pubDate]);
// チャンネルに投稿
postToChannel(feed.name, title, link);
console.log(feed.name + ': ' + title);
}
}
}
チャンネルに投稿
/**
* チャンネルに通知を投稿する
* @param {string} name フィード名
* @param {string} title 記事タイトル
* @param {string} link 記事リンク
*/
function postToChannel(name, title, link) {
const webhookURL = "<https://discord.com/api/webhooks/XXXX>";
const message = {
"content": '`' + name + '`\\n' + '**' + title + '**' + '\\n' + link
}
const param = {
"method": "POST",
"headers": { 'Content-type': "application/json" },
"payload": JSON.stringify(message)
}
UrlFetchApp.fetch(webhookURL, param);
}
※Slackに投稿する場合は、message.contentをmessage.textに変更すればよい(こちらを参照)。
定期実行
最後に任意のトリガーを設定して、実行する関数にgetArticlesを設定すれば、定期的に自動でRSSフィードから記事を取得して、新規記事があればチャンネルに投稿される。
参考
この記事が気に入ったらサポートをしてみませんか?