2
3
Fork
You've already forked notibot-mastodon-bot-rss
2
Bot posting RSS feeds to Mastodon account
  • JavaScript 99.6%
  • EJS 0.4%
Froilán Irizarry Rivera 5cb465bd4b Add pino.js ( #16 )
Wepa! Aqui tienes un unsolicited PR.
Le añadí [pino.js](https://getpino.io/) como un logger para tener structured logs con el bot. Esto sustituye el uso de _console.log_ y nos deja añadir contexto (key=value pairs of data) a un log line.
En este PR le añadí dos transports al logger, uno que utiliza [pino-pretty](https://getpino.io/#/docs/pretty) y otro que escribe JSON log lines a un archivo.
El transport de [pino-pretty](https://getpino.io/#/docs/pretty) se tiene que activar con la variable de ambiente de _LOG_PRETTY=true_. Si la variable no existe o esta con algún otro valor a _true_, los logs no se despliegan al stdout pero si al log file.
<details>
<summary>See pino-pretty log format</summary>
```
[2025年11月08日 20:48:45.628 -0500] INFO: Loading feeds from config to database
 service: "mastodon-bot-rss"
 feedCount: 1
[2025年11月08日 20:48:45.629 -0500] INFO: Finished loading feeds from config to database
 service: "mastodon-bot-rss"
[2025年11月08日 20:48:45.629 -0500] INFO: Bot cycle started
 service: "mastodon-bot-rss"
[2025年11月08日 20:48:45.629 -0500] INFO: RSS feed: Froi.dev - schedule_check
 service: "mastodon-bot-rss"
 feedName: "Froi.dev"
 feedAction: "schedule_check"
 lastExecutionDate: "2025年11月09日T01:43:17.000Z"
 nextExecutionDate: "2025年11月09日T01:43:27.000Z"
[2025年11月08日 20:48:45.629 -0500] INFO: RSS feed: Froi.dev - fetching
 service: "mastodon-bot-rss"
 feedName: "Froi.dev"
 feedAction: "fetching"
 feedUrl: "https://froi.dev/posts/index.xml"
[2025年11月08日 20:48:45.629 -0500] INFO: Network request started
 service: "mastodon-bot-rss"
 networkEvent: "request_start"
 requestUrl: "https://froi.dev/posts/index.xml"
 requestMethod: "GET"
 feedName: "Froi.dev"
[2025年11月08日 20:48:45.764 -0500] INFO: Network request succeeded
 service: "mastodon-bot-rss"
 networkEvent: "request_success"
 requestUrl: "https://froi.dev/posts/index.xml"
 requestMethod: "GET"
 durationMs: 135
 feedName: "Froi.dev"
 itemsFound: 14
[2025年11月08日 20:48:45.767 -0500] INFO: Bot cycle completed
 service: "mastodon-bot-rss"
 botCycleDurationTimeSecs: 0.138
 feedsProcessed: 1
```
It has colors!
![CleanShot 2025年11月08日 at 21.27.01@2x](/attachments/6e6343bc-17c0-4024-88c5-de6a9e074e24)
</details>
El transport para el log file have "append" de JSON log lines. Este archivo se puede "parsear" muy bien con __jq__.
```sh
cat ./logs/bot.log | jq .
```
<details>
<summary>Ejemplos del log file</summary>
El contenido del log file se ve asi
```json
{"level":30,"time":"2025年11月09日T02:06:52.570Z","service":"mastodon-bot-rss","feedCount":1,"msg":"Loading feeds from config to database"}
{"level":30,"time":"2025年11月09日T02:06:52.571Z","service":"mastodon-bot-rss","msg":"Finished loading feeds from config to database"}
{"level":30,"time":"2025年11月09日T02:06:52.571Z","service":"mastodon-bot-rss","msg":"Bot cycle started"}
{"level":30,"time":"2025年11月09日T02:06:52.571Z","service":"mastodon-bot-rss","feedName":"Froi.dev","feedAction":"schedule_check","lastExecutionDate":"2025年11月09日T01:48:45.000Z","nextExecutionDate":"2025年11月09日T01:48:55.000Z","msg":"RSS feed: Froi.dev - schedule_check"}
{"level":30,"time":"2025年11月09日T02:06:52.571Z","service":"mastodon-bot-rss","feedName":"Froi.dev","feedAction":"fetching","feedUrl":"https://froi.dev/posts/index.xml","msg":"RSS feed: Froi.dev - fetching"}
{"level":30,"time":"2025年11月09日T02:06:52.571Z","service":"mastodon-bot-rss","networkEvent":"request_start","requestUrl":"https://froi.dev/posts/index.xml","requestMethod":"GET","feedName":"Froi.dev","msg":"Network request started"}
{"level":30,"time":"2025年11月09日T02:06:52.714Z","service":"mastodon-bot-rss","networkEvent":"request_success","requestUrl":"https://froi.dev/posts/index.xml","requestMethod":"GET","durationMs":143,"feedName":"Froi.dev","itemsFound":14,"msg":"Network request succeeded"}
{"level":30,"time":"2025年11月09日T02:06:52.716Z","service":"mastodon-bot-rss","botCycleDurationTimeSecs":0.145,"feedsProcessed":1,"msg":"Bot cycle completed"}
{"level":30,"time":"2025年11月09日T02:07:02.718Z","service":"mastodon-bot-rss","msg":"Bot cycle started"}
{"level":30,"time":"2025年11月09日T02:07:02.720Z","service":"mastodon-bot-rss","feedName":"Froi.dev","feedAction":"schedule_check","lastExecutionDate":"2025年11月09日T02:06:52.000Z","nextExecutionDate":"2025年11月09日T02:07:02.000Z","msg":"RSS feed: Froi.dev - schedule_check"}
{"level":30,"time":"2025年11月09日T02:07:02.720Z","service":"mastodon-bot-rss","feedName":"Froi.dev","feedAction":"skipped","reason":"not_due_yet","nextExecutionDate":"2025年11月09日T02:07:02.000Z","msg":"RSS feed: Froi.dev - skipped"}
{"level":30,"time":"2025年11月09日T02:07:02.721Z","service":"mastodon-bot-rss","botCycleDurationTimeSecs":0.003,"feedsProcessed":1,"msg":"Bot cycle completed"}
```
Filtrarlo con _jq_ es bien facil
```sh
❯ cat .logs/bot.log | jq ".time,.msg"
"2025年11月09日T02:06:52.570Z"
"Loading feeds from config to database"
"2025年11月09日T02:06:52.571Z"
"Finished loading feeds from config to database"
"2025年11月09日T02:06:52.571Z"
"Bot cycle started"
"2025年11月09日T02:06:52.571Z"
"RSS feed: Froi.dev - schedule_check"
"2025年11月09日T02:06:52.571Z"
"RSS feed: Froi.dev - fetching"
"2025年11月09日T02:06:52.571Z"
"Network request started"
"2025年11月09日T02:06:52.714Z"
"Network request succeeded"
"2025年11月09日T02:06:52.716Z"
"Bot cycle completed"
"2025年11月09日T02:07:02.718Z"
"Bot cycle started"
"2025年11月09日T02:07:02.720Z"
"RSS feed: Froi.dev - schedule_check"
"2025年11月09日T02:07:02.720Z"
"RSS feed: Froi.dev - skipped"
"2025年11月09日T02:07:02.721Z"
"Bot cycle completed"
```
</details>
Reviewed-on: #16
Co-authored-by: Froilán Irizarry Rivera <code@froi.dev>
Co-committed-by: Froilán Irizarry Rivera <code@froi.dev>
2025年11月14日 03:29:19 +01:00
db Add db-migrate ( #13 ) 2025年11月01日 03:47:02 +01:00
imposters add mastodon API to the imposter list 2025年10月12日 13:23:42 -04:00
.db-migraterc Add db-migrate ( #13 ) 2025年11月01日 03:47:02 +01:00
.gitignore fix RSS feeds still showing after removal from the config.json file 2025年10月04日 10:06:55 -04:00
code_of_conduct.md add code of conduct 2025年03月16日 22:42:50 -04:00
config.sample.json Add language configuration to feeds ( #8 ) 2025年10月26日 02:14:06 +01:00
LICENSE initial commit 2025年03月16日 12:57:26 -04:00
logger.js Add pino.js ( #16 ) 2025年11月14日 03:29:19 +01:00
mastodon-bot-rss.js Add pino.js ( #16 ) 2025年11月14日 03:29:19 +01:00
mastodon-bot-rss.service initial commit 2025年03月16日 12:57:26 -04:00
msBotDBOps.js Add pino.js ( #16 ) 2025年11月14日 03:29:19 +01:00
package-lock.json Add pino.js ( #16 ) 2025年11月14日 03:29:19 +01:00
package.json Add pino.js ( #16 ) 2025年11月14日 03:29:19 +01:00
README-systemd.md initial commit 2025年03月16日 12:57:26 -04:00
README.md Add pino.js ( #16 ) 2025年11月14日 03:29:19 +01:00

notibot-mastodon-bot-rss

Adds posts from one or more RSS feeds to Mastodon. Based on the mastodon-bot-rss repo by t3rr0rz0ne

Packages

Features

  • Use more than one RSS feed at the same time
  • Switch post visibility
  • Add language settings to posts on Mastodon
  • Add content warnings or spoiler tags according to news titles in the RSS feeds

Pre requirements

  • A Mastodon account with access token, client key and client secret. In Mastodon, go to your account > Preferences > Development > New Application > Choose Read and Write. Then these values are given to you over there.
  • Your Mastodon instance endpoint. Usually it is https://[instance]/api/v1
  • Node.js 18 installed.

Installing notibot-mastodon-bot-rss

  1. Clone the repository

    git clone https://codeberg.org/jdm2/notibot-mastodon-bot-rss
    
  2. Install the project's dependencies

    npm install
    
  3. Make a copy of the config.sample.json file and name it config.json

    cp config.sample.json config.json
    

Once you've created a config.json file you'll be ready to configure the bot.

Configuring config.json

Note

You can use the config.sample.json file as an example for the Mastodon configuration and to see multiple sample feeds configured.

Mastodon settings

notibotpr is a Mastodon application. As such, you need to register a new application from the Mastodon settings or use an existing one.

To create a new application go to Preferences > Development and click on the New Application button. Fill out the required fields and select the scopes you want to use. At a minimum you will need to select write:statuses.

Once you create the app you will be able to get the needed authentication values to configure your bot:

  • clientKey
  • clientSecret
  • accessToken

To finish configuring the Mastodon setting you will need to fill out:

  • apiURL: Usually it is https://[instance]/api/v1. For example, mastodon.social would be https://mastodon.social/api/v1
  • jobInterval: total milliseconds between main loop runs again. Default value is 1800000
  • visibility: the visibility of the post; public, unlisted, followers or private. Default value is unlisted to avoid clogging the local timelines.

Configuring feeds

You can use more than one feed in this program. Each feeds has the following values inside:

  • name: the name of the feed. Example: NewsTestFeed
  • feedURL: where you can find the url of the feed. Example: https://newstest.sample/feed
  • hashtags: the hashtags following the news post from the RSS feed. Great idea to use different hashtags for different RSS feeds so people can filter them if the feed is "too noisy". Example: #NewsTestFeed
  • timeToCheck: The bot will check this RSS feed once every n seconds, where n will be the value inside timeToCheck value.
  • language: The language to use for all Mastodon status updates for a feed.

Configuring content warnings

  • name: the name shown inside the spoiler or content warning
  • keywords: trigger words to make the post hide behind a content warning

Running bot

Note

You can see an example of this bot running here: NotiBot Puerto Rico

Now, you can execute the script with:

npm run start

Running the app you will Immediately see some output logs around database migrations, this is expected. notibot-mastodon-bot-rss uses a small sqlite3 database to store the RSS feed history. This database schema should be created the first time this bot is started. No additional input needed on your part.

Click here to see DB migrations example
> npm start
> mastodon-bot-rss@1.0 prestart
> db-migrate up
received data: CREATE TABLE IF NOT EXISTS RSSFeeds (
 id INTEGER PRIMARY KEY,
 name TEXT NOT NULL,
 feedUrl TEXT not null,
 interval INTEGER not null,
 hashtags TEXT not null,
 language TEXT not null
);
[INFO] Processed migration 20251030021010-create-rssfeeds
received data: CREATE TABLE IF NOT EXISTS RSSFeedHistory (
 id INTEGER PRIMARY KEY,
 name TEXT NOT NULL,
 lastTimeChecked int not null
)
[INFO] Processed migration 20251030021252-create-rssfeed-history
received data: CREATE TABLE IF NOT EXISTS RSSFeedCache (
 id INTEGER PRIMARY KEY,
 name TEXT NOT NULL,
 rssItemTitle text not null,
 rssItemURL text not null,
 postedDate int not null
)
[INFO] Processed migration 20251030021440-create-rssfeed-cache
[INFO] Done

If the database has already been created and no new database changes need to be applied you will see a No migrations to run message. The application will then run normally.

Click here to see a no migration needed example
❯ npm start
> mastodon-bot-rss@1.0 prestart
> db-migrate up
[INFO] No migrations to run
[INFO] Done
> mastodon-bot-rss@1.0 start
> node mastodon-bot-rss.js

If you want log entries to show up in the console you need to set the LOG_PRETTY environment variable to true.

LOG_PRETTY=true npm start
Click to see pretty logs
LOG_PRETTY=true npm start
> mastodon-bot-rss@1.0 prestart
> db-migrate up
[INFO] No migrations to run
[INFO] Done
> mastodon-bot-rss@1.0 start
> node mastodon-bot-rss.js
[2025年11月08日 20:04:30.871 -0500] INFO: Loading feeds from config to database
 service: "mastodon-bot-rss"
 feedCount: 1
[2025年11月08日 20:04:30.872 -0500] INFO: Finished loading feeds from config to database
 service: "mastodon-bot-rss"
[2025年11月08日 20:04:30.872 -0500] INFO: Bot cycle started
 service: "mastodon-bot-rss"
[2025年11月08日 20:04:30.873 -0500] INFO: RSS feed: Froi.dev - schedule_check
 service: "mastodon-bot-rss"
 feedName: "Froi.dev"
 feedAction: "schedule_check"
 lastExecutionDate: "2025年11月09日T00:59:39.000Z"
 nextExecutionDate: "2025年11月09日T00:59:49.000Z"
[2025年11月08日 20:04:30.873 -0500] INFO: RSS feed: Froi.dev - fetching
 service: "mastodon-bot-rss"
 feedName: "Froi.dev"
 feedAction: "fetching"
 feedUrl: "https://froi.dev/posts/index.xml"
[2025年11月08日 20:04:30.873 -0500] INFO: Network request started
 service: "mastodon-bot-rss"
 networkEvent: "request_start"
 requestUrl: "https://froi.dev/posts/index.xml"
 requestMethod: "GET"
 feedName: "Froi.dev"
[2025年11月08日 20:04:31.046 -0500] INFO: Network request succeeded
 service: "mastodon-bot-rss"
 networkEvent: "request_success"
 requestUrl: "https://froi.dev/posts/index.xml"
 requestMethod: "GET"
 durationMs: 173
 feedName: "Froi.dev"
 itemsFound: 14
[2025年11月08日 20:04:31.049 -0500] INFO: Bot cycle completed
 service: "mastodon-bot-rss"
 feedsProcessed: 1

Special thanks

  • Special thanks to Froilán Irizarry Rivera for their contributions to this project
  • Special thanks to t3rr0rz0ne for starting this project years ago and inspiring us to give back to the community
  • Special thanks to all the users contributing ideas to this project on Mastodon.

Dev environment

To start working on this project, you can fake out both Mastodon API as well as a sample RSS feed using mountebank. To get started, install mountebank globally. Follow the instructions on that repo.

Stubs and imposter configurations were placed inside the imposter/ folder.

You can use them by executing:

mb --configfile ./imposters/imposters.ejs --allowInjection`

License

GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007

Mastodon-bot-rss Copyright (C) 2020 by T3rr0rZ0n3

notibot-mastodon-bot-rss Copyright (C) 2025 by jdm2