Search code examples
htmlgoogle-apps-scriptgoogle-drive-apirss

Google Drive and Translation Script


I am using this script, but each time it fetches the RSS it creates a new HTML file.

I would like it to just rewrite the previous file instead of creating a new one and fetch only once a day. After that once i share the file is not validated in RSS Validator if there is any way to fix this changing mime or any other option. Any help with this would be appreciated.

function doGet() {

  var fromLang = "en";    
  var toLang   = "es";    
  var rssFeed  = "http://xkcd.com/rss.xml";  

  var feed = parseRSS(rssFeed, fromLang, toLang);   
  DriveApp.createFile("rssTest", feed, MimeType.HTML);
  return ContentService.createTextOutput(feed)
           .setMimeType(ContentService.MimeType.RSS);    
}

function parseRSS(feed, fromLang, toLang) {

  var id = Utilities.base64Encode(feed + fromLang + toLang);

  // Cache the RSS feeds for an hour
  var cache = CacheService.getPublicCache();
  var rss   = cache.get(id);

  if (rss != null) {
    return rss;
  }

  var item, date, title, link, desc, guid; 

  var txt = UrlFetchApp.fetch(feed).getContentText();
  var doc = Xml.parse(txt, false);  

  title = doc.getElement().getElement("channel").getElement("title").getText();

  // The RSS Feed is translated using Google Translate
  rss = '<rss version="2.0">';
  rss += "<channel><title>";
  rss += LanguageApp.translate(title, fromLang, toLang);
  rss += " (" + title + ")</title>";

  var items = doc.getElement().getElement("channel").getElements("item");   

  // Parsing single items in the RSS Feed
  for (var i in items) {

    try {

      item  = items[i];

      title = item.getElement("title").getText();
      link  = item.getElement("link").getText();
      date  = item.getElement("pubDate").getText();
      desc  = item.getElement("description").getText();

      guid  = Utilities.base64Encode(link + fromLang + toLang);

      title = LanguageApp.translate(title, fromLang, toLang);
      desc  = LanguageApp.translate(desc,  fromLang, toLang, 
                                       {contentType: "html"});

      rss += "<item>";
      rss += "  <title>"   + title + "</title>";
      rss += "  <link>"    + link  + "</link>";
      rss += "  <pubDate>" + date  + "</pubDate>";
      rss += "  <guid>"    + guid  + "</guid>";
      rss += "  <description><![CDATA[" + desc + "]]></description>";
      rss += "</item>";

    } catch (e) {
      Logger.log(e);
    }
  }

  rss += "</channel></rss>";

  cache.put(id, rss, 3600);
  return rss;

}

Solution

  • You can change the content of a file by just calling the method setContent(). And if you know the ID you can get the file through DriveApp.getFileById().

    So this part of your code:

    DriveApp.createFile("rssTest", feed, MimeType.HTML);
    

    Can change to this:

    var file = DriveApp.getFileById("<your file ID>");
    file.setContent(feed);
    

    I've tried to validate this RSS in the validator you sent.

    There are some things that I needed to do in order to validate.

    1. In the guid tag there is an error, basically, you need to add isPermaLink="false".

    2. After that remember that the channel elements needs description element and link check it at w3schools.

    Doing that made it a valid RSS for me. So you need to change your parseRSS to make it work.

    function parseRSS(feed, fromLang, toLang) {
    
      var id = Utilities.base64Encode(feed + fromLang + toLang);
    
      // Cache the RSS feeds for an hour
      var cache = CacheService.getPublicCache();
      var rss   = cache.get(id);
    
      if (rss != null) {
        return rss;
      }
    
      var item, date, title, link, desc, guid; 
    
      var txt = UrlFetchApp.fetch(feed).getContentText();
      var doc = Xml.parse(txt, false);  
    
      title = doc.getElement().getElement("channel").getElement("title").getText();
    
      // The RSS Feed is translated using Google Translate
      rss = '<rss version="2.0">';
      rss += "<channel><title>";
      rss += LanguageApp.translate(title, fromLang, toLang);
      rss += " (" + title + ")</title>";
      rss += "<description>Description you need to fill</description>"; // Add this line
      rss += "<link>Link you need to fill</link>"; // Add this line 
    
      var items = doc.getElement().getElement("channel").getElements("item");   
    
      // Parsing single items in the RSS Feed
      for (var i in items) {
    
        try {
    
          item  = items[i];
    
          title = item.getElement("title").getText();
          link  = item.getElement("link").getText();
          date  = item.getElement("pubDate").getText();
          desc  = item.getElement("description").getText();
    
          guid  = Utilities.base64Encode(link + fromLang + toLang);
    
          title = LanguageApp.translate(title, fromLang, toLang);
          desc  = LanguageApp.translate(desc,  fromLang, toLang, 
                                           {contentType: "html"});
    
          rss += "<item>";
          rss += "  <title>"   + title + "</title>";
          rss += "  <link>"    + link  + "</link>";
          rss += "  <pubDate>" + date  + "</pubDate>";
          rss += "  <guid isPermaLink="false">"    + guid  + "</guid>"; // Modified this line
          rss += "  <description><![CDATA[" + desc + "]]></description>";
          rss += "</item>";
    
        } catch (e) {
          Logger.log(e);
        }
      }
    
      rss += "</channel></rss>";
    
      cache.put(id, rss, 3600);
      return rss;
    
    }