1
/
5

【RSSフィードの活用】最新記事を毎日Gmailで受け取る方法

2024年12月10日に投稿された記事です。

目次

  1. 1. GASプロジェクトを作成する
  2. 2. 読みたい記事のフィードを登録する
  3. 3. 登録した記事をGmailに送信する
  4. 4. 毎日指定の時間に記事が送信されるようにする
  5. さいごに

こんにちは。dotDのエンジニアの前田です。

dotD Advent Calendar 2024の10日目になります。

この記事に書いてある手順を実施してくれたあなたは、「毎日決まった時間に興味のあるサイトの最新記事をGmailで受信」が叶います。
※フィードを提供しているサイトの記事であることを前提としています

スクリプトを作りますが、コピペして少し修正するだけなので、非エンジニアの方でも実現できます!

早速以下の手順をやっていきましょう!

1. GASプロジェクトを作成する

Googleドライブを開き、以下のように、「+新規」ボタンから「その他」→「Google Apps Script」を押下します。

以下が表示されたら、注意書きを読んで問題なかったら、「スクリプトを作成」を押下します。

以下の画面が表示されたらプロジェクト作成に成功です。
画面左上の「無題のプロジェクト」を押下すると、プロジェクト名が変更できるので、「記事をGmailに送信するスクリプト」など、わかりやすくしておきましょう。

2. 読みたい記事のフィードを登録する

画面左のファイルの横にある「+」ボタンを押下して、「スクリプト」を押下します。

ファイル名の入力が求められるので、「feedList」と入力すると、以下のように新規ファイルが作成されます。

次に、読みたい記事の登録方法について説明します。

まず、読みたい記事を公開しているサイトのフィードURLを取得します。
フィードを提供しているサイトなら、一般的にサイト内に「フィード」ボタンや「RSS」テキストリンクがあるので、そちらを押下してURLを取得します。

※公開されているフィードを利用する際は、必ず提供元のサイトの利用規約やポリシーを確認してください。一部のサイトでは、特定の用途においてフィード利用が制限されている場合があります。

以下の形式で、サイト名(名称は任意でok)とフィード名(名称は任意でok)とフィードURLを入力します。

const feedList = {
サイト名: [
{name: "フィード名", url: "フィードURL"},
],
};const feedList = {
サイト名: [
{name: "フィード名", url: "フィードURL"},
],
};

copy

あるサイトの最新記事を受け取りたい場合の例です。

const feedList = {
exampleSite: [
{name: "latest", url: "https://example.com/feed"},
],
};const feedList = {
exampleSite: [
{name: "latest", url: "https://example.com/feed"},
],
};

copy

これで読みたい記事の登録が完了しました。

他にも読みたい記事を増やしたい場合は、以下のように、フィードURLを調べて、サイト名(名称は任意でok)とフィード名(名称は任意でok)とフィードURLを入力します。

const feedList = {
exampleSite: [
{name: "latest", url: "https://example.com/feed"},
],
サイト名: [
{name: "フィード名", url: "フィードURL"},
],
};const feedList = {
exampleSite: [
{name: "latest", url: "https://example.com/feed"},
],
サイト名: [
{name: "フィード名", url: "フィードURL"},
],
};

copy

サイトによっては、特定のカテゴリーの記事のフィードなど複数のフィードを提供している場合があります。
その場合は以下のように入力すれば、同じサイトで複数のフィードの記事を登録することができます。

const feedList = {
サイト名: [
{name: "フィード名1", url: "フィードURL1"},
{name: "フィード名2", url: "フィードURL2"},
],
};const feedList = {
サイト名: [
{name: "フィード名1", url: "フィードURL1"},
{name: "フィード名2", url: "フィードURL2"},
],
};

copy

2つのサイトの記事(1つは最新記事のみで、もう1つは最新記事とITカテゴリーの最新記事)を受け取りたい場合の例です。

const feedList = {
exampleSite1: [
{name: "latest", url: "https://example.com/feed1"},
],
exampleSite2: [
{name: "latest", url: "https://example.com/feed2"},
{name: "it", url: "https://example.com/it/feed2"},
],
};
const feedList = {
exampleSite1: [
{name: "latest", url: "https://example.com/feed1"},
],
exampleSite2: [
{name: "latest", url: "https://example.com/feed2"},
{name: "it", url: "https://example.com/it/feed2"},
],
};

