{"id":13571071,"url":"https://github.com/synzen/feedtracker","last_synced_at":"2025-04-25T02:30:47.568Z","repository":{"id":40753535,"uuid":"146520992","full_name":"synzen/feedtracker","owner":"synzen","description":"Track RSS feeds and get pre-beautified articles","archived":false,"fork":false,"pushed_at":"2022-12-07T23:53:06.000Z","size":368,"stargazers_count":13,"open_issues_count":11,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-13T05:03:33.078Z","etag":null,"topics":["atom","feeds","rss"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/synzen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-29T00:09:09.000Z","updated_at":"2023-03-21T20:11:05.000Z","dependencies_parsed_at":"2023-01-25T00:31:27.353Z","dependency_job_id":null,"html_url":"https://github.com/synzen/feedtracker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synzen%2Ffeedtracker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synzen%2Ffeedtracker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synzen%2Ffeedtracker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synzen%2Ffeedtracker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/synzen","download_url":"https://codeload.github.com/synzen/feedtracker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250741884,"owners_count":21479687,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atom","feeds","rss"],"created_at":"2024-08-01T14:00:58.150Z","updated_at":"2025-04-25T02:30:47.343Z","avatar_url":"https://github.com/synzen.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# feedtracker\n[![Build Status](https://travis-ci.org/synzen/feedtracker.svg?branch=master)](https://travis-ci.org/synzen/feedtracker) [![dependencies Status](https://david-dm.org/synzen/feedtracker/status.svg)](https://david-dm.org/synzen/feedtracker)\n\n[![NPM](https://nodei.co/npm/feedtracker.png)](https://nodei.co/npm/feedtracker/)\n\nTrack RSS feeds and receive new articles automatically.\n\n## Quick Start\n```js\nconst Tracker = require('feedtracker')\n\nconst fetcher = new Tracker.Fetcher(10000) // Time in ms to check for new articles\nfetcher.addFeed(url)\n.then(() =\u003e /* success */)\n.catch(err =\u003e /* handle error */)\n\n\nfetcher.on('article', (article, feedLink) =\u003e {\n    // The article object is an Article object with processed values (that cleans up HTML/etc.). To get the raw article object, use article.raw.\n})\n\nfetcher.on('err', (err, feedLink) =\u003e {\n    // Link connection errors during fetch cycles\n})\n```\n## Basic Functions\n#### Adding Multiple Feeds\n```js\nconst Tracker = require('feedtracker')\nconst links = [url1, url2, url3]\n\nconst fetcher = new Tracker.Fetcher(10000) // Time in ms\nfetcher.addFeeds(links)\n.then(() =\u003e /* success */)\n.catch(err =\u003e /* handle error */)\n\n// Then add fetcher listeners\n\n```\n\n#### Fetch feeds on different intervals\n```js\nconst Tracker = require('feedtracker')\n\nconst fetcher = new Tracker.Fetcher(10000) // Time in ms\nfetcher.addSchedule(new Tracker.Schedule(20000, 'schedule name'))\nfetcher.addFeed(url)\n.then(() =\u003e fetcher.addFeed(url2, 'schedule name') // Add this feed to the new schedule. Omit the name for the default one)\n.then(() =\u003e /* success */)\n\nfetcher.on('article', handler)\nfetcher.on('err', errHandler)\n\n```\n## API Table of Contents\n\n* [Main Classes](#main-classes)\n* [Utility Classes](#utility-classes)\n* [Fetcher](#fetcher)\n   * [Fetcher#addFeed(url[, scheduleName])](#fetcheraddfeedurl-schedulename)\n   * [Fetcher#addFeeds(urls[, scheduleName])](#fetcheraddfeedsurls-schedulename)\n   * [Fetcher#addSchedule(schedule)](#fetcheraddscheduleschedule)\n   * [Fetcher#on(event[, args...])](#fetcheronevent-args)\n* [Schedule](#schedule)\n   * [Schedule#addFeed(feed)](#scheduleaddfeedfeed)\n   * [Schedule#addFeeds(feed)](#scheduleaddfeedsfeeds)\n   * [Schedule#on(event[, args...]](#scheduleonevent-args)\n* [Feed](#feed)\n   * [Feed#getArticles](#feedgetarticles)\n   * [Feed#toJSON](#feedtojson)\n\n***\n\n### Main Classes\n\n#### new Tracker.Fetcher([interval])\n   * *Number* `interval` - Frequency of how long to request feeds for updates for an automatically created Schedule\n\nCreates a fetcher. If no interval is specified, a default schedule is automatically created - otherwise schedules must be manually added with Fetcher#addSchedule to add feeds.\n\n#### new Tracker.Schedule(interval, name[, options])\n   * *Number* `interval` - Frequency of how long to request feeds for updates. Non-zero positive integer\n   * *String* `name` - The name of the schedule. Purely for identification purposes\n   * *Object* `options` - Object of options to configure the schedule\n      * *String* `processingMethod` - Defines how feeds are fetched for efficiency. Either `\"concurrent\"` or `\"parallel-isolated\"`. Defaults to `\"concurrent\"`\n      * *Number* `batchSize` - Number of feeds to request in one batch of concurrent requests. Applies to both `processingMethods` above. Defaults to `300`\n\nConcurrent processing method is when feeds are fetched in the same process of fetcher (that the schedule belongs to). Parallel-isolated is when feeds are fetched in a forked child process. The latter method is much faster and more efficient for heavy use (several thousand feeds).\n\n***\n\n### Utility Classes\n\n#### Article\n\nA class made to auto-beautify the contents given by the feedparser by cleaning up the HTML and extracting useful items such as images and anchors. Accessed as the second argument to the article listener for `Tracker.Fetcher#on(\"article\", article)` and `Tracker.Schedule#on(\"article\", article)`.\n\nProperties:\n   * *Object* `raw` - The original object created by the feedparser\n   * *String* `title` - Title of the article\n   * *String* `author` - Author of the article\n   * *String* `description` - Description of the article\n   * *String* `summary` - Summary of the article\n   * *String* `link` - Link of the article\n   * *Array\\\u003cString\\\u003e* `tags` - Categories/tags of the article\n   * *Array\\\u003cString\\\u003e* `imageLinks` - Image links found in the raw object values in all object depths\n   * *Array\\\u003cString\\\u003e* `titleImages` - Image links found in the title\n   * *Array\\\u003cString\\\u003e* `descriptionImages` - Image links found in the description\n   * *Array\\\u003cString\\\u003e* `summaryImages` - Image links found in the summary\n   * *Array\\\u003cString\\\u003e* `titleAnchors` - Anchor links found in the title\n   * *Array\\\u003cString\\\u003e* `descriptionAnchors` - Anchor links found in the description\n   * *Array\\\u003cString\\\u003e* `summaryAnchors` - Anchor links found in the summary\n\n***\n\n### Fetcher\n\n#### Fetcher#addFeed(url[, scheduleName])\n   * *String* `url` - URL of the feed\n   * *String* `scheduleName` - Name of the schedule to add the feed to. Defaults to the default schedule if it exists\n\nReturns a promise since it requests the feed to check if it is a valid (returns a valid parsable 200-code response). Do not use this to add multiple links - use the pluralized method (addFeeds) instead for faster concurrent requests. Resolves with a Tracker.Feed object.\n\n#### Fetcher#addFeeds(urls[, scheduleName])\n   * *Array\\\u003cString\\\u003e* `urls` - URLs of feeds\n   * *String* `scheduleName` - Name of the schedule to add the feed to. Defaults to the default schedule if it exists\n\nReturns a promise. Concurrently requests the urls for validation. Resolves with an array of Tracker.Feed objects. Rejects all the URLs if a single one fails.\n\n#### Fetcher#addSchedule(schedule)\n   * *Tracker.Schedule* `schedule` - The Schedule to add\n\nThrows an error if the schedule name already exists.\n\n#### Fetcher#on(event[, args...])\n   * *String* `event` - There are two events to listen to\n      * *String* `article` - Emitted whenever there is a new article found durng one of the feed check cycles\n      * *String* `err` - Emitted whenever a link has an error (a feedparser error or connection error)\n   * *String* `args...` - For the article event, there are two args - the article and the feed link. For the err event, there are two args - the error and the feed link, respectively - however the link is not available when the schedule's processingMethod is `parallel-isolated`\n\n***\n\n### Schedule\n\n#### Schedule#addFeed(feed)\n   * *String* `url` - URL of the feed\n\nReturns a promise. Resolves with a Tracker.Feed object.\n\n#### Schedule#addFeeds(feeds)\n   * *Array\\\u003cString\\\u003e* `urls` - URLs of feeds\n\nReturns a promise. Resolves with an array of Tracker.Feed objects. Rejects all the URLs if a single one fails.\n\n#### Schedule#on(event[, args...])\n   * *String* `event` - There are two events to listen to\n      * *String* `article` - Emitted whenever there is a new article found durng one of the feed check cycles\n      * *String* `err` - Emitted whenever a link has an error (a feedparser error or connection error)\n   * *String* `args...` - For the article event, there are two args - the article and the feed link. For the err event, there are two args - the error and the feed link, respectively - however the link is not available when the schedule's processingMethod is `parallel-isolated`\n\n***\n\n### Feed\n\n#### Feed#getArticles()\n\nReturns a promise, and resolves with an array of the current articles by feedparsing the requested contents.\n\n#### Feed#toJSON()\n\nReturns a JSON representation of the the Feed instance.\n\n***\n\n## Testing\n\n```\nnpm run mocha-test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynzen%2Ffeedtracker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynzen%2Ffeedtracker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynzen%2Ffeedtracker/lists"}