How to Convert Atom feeds to RSS feeds

Submitted by Danny on Mon, 02/17/2025 - 20:53

YouTube can provide atom feeds for a channel's content, but not RSS feeds. My web site software can ingest RSS feeds but not Atom feeds. Here's how I converted the Atom feeds to RSS feeds.

First, you'll need a web server with Node.js installed.

Start a new Node.js project and add the plug-ins for fs, feed, xml2js, and https.

 $> mkdir atom2rss
 $> cd atom2rss
 $> npm init
 $> npm install fs
 $> npm install feed
 $> npm install xml2js
 $> npm install https

Next, create a file index.js in the atom2rss directory, and use this code:

console.log('------------------------------------------------');
console.log('atom2rss: converting youtube atom feed to rss');
 
var Feed = require('feed').Feed;
var parseString = require('xml2js').parseString;
var fs = require('fs');
var https =  require("https")
 
var atomUrl = 'https://www.youtube.com/feeds/videos.xml?channel_id=YOUR_CHANNEL_ID';
var rssFile = '/srv/users/nodejs/apps/youtube/public/youtube.xml'; // OR A DIRECTORY AND FILENAME OF YOUR CHOICE
 
var req = https.get(atomUrl, function(res) {
  // save the data
  var atomXml = '';
  res.on('data', function(chunk) {
    atomXml += chunk;
  });
 
  res.on('end', function() {
    // parse xml
 
    // create a feed object
    let rssFeed = new Feed({
      title: "YOUR FEED NAME",
      description: "YOUR FEED DESCRIPTION",
      id: "YOUR CHANNEL ID",
      link: "YOUR URL",
      language: "en", // optional, used only in RSS 2.0, possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
      image: "",
      copyright: "All rights reserved "+new Date().getFullYear()+", YOUR ORGANIZATION NAME",
      //updated: new Date()// optional, default = today
      generator: "YOUR NAME", // optional, default = 'Feed for Node.js'
      feedLinks: {
        json: "",
        atom: "https://www.youtube.com/feeds/videos.xml?channel_id=YOUR-CHANNEL-ID",
        rss: "YOUR CONTENT URL"
      },
      author: {
        name: "YOUR NAME",
        email: "YOUR EMAIL",
        link: "YOUR WEBSITE URL"
      }
    });
 
    parseString(atomXml, function (err, atomFeed) {
      atomFeed['feed']['entry'].forEach(function(entry) {
          //console.log(JSON.stringify(entry, null, 2));
          rssFeed.addItem({
              title: entry["title"],
              link: entry["link"][0]['$']['href'],
              id: entry['id'][0],
              content: entry['media:group'][0]['media:description'][0],
              description: entry['media:group'][0]['media:description'][0],
              date: new Date(entry['published'][0]),
              image: entry['media:group'][0]['media:thumbnail'][0]['$']['url'],
 
          });
      });
 
    });
 
 
    //console.log(rssFeed.rss2())
    fs.writeFile(rssFile, rssFeed.rss2(), err => {
        if (err) {
            console.error(err);
        } else {
            // file written successfully
            console.log('file updated successfully');
        }
    });
 
  });
 
  // or you can pipe the data to a parser
  //res.pipe(dest);
});
 
req.on('error', function(err) {
  // debug error
  console.log(err);
});

You'll need to fill in the paramaters as approriate for your RSS feed.

Finally, create a cron job to run this script as often as needed. For me, that's once an hour. But because youtube updates the atom feeds on the hour, I set my script to run 5 minutes past the hour, so that everything is copacetic.

5 * * * * node /srv/users/nodejs/apps/youtube/atom2rss/index.js >> /srv/users/nodejs/cron.log 2>&1

The above line can be added to your crontab file by using the command `crontab -e` and you can configure it to send output to your desired directory and filename, for me that was /srv/users/nodejs/cron.log.

Happy coding!