copy

上記形式で、読みたい記事を登録できたら、それをファイルにコピペします。
Macユーザーは「command + s」、Windowsユーザーは「ctrl + s」でファイルを保存します。

3. 登録した記事をGmailに送信する

まず、「コード」というファイルの名前を「main」に変更しましょう。

そして、以下のコードをmainファイルにコピペします。

function sendTargetArticleToGmail() {
try {
// 送信したい記事を指定する
const feedUrls = [
getFeedUrl("xxx", "xxx"),
getFeedUrl("xxx", "xxx"),
getFeedUrl("xxx", "xxx"),
];

// 送信したい記事の件数
const articleCount = 10;

// 記事を送信したいメールアドレスを指定
const recipient = "xxx@gmail.com";

// 件名
const subject = "各フィードの記事";

// メール本文
let emailBody = "";

feedUrls.forEach((feedUrl) => {
emailBody += `# フィードURL: ${feedUrl}\n\n`;

// XMLのルート要素を取得
const response = UrlFetchApp.fetch(feedUrl);
const xml = XmlService.parse(response.getContentText());
const root = xml.getRootElement();

// 記事の取得
const articles = getArticle(root, articleCount);

// 記事がない場合
if (articles.length === 0) {
emailBody += "記事が見つかりませんでした。\n\n";
return;
}

// メール本文に記事のタイトルとリンクを追記
const articleTitleAndLink = articles.map(item => `## ${item.title}\n${item.link}`).join("\n\n");
emailBody += articleTitleAndLink;

emailBody += "\n\n--------------------------------------------\n\n";
});

GmailApp.sendEmail(recipient, subject, emailBody);
Logger.log("メールが正常に送信されました。");
} catch (e) {
Logger.log(e.message);
}
}

function getFeedUrl(site, name) {
const feeds = feedList[site];
if (!feeds) {
throw new Error(`サイト'${site}'が存在しません。`);
}
const feed = feeds.find(feed => feed.name === name);
if (!feed) {
throw new Error(`'${name}'のフィードが、サイト'${site}'に存在しません。`);
}
return feed.url;
}

function getArticle(xmlRoot, articleCount) {
if (xmlRoot.getName() === "feed") {
// Atom形式の場合
const entries = xmlRoot.getChildren("entry", xmlRoot.getNamespace()).slice(0, articleCount);

return getAtomArticleTitleAndLink(xmlRoot, entries);
} else if (xmlRoot.getName() === "rss") {
// RSS形式の場合
const entries = xmlRoot.getChild("channel").getChildren("item").slice(0, articleCount);;

return getRssArticleTitleAndLink(entries);
}

return [];
}

function getAtomArticleTitleAndLink(xmlRoot, entries) {
const articleTitleAndLinkList = [];

entries.forEach((entry) => {
try {
// Atom形式のタイトルとリンク
const titleElement = entry.getChild("title", xmlRoot.getNamespace());
const linkElement = entry.getChild("link", xmlRoot.getNamespace());

const title = titleElement ? titleElement.getText() : "タイトル不明";
const link = linkElement
? linkElement.getAttribute("href").getValue()
: "リンク不明";

articleTitleAndLinkList.push({title, link});
} catch (e) {
Logger.log(e.message);
}
})

return articleTitleAndLinkList;
}

function getRssArticleTitleAndLink(entries) {
const articleTitleAndLinkList = [];

entries.forEach((entry) => {
try {
// RSS形式のタイトルとリンク
const titleElement = entry.getChild("title");
const linkElement = entry.getChild("link");

const title = titleElement ? titleElement.getText() : "タイトル不明";
const link = linkElement ? linkElement.getText() : "リンク不明";

articleTitleAndLinkList.push({title, link});
} catch (e) {
Logger.log(e.message);
}
})

return articleTitleAndLinkList;
}
function sendTargetArticleToGmail() {
try {
// 送信したい記事を指定する
const feedUrls = [
getFeedUrl("xxx", "xxx"),
getFeedUrl("xxx", "xxx"),
getFeedUrl("xxx", "xxx"),
];

// 送信したい記事の件数
const articleCount = 10;

// 記事を送信したいメールアドレスを指定
const recipient = "xxx@gmail.com";

// 件名
const subject = "各フィードの記事";

// メール本文
let emailBody = "";

feedUrls.forEach((feedUrl) => {
emailBody += `# フィードURL: ${feedUrl}\n\n`;

// XMLのルート要素を取得
const response = UrlFetchApp.fetch(feedUrl);
const xml = XmlService.parse(response.getContentText());
const root = xml.getRootElement();

// 記事の取得
const articles = getArticle(root, articleCount);

// 記事がない場合
if (articles.length === 0) {
emailBody += "記事が見つかりませんでした。\n\n";
return;
}

// メール本文に記事のタイトルとリンクを追記
const articleTitleAndLink = articles.map(item => `## ${item.title}\n${item.link}`).join("\n\n");
emailBody += articleTitleAndLink;

emailBody += "\n\n--------------------------------------------\n\n";
});

GmailApp.sendEmail(recipient, subject, emailBody);
Logger.log("メールが正常に送信されました。");
} catch (e) {
Logger.log(e.message);
}
}

