Giter VIP home page Giter VIP logo

echo's Introduction

Echo - RSS Cross Poster

Echo screenshot

What is it?

Echo is a node script to post new items from an RSS feed to various services including Micro.blog and Mastodon.

Why "Echo"?

It does RSS feeds, so Feeder. Feeder are a band with an album called Echo Park. Echo is a good name because the album link AND the meaning of the word echo. So there.

Requirements

  • Node 19 (it might work with earlier versions but that's what I used)
  • A server/computer/potato to run it on

Installation

  1. Clone this repository
  2. Run npm install to install the node module
  3. Run cp config.example.js config.js to create a new config file
  4. Setup your RSS feeds and services (see configuration for options)
  5. Run node index.js init to setup - this will store the latest ID so only new posts going forward will be posted. If you want to post some items from a feed, add the ID of the latest item you don't want to post in data/nameofsite.txt.
  6. Setup a cron to run node index.js regularly

๐Ÿšจ Warning: If you don't run node index.js init first, the script will post all the posts in the RSS feeds. You probably don't want this.

You can also run node index.js dry. This will log which posts will be created, but will not post anything.

Echo keeps track of the last item posted so on subsequent runs it will only post new posts.

You can also run Echo with GitHub actions. See Lewis' blog post for more info

Configuration

There are two parts to configure: sites and services. sites is the RSS feeds you want to cross-post and services is the services you want to cross-post to.

Go to the Echo website to use the config generator and paste the generated config into config.js or see below for setting it up manually.

Sites

config.sites is an array of RSS feeds you wish to cross-post. A site has five attribute:

  • name (required): this can be anything (this is used in a filename so probably don't use special characters).
  • feed (required): the feed URL you want to post to Micro.blog (e.g. https://mycoolsite.com/feed).
  • categories (optional - only for Micro.blog): An array of categories to assign to you posts for the site (e.g. ["Cat One", "Cat Two"]).
  • services: The services you want to cross-post to. See services.
  • transform: this is an object with two functions (see below for preset transforms):
    • getId: This tells Echo which attribute to use for the ID of each feed item. Most feeds use id or guid but if it's something different you can set that here.
    • format: This is how you format the title, body, and date of the post. This returns an object with content, date, and an optional title.
    • filter (optional): Use this if you need to filter out specific items in a feed. For example, Letterboxd includes items for lists being updated which I don't want to be posted.

Example Site Configuration

{
    name: "example.com",
    feed: "http://example.com/feed",
    categories: ["my category"],
    services: [SERVICES.MICROBLOG, SERVICES.WEBHOOK]
    transform: {
        getId: (data) => {
            return data.id
        },
        format: (data) => {
            return {
                content: data.content,
                date: data.isoDate,
                title: data.title, // optional
            }
        },
        filter: (items) => {
            return items.filter(item => {
                return !item.link.includes('/list/')
            })
        }
    }
}

Preset Transforms

Echo has a few presets you can use instead of having to write the getId and format functions for every site. These can be seen in presets.js. For example, to use the Letterboxd or status.lol preset you can do the following:

{
    name: "letterboxd.com",
    feed: "http://letterboxd.com/exampleuser/rss",
    categories: ["movies"],
    transform: presets.letterboxd,
},
{
    name: "status.lol",
    feed: "http://exampleuser.status.lol/feed",
    categories: ["status"],
    transform: presets.statuslol,
}

You can define the body of your post in format to make your posts look exactly how you want. For ease, Echo includes helpers.js with some helper libraries.

  • To convert HTML to markdown, use helpers.toMarkdown(text)
  • To use Cheerio use helpers.cheerioLoad(text)
  • To generate a UUID use helpers.generateUuid()
  • Get the length of the post based on how Mastodon calculates this (links are always 23 characters, for example) helpers.getMastodonLength(string)
  • Get all links as an array helpers.getLinks(string)
  • Encode and decode HTML entities with helpers.decode(string) and helpers.encode(string)
format: (data) => {
    const formatted = presets.default.format(data)

    // get the first link with Cheerio
    // and append it to the content
    const $ = helpers.cheerioLoad(formatted.content)
    const firstLink = $('a:first').attr('href')
    formatted.content += ` ${firstLink}`

    // format to markdown
    formatted.content = helpers.toMarkdown(formatted.content)
    return formatted
}

Services

Each service requires a different set of values depending on how the API works.

Micro.blog

Key Value Notes
siteUrl The Micro.blog site you're posting to e.g. https://coolsite.micro.blog
apiKey A Micro.blog API key Get an API key from https://micro.blog/account/apps

Mastodon

Key Value Notes
instance Your Mastodon instance e.g. https://social.lol
accessToken Go to Preferences > Development > New Application on your Mastodon instance and grab the access token
visibility (optional, default public) public unlisted private direct
sensitive (optional, default false) false true

Webhooks

The webhook service will send a POST request with the result of transform.format (as set in your site config) to a given url.

Key Value Notes
url The URL to post to

Omnivore

The Omnivore service will save a URL to your Omnivore account.

Key Value Notes
apiKey Your Omnivore API key

GitHub

Create a new file on a GitHub repository.

Key Value Notes
token Your GitHub token
repo The repository to commit to e.g. rknightuk/echo
branch The branch to commit to
committer An object with name and email values e.g. { name: 'Robb', email: '[email protected] }

For posting to Github your format function must return content and filePath where filePath is the path to where the file will be in the Github repository, for example src/posts/movies/2024-02-09.md. It can optionally return a commit message, which will fallback to New post if none is set. Example format function for GitHub:

format: (data) => {
    return {
        content: data.title,
        date: new Date(data.isoDate).toISOString(),
        filePath: `src/posts/movies/${new Date().getFullYear()}/${new Date().toISOString().split('T').md`,
        commit: `Add ${data.title}`,
    }
}

LinkAce

Key Value Notes
domain The LinkAce domain where you have it installed e.g.https://links.example.com
apiKey A LinkAce API key

content returns from transform.format should be a link. Categories on the site will be converted to tags. Any tags included from format will be merged with categories.

{
    name: 'mycoollinkfeed',
    feed: 'https://example.com/linkfeed.xml',
    categories: ['ATag'],
    transform: {
        getId: presets.default.getId,
        format: (data) => {
            return {
                content: data.external_url,
                date: data.date_published,
                tags: data._custom.tags,
            }
        }
    },
    services: [SERVICES.LINKACE],
},

Webmentions

Key Value Notes
no config is required for webmentions

content returns from transform.format should be a link.

echo's People

Contributors

calebhearth avatar nhoizey avatar rknightuk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

echo's Issues

"null" in feed data

Hey Robb,

Loving this tool, it's great! I'm having a small issue where the feed I'm using (https://kevquirk.com/social-feed) is producing nothing but 'null' for the ID in the data folder, so it's dumping my entire feed every time the cron runs. This is 100% my fault, but I'm not sure what's happening here. What does echo use as the ID for posts? I can make sure it's added to the feed then.

For now, I've worked around the problem by simply limiting the feed to the single latest entry, so this is really low priority.

Thanks,

Kev

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.