RSSフィードからDiscord通知を行うGoogle Apps Script入門
こんにちは!今回は、Google Apps Scriptを使って、RSSフィードの更新をDiscordに通知する方法を解説します。このスクリプトを使えば、お気に入りのブログやニュースサイトの更新を自動でチェックし、Discordで通知を受け取ることができます。
1. スクリプトの全体構造
このスクリプトは、以下の主要な部分で構成されています:
定数の定義
メイン関数(`main`)
RSSフィード処理関数(`processFeed`)
記事処理関数(`processItem`)
Discord送信関数(`sendToDiscord`)
トリガー設定関数(`createTimeTrigger`)
スクリプトプロパティ設定関数(`setScriptProperties`)
それでは、各部分を詳しく見ていきましょう。
2. 定数の定義とスクリプトプロパティ
const SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('SPREADSHEET_ID');
const DISCORD_WEBHOOK_URL = PropertiesService.getScriptProperties().getProperty('DISCORD_WEBHOOK_URL');
ここでは、スクリプトプロパティから重要な情報を取得しています。スクリプトプロパティとは、Google Apps Scriptで使用する変数を安全に保存する機能です。
スクリプトプロパティの設定方法
スクリプトエディタを開く
左側のメニューから「プロジェクトの設定」を選択
「スクリプトプロパティ」タブをクリック
「行を追加」をクリックし、以下の項目を設定:
`SPREADSHEET_ID`: RSSフィードのURLが記載されているスプレッドシートのID
`DISCORD_WEBHOOK_URL`: Discord通知用のWebhook URL
また、以下の関数を使って、コードからスクリプトプロパティを設定することもできます:
function setScriptProperties() {
const scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
'SPREADSHEET_ID': 'あなたのスプレッドシートIDをここに入力',
'DISCORD_WEBHOOK_URL': 'あなたのDiscord WebhookのURLをここに入力'
});
console.log('スクリプトプロパティが設定されました。');
}
この方法を使う場合は、セキュリティ上の理由から、設定後にこの関数を削除することをお勧めします。
3. メイン関数(`main`)
function main() {
console.log('main関数が開始されました。');
const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getActiveSheet();
const data = sheet.getDataRange().getValues();
console.log(`スプレッドシートから ${data.length} 行のデータを取得しました。`);
// ヘッダーを除いてデータを処理
const rssFeeds = data.slice(1).map(row => ({
title: row[0],
url: row[1]
}));
rssFeeds.forEach(processFeed);
}
この関数は、スクリプトの起点となります。主な処理は以下の通りです:
スプレッドシートを開く
データを取得
ヘッダー行を除いてRSSフィードの情報を抽出
各フィードに対して`processFeed`関数を実行
4. RSSフィード処理関数(`processFeed`)
function processFeed(feed) {
console.log(`フィード処理開始: ${feed.title}`);
try {
const xmlContent = UrlFetchApp.fetch(feed.url).getContentText();
const document = XmlService.parse(xmlContent);
const root = document.getRootElement();
const channel = root.getChild('channel');
const items = channel.getChildren('item');
console.log(`${items.length} 件の記事を取得しました。`);
const now = new Date();
const twentyFourHoursAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000);
items.forEach(item => {
const pubDate = new Date(item.getChildText('pubDate'));
if (pubDate >= twentyFourHoursAgo) {
processItem(item, feed.title);
Utilities.sleep(1000); // Discordのレート制限を避けるために1秒待機
}
});
} catch (error) {
console.error(`フィード処理中にエラーが発生しました: ${feed.title}`, error);
sendToDiscord(`エラー: "${feed.title}" のフィード処理中に問題が発生しました。`);
}
}
この関数は各RSSフィードを処理します:
フィードのURLからXMLコンテンツを取得
XMLを解析し、記事(item)を抽出
過去24時間以内の記事のみを処理
各記事に対して`processItem`関数を実行
5. 記事処理関数(`processItem`)
function processItem(item, feedTitle) {
const title = item.getChildText('title');
const link = item.getChildText('link');
const message = `**${feedTitle}**\n[${title}](${link})`;
if (message.trim().length > 0) {
sendToDiscord(message);
} else {
console.log('空のメッセージは送信しません。');
}
}
この関数は個々の記事を処理し、Discord用のメッセージを作成して送信します。
6. Discord送信関数(`sendToDiscord`)
function sendToDiscord(message) {
if (!message || message.trim().length === 0) {
console.log('空のメッセージは送信しません。');
return;
}
console.log('Discordにメッセージを送信中...');
const maxRetries = 5;
let retries = 0;
while (retries < maxRetries) {
try {
const response = UrlFetchApp.fetch(DISCORD_WEBHOOK_URL, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
payload: JSON.stringify({ content: message }),
muteHttpExceptions: true
});
const responseCode = response.getResponseCode();
if (responseCode === 204 || responseCode === 200) {
console.log('Discordへのメッセージ送信が完了しました。');
return;
} else if (responseCode === 429) {
const retryAfter = JSON.parse(response.getContentText()).retry_after;
console.log(`レート制限に達しました。${retryAfter}秒後にリトライします。`);
Utilities.sleep(retryAfter * 1000);
} else {
throw new Error(`Discord API returned status ${responseCode}: ${response.getContentText()}`);
}
} catch (error) {
console.error('Discordへのメッセージ送信中にエラーが発生しました:', error);
retries++;
if (retries >= maxRetries) {
console.error('最大再試行回数に達しました。メッセージの送信を諦めます。');
break;
}
Utilities.sleep(1000 * retries); // 指数バックオフ
}
}
}
この関数はDiscordにメッセージを送信します。主な特徴は:
空のメッセージをチェックして送信しない
エラー発生時に最大5回まで再試行
レート制限に対応(429エラー時に待機)
7. トリガー設定関数(`createTimeTrigger`)
function createTimeTrigger() {
console.log('日次トリガーを作成中...');
ScriptApp.newTrigger('main')
.timeBased()
.everyDays(1)
.atHour(8)
.create();
console.log('日次トリガーの作成が完了しました。');
}
この関数は、スクリプトを毎日自動実行するためのトリガーを設定します。
トリガーの設定方法
スクリプトエディタで`createTimeTrigger`関数を実行
または、スクリプトエディタの左側メニューから「トリガー」を選択し、手動で設定
まとめ
このスクリプトを使えば、お気に入りのRSSフィードの更新を自動的にDiscordで受け取ることができます。初期設定さえ済ませてしまえば、あとは自動で動作するので非常に便利です。
ぜひ、自分好みにカスタマイズして使ってみてください!
追記 Discord側の設定
この記事が気に入ったらサポートをしてみませんか?