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:
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 |
DISCORD_WEBHOOK.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.
repo (Full control of private repositories)workflow (Required for GitHub Actions)GH_PAT.🚨 Important:
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.
{
"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"
}
]
}
new_arc_checker.py and completed_novel_checker.py:
- Re-add your CONFIG_PATH constant:
diff
- Bring back `load_config()` helper (which reads `config.json`).
- Swap the bottom if `__name__ == "__main__":` block to loop over:
python
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.yml and update-free-feed.yml:
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]Jobs:
python new_arc_checker.py
python new_extra_checker.py
name: Paid Completion run: python completed_novel_checker.py –feed paid
name: Free Completion run: python completed_novel_checker.py –feed free ```
HOSTING_SITE_DATA must be updated first before 1st chapter is scheduled to launch.history_file (e.g. tvitpa_history.json) in novel_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)."allowed_mentions":{"parse":["roles"]} to color role pings and "flags":4 to suppress all link-preview embeds.HOSTING_SITE_DATA must 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.New Series Launch Alerts
free_feedChapter 1, Ch 1, Episode 1, Ep 1, 1.1, Prologue)New Arc Alerts
free_feed and paid_feedExtras / Side Story Alerts
paid_feedpaid_feed is missing, that novel is skippedCompletion Announcements
python completed_novel_checker.py --feed paid
paid_feedpython completed_novel_checker.py --feed free
free_feed🚀 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_TOKEN |
Bot’s token |
DISCORD_CHANNEL_ID |
Channel ID for news/announcements |
DISCORD_FREE_CHAPTERS_CHANNEL |
Channel ID for free-chapter posts |
DISCORD_ADVANCE_CHAPTERS_CHANNEL |
Channel ID for paid-chapter posts |
DISCORD_COMMENTS_CHANNEL |
Channel 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 |
|