function getFeedUrl(site, name) {
const feeds = feedList[site];
if (!feeds) {
throw new Error(`サイト'${site}'が存在しません。`);
}
const feed = feeds.find(feed => feed.name === name);
if (!feed) {
throw new Error(`'${name}'のフィードが、サイト'${site}'に存在しません。`);
}
return feed.url;
}

function getArticle(xmlRoot, articleCount) {
if (xmlRoot.getName() === "feed") {
// Atom形式の場合
const entries = xmlRoot.getChildren("entry", xmlRoot.getNamespace()).slice(0, articleCount);

return getAtomArticleTitleAndLink(xmlRoot, entries);
} else if (xmlRoot.getName() === "rss") {
// RSS形式の場合
const entries = xmlRoot.getChild("channel").getChildren("item").slice(0, articleCount);;

return getRssArticleTitleAndLink(entries);
}

return [];
}

function getAtomArticleTitleAndLink(xmlRoot, entries) {
const articleTitleAndLinkList = [];

entries.forEach((entry) => {
try {
// Atom形式のタイトルとリンク
const titleElement = entry.getChild("title", xmlRoot.getNamespace());
const linkElement = entry.getChild("link", xmlRoot.getNamespace());

const title = titleElement ? titleElement.getText() : "タイトル不明";
const link = linkElement
? linkElement.getAttribute("href").getValue()
: "リンク不明";

articleTitleAndLinkList.push({title, link});
} catch (e) {
Logger.log(e.message);
}
})

return articleTitleAndLinkList;
}

function getRssArticleTitleAndLink(entries) {
const articleTitleAndLinkList = [];

entries.forEach((entry) => {
try {
// RSS形式のタイトルとリンク
const titleElement = entry.getChild("title");
const linkElement = entry.getChild("link");

const title = titleElement ? titleElement.getText() : "タイトル不明";
const link = linkElement ? linkElement.getText() : "リンク不明";

articleTitleAndLinkList.push({title, link});
} catch (e) {
Logger.log(e.message);
}
})

return articleTitleAndLinkList;
}

copy

ソースコードの内容について概要を説明します。(興味のある方だけ読んでください)

・まずは、送信したい記事と件数、メールアドレス、件名を指定
・次に、フィードURLからXMLのルート要素を取得
・そのルート要素をもとに、フィードがAtom形式かRSS形式かを判別して、各形式の取得方法で、各記事のタイトルとURLを取得
・取得した記事のタイトルとURLをメール本文に書き込み、指定したメールアドレスにメールを送信

では、自分が読みたい記事を自分宛に送信できるように、ソースコードをちょっと修正します。簡単な修正です。

送信したい記事と件数、メールアドレス、件名の指定

mainファイルの3~17行目が修正箇所です。

送信したい記事の指定方法は、以下のように、feedListファイルに登録したフィードのサイト名とフィード名を入力します。

// 送信したい記事を指定する
const feedUrls = [
// この中に以下の形式で読みたい記事を指定する
getFeedUrl("サイト名", "フィード名"),
getFeedUrl("サイト名", "フィード名"),
getFeedUrl("サイト名", "フィード名"),
];// 送信したい記事を指定する
const feedUrls = [
// この中に以下の形式で読みたい記事を指定する
getFeedUrl("サイト名", "フィード名"),
getFeedUrl("サイト名", "フィード名"),
getFeedUrl("サイト名", "フィード名"),
];

copy

