Skip to content

About

Self-hosted Discord notifiers for your favourite book sites, monitors your reading lists and alerts on new books and chapters.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Book Notifier

License Last Commit Build Language Image Tag Image Size

A single self-hosted notifier that monitors your reading lists across multiple fiction platforms and sends Discord notifications when new books or chapters are released.

Supported platforms:

  • GoodReads — new books and series entries from authors on your shelf
  • ScribbleHub — new chapters on stories in your reading list
  • Literotica — new stories from your favourite authors
  • RoyalRoad — new books and chapters entries from your favourites
  • Ao3 — new books and chapters entries from your favourites

One container, one .env file. Run one notifier or all five concurrently.


📦 Requirements

  • Docker installed
  • Accounts on whichever platforms you want to monitor
  • A Discord Webhook URL

Important

AO3, ScribbleHub and RoyalRoad require a FlareSolver instance (FLARESOLVER_URL). The container refuses to start if one of them is enabled without it. GoodReads uses it as a fallback when GoodReads' bot protection blocks a request.


Launch Options

Launch Parameter Description
--runonce No matter the retry duration, the program will exit after all notifiers run.
--ignore-post Incase you just want the data files, you can ignore posting and it will run normally. Skipped notifications are logged as would send ....
--selftest Runs the built-in helper checks and exits.

🚀 Setup

1. Pull the Image

docker pull ghcr.io/riisdev/book-notifier:latest

2. Create a .env File

Set NOTIFIER to a comma-separated list of the platforms you want to monitor. Only include variables for the platforms you are running.

# Which notifiers to run (comma-separated, any combination)
NOTIFIER=goodreads,scribblehub,literotica,royalroad,ao3

# FlareSolver for required services
FLARESOLVER_URL=your_flaresolver_url

# Shared
WEBHOOK=https://your.webhook.url/here

# ---- GoodReads ----
GOODREADS_RECHECK_MS=300000
GOODREADS_USER_ID=your_goodreads_user_id
GOODREADS_SHELF_TAG=your_shelf_name

# ---- ScribbleHub ----
SCRIBBLEHUB_RECHECK_MS=60000
SCRIBBLEHUB_USERID=your_scribblehub_userid

# ---- AO3 ----
AO3_RECHECK_MS=6000000
AO3_USERNAME=your_username
AO3_PSEUDO=your_pseudo #optional, will fallback to username

# ---- Literotica ----
LITEROTICA_RECHECK_MS=600000
LITEROTICA_USERNAME=your_literotica_username
LITEROTICA_PASSWORD=your_literotica_password

# ---- Royal Road ----
ROYALROAD_RECHECK_MS=300000
ROYALROAD_USERID=your_royalroad_user_id

3. Run with Docker

docker run -d \
  --name book-notifier \
  --env-file .env \
  -v $(pwd)/data:/app/data \
  ghcr.io/riisdev/book-notifier:latest

Or build from source:

git clone https://github.com/riisdev/BookNotifier.git
cd BookNotifier
docker build -t book-notifier ./BookNotifier
docker run -d \
  --name book-notifier \
  --env-file .env \
  -v $(pwd)/data:/app/data \
  book-notifier

🛠 Configuration

Shared

Variable Description
NOTIFIER Comma-separated list of notifiers to run. Valid values: goodreads, scribblehub, literotica, royalroad, ao3
WEBHOOK Discord webhook URL where notifications will be sent
FLARESOLVER_URL URL of a FlareSolverr instance (e.g. http://flaresolverr:8191/v1). Required for scribblehub, royalroad and ao3; fallback for goodreads

GoodReads

Variable Description
GOODREADS_RECHECK_MS Interval in milliseconds between checks
GOODREADS_USER_ID Your GoodReads user ID — found in your profile URL
GOODREADS_SHELF_TAG Shelf to watch (e.g. to-read, currently-reading)

ScribbleHub

Variable Description
SCRIBBLEHUB_RECHECK_MS Interval in milliseconds between checks
SCRIBBLEHUB_USERID Your ScribbleHub userid

Ao3

Variable Description
AO3_RECHECK_MS Interval in milliseconds between checks
AO3_USERNAME Your Ao3 username
AO3_PSEUDO Your Ao3 pseudoname

Literotica

Variable Description
LITEROTICA_RECHECK_MS Interval in milliseconds between checks
LITEROTICA_USERNAME Your Literotica username
LITEROTICA_PASSWORD Your Literotica password

Royal Road

Variable Description
ROYALROAD_RECHECK_MS Interval in milliseconds between checks
ROYALROAD_USERID Your Royal Road user ID — found in your profile URL

📝 How It Works

Each enabled notifier runs concurrently in its own loop on its own interval. They do not block or affect each other.

GoodReads fetches your shelf, collects all distinct authors, retrieves their full book lists (/author/list, all pages, not just the top 10), and checks for new standalone books and series entries against the local cache. Books are matched by their GoodReads ID, so retitled books aren't re-announced. Book pages are loaded a few at a time; if GoodReads' bot protection blocks a request it automatically retries through FlareSolver. The first run after upgrading to full author lists saves the extra books silently (marker file data/goodreads.fulllist).

ScribbleHub fetches your PUBLIC reading list and each story's full table of contents, then compares the latest chapter against the cache. FlareSolver is REQUIRED.

Literotica logs in each cycle and keeps a full catalog of your favourite authors. A full crawl only happens on the first run and when you favourite a new author (announced once, back catalog saved silently). Otherwise it reads the followed-authors activity feed (last 20 entries) and refreshes only the authors with something new; if the whole feed is unseen it refreshes everyone.

RoyalRoad fetches your favourites through FlareSolver, looks through all the books and checks for new chapters, will also look if new books are added. Books and chapters are matched by ID, so renamed fictions aren't re-announced.

Ao3 fetches your public bookmarks (Max first 3 pages), looks through all the books and checks for new chapters, will also look if new books are detected.

Restarts & schedule: the time each notifier last finished is saved in data/schedule.json. After a restart a notifier waits out the remainder of its interval instead of running immediately, so restarting the container (e.g. nightly) won't reset a 12-hour check. A single run that hangs for over an hour is abandoned and retried next cycle.

Logs: written to console and to data/log-yyyy-MM-dd.txt; one file per day, the newest 3 are kept.


🔔 Notifications

Notifier Triggers
GoodReads New book by a tracked author; new series entry
ScribbleHub New story on reading list; new chapter released
Literotica New story from a favourite author
RoyalRoad New story on reading list; new chapter released
Ao3 New story on reading list; new chapter released

🧹 Stopping and Cleaning Up

docker stop book-notifier
docker rm book-notifier

To reset the cache (the next run is a silent first run, so nothing is announced):

rm -rf ./data

Note

You don't need to wipe data/ when upgrading. Keep it mounted as a volume: it holds the caches, schedule.json and the GoodReads backfill marker.


🤖 AI Usage

Parts of this project were developed with AI assistance. Below is a summary of where it was used:

  • README generation — documentation written with AI assistance based on source code
  • Summary Tags — In instances of C# Summary tags, they're generated by Visual Studio built in agent
  • HTML parsing logic — CSS & HTML DOM selector and regex patterns for scraping responses
  • Webhook payload formatting — Discord embed structure and message formatting
  • Models Advice — Internal records and class data types were often helped formed using AI (Cleanup / Standardizing)
  • GitHub Actions workflow — CI/CD pipeline for building and publishing Docker images

📄 License

MIT License

About

Self-hosted Discord notifiers for your favourite book sites, monitors your reading lists and alerts on new books and chapters.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

Contributors

Languages