Last active
October 30, 2025 11:17
-
-
Save CennoxX/7a4b18542ac24618330904373b337cee to your computer and use it in GitHub Desktop.
A Google Apps Script to monitor RSS and Atom feeds, automatically detect new entries, and send email notifications with the new post.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function monitor(feedName, url, author, filter = null) { | |
| console.log(feedName); | |
| let startTime = Date.now(); | |
| let scriptProperties = PropertiesService.getScriptProperties(); | |
| let lastUpdate = scriptProperties.getProperty(`lastUpdate${feedName}`); | |
| let errorCount = parseInt(scriptProperties.getProperty(`errorCount${feedName}`) || "0"); | |
| let root; | |
| try { | |
| let res = UrlFetchApp.fetch(url); | |
| root = XmlService.parse(res.getContentText().replace(/content:encoded/g, "content").replace(/&#(\w.+?);/g, (_, p) => {return String.fromCharCode(p)})).getRootElement(); | |
| scriptProperties.deleteProperty(`errorCount${feedName}`); | |
| } catch (e) { | |
| errorCount++; | |
| scriptProperties.setProperty(`errorCount${feedName}`, errorCount.toString()); | |
| console.error(`${feedName} failed`, errorCount, lastUpdate); | |
| if (errorCount < 24) | |
| return; | |
| throw e; | |
| } | |
| let ns = root.getNamespace(); | |
| let entries = root.getChild("channel", ns)?.getChildren("item", ns) || root.getChildren("entry", ns); | |
| entries.reverse().forEach(entry => { | |
| let published = entry.getChild("updated", ns)?.getText() || entry.getChild("pubDate", ns)?.getText(); | |
| if (new Date(published) <= new Date(lastUpdate)) | |
| return; | |
| scriptProperties.setProperty(`lastUpdate${feedName}`, published); | |
| let title = entry.getChild("title", ns).getText().replace(/&#(\w.+?);/g, (_, p) => {return String.fromCharCode(p)}); | |
| let content = entry.getChild("content", ns)?.getText() || entry.getChild("description", ns)?.getText() || entry.getChild("summary", ns)?.getText() || ""; | |
| let link = entry.getChild("link", ns).getAttribute("href")?.getValue() || entry.getChild("link", ns).getText().replace(/\?.*/, ""); | |
| let body = `<b>${title}</b> von ${author}<br /><a href="${link}">${link}</a><br /><div style="width:700px">${content}</div>`; | |
| if (!filter || link.match(filter)) | |
| MailApp.sendEmail({to: Session.getActiveUser().getEmail(), subject: title, htmlBody: body, name: author}); | |
| }); | |
| let duration = (Date.now() - startTime) / 1000; | |
| console.log(`${duration.toFixed(3)} s`); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment