Create an RSS feed for your DEV.to Reading List
Tags: tutorial, node, rss
Published: 2023-07-02 10:30:34

[DEV.to](https://dev.to) is a great place to learn and share knowledge about software development. With an active community of developers and technical writers, this website provides a vast range of resources for beginners as well as experienced programmers. One thing that DEV.to offers is a "read later" feature called Reading List. This feature allows users to save any article that they find interesting but do not have time to read right away. Articles that have been added to the Reading List can be accessed at any time, making it more convenient for users to catch up on their reading at a later time.

In this tutorial, we are going to create an RSS feed for the articles that you saved to your DEV.to Reading List. In order to do this, we will generate a token to gain access to the [DEV.to API](https://developers.forem.com/api/v1). Then, we will write a Node.js script that loads the article data, creates the RSS feed and saves it to a designated file.

**Note**: All of the code can be found at [this repository on GitHub](https://github.com/stefankolb/RSSFeedDEVtoReadingList), including setup instructions and how to run the script to create your personal RSS feed.


## Create access token

To access the DEV.to API and load the articles, we need to create an access token. For this, we open the [extensions section](https://dev.to/settings/extensions) in our DEV.to profile and scroll to "DEV Community API Keys" at the bottom of the page. We enter a project name in the description field, e.g. "Reading List RSS Feed", and click the "Generate API Key" button. Done.

**Warning**: API keys are like passwords, which means, keep them safe and do not share them with others.


## Create RSS feed

We use JavaScript to write a Node.js file named `index.js` to load the articles, create an RSS feed and write it to a file. To make things easier, we use the [Feed](https://www.npmjs.com/package/feed) package to create the RSS feed.

**Note**:  The code below has been tested on Node.js version 19.8.1.

```js
import fs from 'fs';
import { Feed } from 'feed';
```

Before we start, we need to configure a couple of things so that our feed can be properly created:

```js
// Your DEV.to API key
const API_KEY = '';

// The title of the RSS feed, e.g. 'My DEV.to Reading List'
const FEED_TITLE = 'My DEV.to Reading List';

// The description of the RSS feed, e.g. 'A feed for all articles that I saved to my DEV.to Reading List'
const FEED_DESCRIPTION = 'A feed for all articles that I saved to my DEV.to Reading List';

// The RSS feed's ID, e.g. 'https://dev.to/<YOUR_DEV_TO_USERNAME>/
const FEED_ID = ''

// The RSS feed's author information, i.e. your name, email and website
const FEED_AUTHOR = {
  name: '',
  email: '',
  link: ''
};

// The RSS feed's format. Possible values: 'rss2', 'atom1' or 'json1'
const FEED_TYPE = 'rss2';

// The file to which the RSS feed should be written to, e.g. 'feed.xml' or 'feed.json'
const FEED_OUTPUT_FILE = {
  rss2: 'feed.xml',
  atom1: 'atom.xml',
  json1: 'feed.json'
};

// DO NOT EDIT THESE VALUES!

const API_URL_READING_LIST = 'https://dev.to/api/readinglist';

const FEED_FAVICON = 'https://dev-to.s3.us-east-2.amazonaws.com/favicon.ico';
const FEED_OUTPUT_PATH = 'build';
```

Now that we have all the information we need, there are three things we need to do to create our RSS feed:

1. Load articles from DEV.to
2. Create RSS feed in memory
3. Write RSS feed to file

### Load articles from DEV.to

First, we load the articles from our Reading List. For this, we use the native `fetch` method and parse the JSON response:

```js
const fetchReadingList = () => fetch(
  API_URL_READING_LIST, {
    headers: {
      accept: 'application/vnd.forem.api-v1+json',
      'api-key': API_KEY,
      'content-type': 'application/json',
    }
  }
).then(
  response => {
    if (response.ok) {
      return response.json();
    }

    throw new Error(`Not able to download reading list articles: ${response.statusText} [${response.status}]`);
  }
);
```

### Create RSS feed in memory

Second, with the data received from the API, we create a new `Feed` object in memory that holds all the information about our RSS feed:

```js
const createRSSFeed = data => {
  const feed = new Feed({
    title: FEED_TITLE,
    description: FEED_DESCRIPTION,
    id: FEED_ID,
    link: FEED_ID,
    favicon: FEED_FAVICON,
    author: FEED_AUTHOR
  });

  data.forEach(item => {
    const feedItem = {
      title: item.article.title,
      id: item.article.url,
      link: item.article.url,
      description: item.article.description,
      date: new Date(item.article.published_at)
    };

    if (item.article.cover_image) {
      feedItem.image = item.article.cover_image;
    } else if (item.article.social_image) {
      feedItem.image = item.article.social_image;
    }

    feed.addItem(feedItem);
  });

  return feed[FEED_TYPE]();
};
```

### Write RSS feed to file

Finally, we are going to write our `Feed` object to disk. We can choose between three feed types: RSS 2.0, Atom 1.0 and JSON Feed 1.0. The feed type can be set in the configuration (see above):

```js
const writeRSSFeed = feed => {
  const outputPath = `${FEED_OUTPUT_PATH}/${FEED_OUTPUT_FILE[FEED_TYPE]}`;
  try {
    if (fs.existsSync(FEED_OUTPUT_PATH) === false) {
      fs.mkdirSync(FEED_OUTPUT_PATH);
    }
    fs.writeFileSync(outputPath, feed);
  } catch (e) {
    throw new Error(`Was not able to write feed to "${outputPath}":\r\n${e}`);
  };
}
```

### Execute script

Now that we have all our functionality in place, we can call these functions to actually create the RSS feed's file:

```js
fetchReadingList().then(
  data => {
    if (!data || data.length === 0) {
      console.warn('No articles available -> Exiting');
      process.exit(0);
    }

    const rssFeed = createRSSFeed(data);
    writeRSSFeed(rssFeed);
  }
).catch(
  e => {
    console.error(e);
    process.exit(1);
  }
);
```

We save the Node.js file and call it from the terminal:

```shell
$> node index.js
```

And that's it, our RSS feed is ready and the feed's file is available in the `build` folder. All we need to do now is copy the generated file to a location that is accessible via the web and add the URL to this file to our favorite RSS feed reader.

We can automate running the Node.js script and copying the output to a folder by using a small Bash script (which is also available in the [GitHub repo for this article](https://github.com/stefankolb/RSSFeedDEVtoReadingList)):

```bash
#!/usr/bin/env bash

node index.js
cp ./build/* <PATH_TO_WEB_SERVER_FOLDER>/
```


## Bonus: Automatic updates

Wouldn't it be great if the feed would automatically update, let's say every 60 minutes? Sure, no problem. We add an entry into the configuration for Cron, Anacron, Cronie - or whatever you are using for scheduling tasks - and execute the `run.sh` Bash script.

```shell
# Example for Cron; script runs every 60 minutes
0 * * * * /PATH/TO/run.sh
```


## Final words

RSS feeds are a great way to keep people up-to-date with new content and updates. I hope that with this tutorial, you are able to create your own feed for your DEV.to Reading List. But not only that: You could use the approach in this tutorial to access any API and create an RSS feed from the data it provides.

Did you use this tutorial to generate your own RSS feed? Great, let me know in the [comments](https://dev.to/stefankolb/create-an-rss-feed-for-your-devto-reading-list-19k2#comments). If you have any issues or want to suggest an improvement, head over to the [GitHub repository's issue tracker](https://github.com/stefankolb/RSSFeedDEVtoReadingList/issues).