Automatically monitors paid and free RSS feeds for your novels, tracks arc history, side stories/extras published, and fires three types of Discord announcements via webhook:
- New Novel Launch Alerts looks out for the first free chapter of a new series (Ch. 1, Chapter 1, Ep. 1, Episode 1, 1.1, Prologue)
- New Arc Alerts (lockedโadvance content)
- Side Stories/Extra Alerts (lockedโadvance content, fires one time for each novel)
- Completion Announcements when the final chapter appears (paid) and full series unlocks (free)
Notifications are sent via the Discord bot API (using DISCORD_BOT_TOKEN + DISCORD_CHANNEL_ID).
The old setup used a single DISCORD_WEBHOOK URL โ that webhook flow is legacy and only applies to earlier versions.
| Name | Value |
|---|---|
DISCORD_WEBHOOK |
Your Discord webhook URL (Legacy, not required for bot use) |
GH_PAT |
Personal Access Token for history push |
๐ 1. Add the Discord Webhook URL to Secrets (Legacy โ See update below for new Repository Secrets)
- Go to Settings โ Secrets and variables โ Actions.
- Click New repository secret.
- Set Name to
DISCORD_WEBHOOK. - Set Value to your Discord webhook URL.
- Click Add secret.
To allow the script to update the novel history JSON files and push changes back to GitHub, you need to generate and store a Personal Access Token (PAT) from the source repository that triggers this script.
- Go to GitHub Personal Access Tokens.
- Click "Generate new token (classic)".
- Select Expiration (no expiration).
- Under Scopes, check:
- โ
repo(Full control of private repositories) - โ
workflow(Required for GitHub Actions)
- โ
- Click Generate token and copy it.
- Go to Settings โ Secrets and variables โ Actions.
- Click New repository secret.
- Set Name to
GH_PAT. - Set Value to the Personal Access Token copied earlier.
- Click Add secret.
๐จ Important:
- The PAT must be set in the repository where GitHub Actions runs the script (i.e., the source repo that triggers Discord updates).
- If this repo is forked, the PAT must be added to the forked repositoryโs secrets, not just the original.
- Go to Settings โ Actions โ General.
- Under Workflow permissions, select:
- โ Allow all actions and reusable workflows
- โ Read and write permissions
- Click Save.
If youโd rather always pull the latest novel_mappings.py from the rss-feed repo, add this to your CIโs install step:
pip install --upgrade git+https://github.com/Cannibal-Turtle/rss-feed.git@main
Your rss-feed repo needs a pyproject.toml at its root, for example:
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "cannibal-turtle-rss-feed"
version = "0.1.0"
description = "Mapping data for feeds"
authors = [ { name = "Cannibal Turtle" } ]
readme = "README.md"
requires-python = ">=3.7"
license = { text = "MIT" }
classifiers = [
"Programming Language :: Python :: 3",
]
[project.urls]
Homepage = "https://github.com/Cannibal-Turtle/rss-feed"
[tool.setuptools]
# explicitly list each standalone .py you want installed
py-modules = [
"novel_mappings",
]With that in place, you do not need a local config.jsonโboth new_arc_checker.py and completed_novel_checker.py will import HOSTING_SITE_DATA directly.
Only if you choose not to install the mapping package.
- Add or update config.json at the repo root:
{
"novels": [
{
"novel_title": "Your Novel Title",
"role_mention": "<@&DISCORD_ROLE_ID>",
"chapter_count": "Total number of chapters",
"last_chapter": "Last chapter for novel",
"start_date": "31/8/2024",
"free_feed": "https://your-free-feed-url.xml",
"paid_feed": "https://your-paid-feed-url.xml",
"novel_link": "https://your-novel-link/",
"host": "Your Hosting Site",
"custom_emoji": ":EmojiID:",
"discord_role_url": "https://discord.com/channels/YOUR_ROLE_URL",
"history_file": "your_novel_history.json"
}
]
}- Script changes in both
new_arc_checker.pyandcompleted_novel_checker.py:
- Remove the mapping-package import:
- from novel_mappings import HOSTING_SITE_DATA - Re-add your CONFIG_PATH constant:
+ CONFIG_PATH = "config.json" - Bring back
load_config()helper (which readsconfig.json). - Swap the bottom if
__name__ == "__main__":block to loop over:config = load_config() state = load_state() for novel in config["novels"]: process_novel(novel, state) save_state(state)```
Each novel must have a unique
history_fileto store its arc history.
All scripts read from your generated RSS/Atom-style feeds (free_feed, paid_feed).
Each <item> in the feed is expected to look like this:
<item>
<title>Quick Transmigration: The Villain Is Too Pampered and Alluring</title>
<volume/>
<chaptername>Chapter 377</chaptername>
<nameextend>***My Fiancรฉ Is Definitely Not a Little Pitiful Person 039***</nameextend>
<link>https://dragonholic.com/novel/.../chapter-377/</link>
<description><![CDATA[ ... HTML summary ... ]]></description>
<category>SFW</category>
<translator>Cannibal Turtle</translator>
<featuredImage url="https://dragonholic.com/wp-content/uploads/2024/08/177838.jpg"/>
<pubDate>Sat, 25 Oct 2025 12:00:00 +0000</pubDate>
<host>Dragonholic</host>
<hostLogo url="https://dragonholic.com/wp-content/uploads/2025/01/Web-Logo-White.png"/>
<guid isPermaLink="false">10850</guid>
</item>The scripts rely on a few specific fields:
| Tag | Purpose |
|---|---|
<chaptername> |
Contains the chapter label (e.g. โChapterย 5โ, โExtraย 8โ) โ used to detect paid & free completions |
<link> |
URL to the chapter page โ used to construct message links |
<nameextend> |
Used for arc detection (looks for markers like โ001โ, โ(1)โ, โ.1โ) when generating New Arc Alerts |
<volume> |
Optional alternative base name for arcs if present |
Only
<chaptername>and<link>are strictly required for completion checks. Arc alerts also use<nameextend>or<volume>.
update-paid-feed.ymlandupdate-free-feed.yml:- Cron/dispatch regenerates the respective XML feed file.
- Commits changes and triggers the notifier via:
curl -X POST \ -H "Accept: application/vnd.github.v3+json" \ -H "Authorization: Bearer $GH_PAT" \ https://api.github.com/repos/USER/discord-notifier/dispatches \ -d '{"event_type":"trigger-discord-notify"}'
The workflow listens for:
on: repository_dispatch.types = [trigger-discord-notify]- A scheduled cron
- Manual workflow dispatch
Jobs:
- New Arc Checker
python new_arc_checker.py - New Extra Checker
python new_extra_checker.py - Completion Checker
- name: Paid Completion run: python completed_novel_checker.py --feed paid - name: Free Completion run: python completed_novel_checker.py --feed free
- New Launch Checker
- name: New Launch Checker run: python new_novel_checker.py --feed free
- For each novel, the
HOSTING_SITE_DATAmust be updated first before 1st chapter is scheduled to launch. - For each novel, set a
history_file(e.g.tvitpa_history.json) innovel_mappings.py. If it doesn't exist yet, the script will create it on first run and quietly record Arc 1 (no ping on the very first arc). - Arcs are stored persistently and prevent duplicate notifications.
- NSFW detection adds an extra Discord role mention.
- Every Discord webhook payload uses
"allowed_mentions":{"parse":["roles"]}to color role pings and"flags":4to suppress all link-preview embeds. - Each novel in
HOSTING_SITE_DATAmust define:free_feed: the global/public RSS that lists ALL free/public chapters from all novels.paid_feed: the global/advance RSS that lists ALL paid/locked chapters from all novels. The checkers filter those feeds by<title>to isolate just that novel.
Some scripts will silently skip a novel if one of these feeds is missing. See:
New Series Launch Alerts
- Requires:
free_feed - Behavior: only fires when a public first drop appears (
Chapter 1,Ch 1,Episode 1,Ep 1,1.1,Prologue) - Skips paywalled-only debuts
New Arc Alerts
- Requires:
free_feedandpaid_feed - Behavior: if either feed is missing, that novel is skipped (no ping, no history update)
Extras / Side Story Alerts
- Requires:
paid_feed - Behavior: if
paid_feedis missing, that novel is skipped - Purpose: announces when extras / side stories begin dropping in paid/advance access
Completion Announcements
- Runs twice:
python completed_novel_checker.py --feed paid- Requires:
paid_feed - Announces: the final paid/advance chapter is out (series is fully translated)
- Requires:
python completed_novel_checker.py --feed free- Requires:
free_feed - Announces: the full series is now unlocked for free / bingeable
- Requires:
- Behavior: each side only fires once per novel
๐ Now, you're ready to automate new arc and novel completion announcements to Discord!
Weโve just added three standalone Python bots (migrated from MonitoRSS) that post directly as your own Discord bot:
| Script | Purpose |
|---|---|
bot_free_chapters.py |
Posts new free chapters (๐) in oldestโnewest order. |
bot_paid_chapters.py |
Posts new advance/paid chapters (๐) in oldestโnewest order. |
bot_comments.py |
Posts new comments with from hosting sites. |
-
Repository Secrets
In Settings โ Secrets and variables โ Actions, add:Name Value DISCORD_BOT_TOKENBotโs token DISCORD_CHANNEL_IDChannel ID for news/announcements DISCORD_FREE_CHAPTERS_CHANNELChannel ID for free-chapter posts DISCORD_ADVANCE_CHAPTERS_CHANNELChannel ID for paid-chapter posts DISCORD_COMMENTS_CHANNELChannel ID for comment posts -
Dependencies
Ensure your CI/workflow install step includes:pip install discord.py feedparser python-dateutil aiohttp
These scripts are invoked by your rss-feed repository workflows, and can also be scheduled by cron.
Advance Chapters
|
Free Chapters
|
Comments
|
|
- You can now receive announcements from Novel Updates to know about:
- New comments.
- Weekly readers' statistics.


