Недавно я озаботился вопросом, как бы получать уведомления о появлении новостей в RSS-фиде. Можно, конечно, постоянно пастись в RSS-клиенте, но мне хотелось именно уведомлений. Почтовые вполне подойдут, потому что со смартфоном я не расстаюсь.
Пока думал как это сделать, нашёл очень интересный сервис ifttt.com (If This Then That). Но в конечном итоге, у меня родилось другое решение: скрипт на Google Apps Script. Никогда раньше мне не приходило в голову использовать этот сервис Гугла. Почему бы не попробовать?
Правда, появился ещё один вопрос: как Google Apps используют другие? Просто любопытство, вдруг я что-то ещё интересное упустил. По этому поводу я опубликовал небольшой пост на Хабрахабре. Там был маленький пример скрипта, разбирающего RSS-фид, и вопрос кто-что придумал с Google Apps. Странно, но идеями меня не завалили. Был только один ответ. А через некоторое время, была ещё статья о применении Google Apps. Применение не бытовое, конечно, но возьму на вооружение. И всё, других идей пока не подкинули.
С тех пор я дополнил скрипт. Теперь он понимает два протокола (RSS версии 2.0 и Atom) и работает с несколькими фидами, а не с одним.
Как это сделано... На Google Диске создаём таблицу (spreadsheet) следующего вида:
Фидов может быть, естественно, сколько угодно. Скрипт будет работать со второго ряда вниз до первой пустой ячейки в колонке “A”. Колонка “Время последней новости” служебная, её можно скрыть. И её не нужно заполнять при добавлении нового фида.
Далее в созданную таблицу (spreadsheet) добавляем сценарий (меню “Инструменты” => “Редактор скриптов...”):
function checkFeeds() { const mailAddress = "mail@mail.me"; const feedColumn = 1; const mailSubjectColumn = 2; const lastPublicationDateColumn = 3 var row = 2; var sheet = SpreadsheetApp.getActiveSheet(); while (true) { var currentRow = row++; var feed = sheet.getRange(currentRow, feedColumn).getValue(); if (feed == "") { break; } var mailSubject = sheet.getRange(currentRow, mailSubjectColumn).getValue(); var mailBody = ""; var lastPublicationDateCell = sheet.getRange(currentRow, lastPublicationDateColumn); var feedContent = UrlFetchApp.fetch(feed).getContentText(); var doc = Xml.parse(feedContent, false); var root = doc.getElement(); if (root == null) { break; } var rootName = root.getName().getLocalName(); if (rootName == "rss") { var rssVersion = root.getAttribute("version"); if (rssVersion == null) { break; } if (rssVersion.getValue() == "2.0") { mailBody = parseRssFeed(root, mailSubject, lastPublicationDateCell); } } else if (rootName == "feed") { mailBody = parseAtomFeed(root, mailSubject, lastPublicationDateCell); } if (mailBody != "") { GmailApp.sendEmail(mailAddress, mailSubject, mailBody); } } } function parseRssFeed(root, mailSubject, lastPublicationDateCell) { var maxPubDateText = lastPublicationDateCell.getValue(); var maxPubDate = "2000-01-01T00:00:00Z"; if (maxPubDateText != "") { maxPubDate = maxPubDateText; } var channel = root.getElement("channel"); var mailBody = ""; var items = channel.getElements("item") var curMaxPubDate = maxPubDate; for (var i in items) { var dateText = items[i].getElement("pubDate").getText(); var pubDate = Utilities.formatDate(new Date(dateText), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'"); if (pubDate > maxPubDate) { if (pubDate > curMaxPubDate) { curMaxPubDate = pubDate } mailBody += "\nЗаголовок: " + items[i].getElement("title").getText(); mailBody += "\nСсылка: " + items[i].getElement("link").getText(); mailBody += "\nДата публикации: " + pubDate; mailBody += "\n"; } } lastPublicationDateCell.setValue(curMaxPubDate); return mailBody; } function parseAtomFeed(root, mailSubject, lastPublicationDateCell) { var maxPubDateText = lastPublicationDateCell.getValue(); var maxPubDate = "2000-01-01T00:00:00Z"; if (maxPubDateText != "") { maxPubDate = maxPubDateText; } var mailBody = ""; var entries = root.getElements("entry") var curMaxPubDate = maxPubDate; for (var i in entries) { var pubDate = entries[i].getElement("updated").getText(); if (pubDate > maxPubDate) { if (pubDate > curMaxPubDate) { curMaxPubDate = pubDate } mailBody += "\nЗаголовок: " + entries[i].getElement("title").getText(); mailBody += "\nСсылка: " + entries[i].getElement("link").getAttribute("href").getValue(); mailBody += "\nДата публикации: " + pubDate; mailBody += "\n"; } } lastPublicationDateCell.setValue(curMaxPubDate); return mailBody; }
Теперь надо задать период автоматического запуска скрипта. Например, каждые 10 минут. Для этого в редакторе сценариев выбираем пункт меню “Ресурсы” => “Триггеры текущего проекта...” и добавляем “динамический минутный таймер”.
Всё-таки программировать, это прекрасно. Такой самодельный вариант оповещения мне нравится гораздо больше, чем ifttt. Ведь я его сам сделал! Ну и Google, по правде...
А есть похожий скрипт, только чтобы письмо приходило если в фиде присутствует заданная фраза или слово?
ОтветитьУдалитьСделал всё по инструкции. вроде заработало, но на почту пока ничего не приходило. Только я вот не совсем понял как скрипт обратится к моей таблице с atom фидом...
ОтветитьУдалитьАрсений, я мог неправильно понять вопрос... Скрипт последовательно проходит по строкам нашей таблицы с фидами. Берёт фид (некий URL) и отправляет его в просторы Интернета. В ответ получает какой-то XML. Далее скрипт идентифицирует этот XML. Если это XML со структурой RSS, вызывается функция parseRssFeed, если это Atom - то функция parseAtomFeed. Каждая из этих функций умеет парсить (разбирать) свой формат фида. Ну а по результатам разбора функции формируют текст для письма мне (вам).
УдалитьСпасибо, очень удобно.
ОтветитьУдалить