サイト名とフィード名は、feedListファイルのこの部分です。

const feedList = {
サイト名: [
{name: "フィード名", url: "フィードURL"},
],
サイト名: [
{name: "フィード名", url: "フィードURL"},
{name: "フィード名", url: "フィードURL"},
],
};const feedList = {
サイト名: [
{name: "フィード名", url: "フィードURL"},
],
サイト名: [
{name: "フィード名", url: "フィードURL"},
{name: "フィード名", url: "フィードURL"},
],
};

copy

例えば、feedListファイルの内容が以下の場合は、

const feedList = {
exampleSite1: [
{name: "latest", url: "https://example.com/feed1"},
],
exampleSite2: [
{name: "latest", url: "https://example.com/feed2"},
{name: "it", url: "https://example.com/it/feed2"},
],
};
const feedList = {
exampleSite1: [
{name: "latest", url: "https://example.com/feed1"},
],
exampleSite2: [
{name: "latest", url: "https://example.com/feed2"},
{name: "it", url: "https://example.com/it/feed2"},
],
};

copy

以下のように指定すればokです。

// 送信したい記事を指定する
const feedUrls = [
getFeedUrl("exampleSite1", "latest"),
getFeedUrl("exampleSite2", "latest"),
getFeedUrl("exampleSite2", "it"),
];// 送信したい記事を指定する
const feedUrls = [
getFeedUrl("exampleSite1", "latest"),
getFeedUrl("exampleSite2", "latest"),
getFeedUrl("exampleSite2", "it"),
];

copy

記事の送信件数については、以下の数字を修正します。以下だと、指定した記事が10件ずつ送信されるようになります。

// 送信したい記事の件数
const articleCount = 10;// 送信したい記事の件数
const articleCount = 10;

copy

宛先は、以下のxxxにご自身のメールアドレスを入力します。
件名は、以下の「各フィードの記事」の部分を、受け取りたい件名で修正します。

// 記事を送信したいメールアドレスを指定
const recipient = "xxx@gmail.com";

// 件名
const subject = "各フィードの記事";// 記事を送信したいメールアドレスを指定
const recipient = "xxx@gmail.com";

// 件名
const subject = "各フィードの記事";

copy

これで、読みたい記事を自分のメールアドレスに送信できるようになりました。
ファイルの編集は終わりなので、ファイルをMacユーザーは「command + s」、Windowsユーザーは「ctrl + s」で保存します。

記事をGmailに送信できるかテストしましょう。
以下の「実行」ボタンを押下します。(実行ボタンの右横がsendTargetArticleToGmail になっていることを確認してください)

すると、以下のポップアップが表示されるので、「権限を確認」ボタンを押下して、ご自身のGoogleアカウントでログインします。

以下の警告が出るので、「詳細」を押下して、「記事をGmailに送信するスクリプトに移動」を押下して、スクリプトのGoogleアカウントへのアクセス(Gmailのアクセス)リクエストが問題がないことを確認して、許可します。

実行ログが表示されるので、「メールが正常に送信されました。」と表示されたら、実行成功です。
あなたのメールアドレスに読みたい記事が送信されています。

4. 毎日指定の時間に記事が送信されるようにする

最後の手順です。

毎日指定の時間にスクリプトを自動実行して、記事がGmailに送信されるように設定します。

サイドメニューの「トリガー」ボタンを押下します。

以下の画面右下の「+ トリガーを追加」ボタンを押下します。

以下のように設定して保存すると、毎日7:00-8:00の時間帯に記事が送信されるようになります。ご自身にあわせて内容を入力してください。

以下のように表示されたら設定完了です。

さいごに

毎朝記事を読む習慣を作りたいと思い、「仕事やプライベートで毎日のように使うGmailに記事が送信されたら、読む習慣ができそう」ということで今回のスクリプトを作成しました!

このスクリプトが、少しでもあなたの役に立ってくれたら嬉しく思います!

さいごに、dotDでは一緒に働く仲間を募集しています。
興味のある方はぜひご連絡いただけると嬉しいです!!!

株式会社dotDからお誘い
この話題に共感したら、メンバーと話してみませんか?
株式会社dotDでは一緒に働く仲間を募集しています

同じタグの記事

今週のランキング

kirita kanaさんにいいねを伝えよう
kirita kanaさんや会社があなたに興味を持つかも