substack-publisher
npx skills add https://github.com/apetcu/substack-skill --skill substack-publisher
Agent 安装分布
Skill 文档
Substack Publisher
Publish markdown posts to Substack as drafts or newsletter articles. Converts markdown to Substack’s ProseMirror JSON format.
Requirements
Set these environment variables (add to .env):
SUBSTACK_SID– Yoursubstack.sidsession cookie valueSUBSTACK_SUBDOMAIN– Your Substack subdomain (e.g.,adrianpetcu)SUBSTACK_USER_ID– Your Substack user ID (e.g.,106993810)
Quick Start
python scripts/publish_to_substack.py posts/daily-thoughts/03-context-driven-bug-fixing.md --dry-run
Script Usage
python scripts/publish_to_substack.py <file.md> [options]
Required:
file– Path to the markdown post file
Options:
--title– Override post title (default: extracted from# heading)--subtitle– Override subtitle (default: extracted from## Hooksection)--publish– Publish immediately instead of creating a draft--audience– Post audience:everyone(default) orpaid--dry-run– Output ProseMirror JSON to stdout without making API calls
Workflow
- Select the post file – Choose a markdown post from the repository
- Preview with dry-run – Always run
--dry-runfirst to verify the conversion - Create draft – Run without
--publishto create a draft on Substack - Review in Substack – Open the draft URL and verify formatting
- Publish – Either publish from Substack’s editor or re-run with
--publish
Markdown Format Support
The script handles the repository’s post template format:
- Title: Extracted from the first
# heading - Subtitle: Extracted from the
## Hooksection content - Body: All remaining sections converted to ProseMirror nodes
Included sections: Key Points, Body Outline, Call to Action, Visual Walkthrough, and any custom sections.
Excluded sections (metadata): Status, Hashtags, Notes, Verdict, LinkedIn Assessment.
Block elements: Paragraphs, headings (H1-H3), bullet lists, ordered lists, code blocks (with language), blockquotes, horizontal rules, images (HTTP URLs only).
Inline marks: bold, italic, code, links.
Special handling: Bold labels on standalone lines (e.g., **Section Name:**) become H3 headings. Local image paths are skipped with a warning.
Examples
Preview conversion:
python scripts/publish_to_substack.py posts/daily-thoughts/03-context-driven-bug-fixing.md --dry-run
Create a draft:
python scripts/publish_to_substack.py posts/daily-thoughts/03-context-driven-bug-fixing.md
Publish with custom title:
python scripts/publish_to_substack.py posts/daily-thoughts/03-context-driven-bug-fixing.md \
--title "How AI Turns Vague Bugs Into Actionable Tickets" --publish
Paid subscribers only:
python scripts/publish_to_substack.py post.md --audience paid
How to Get SUBSTACK_SID
- Log into Substack in your browser
- Open DevTools (F12) â Application â Cookies
- Find
substack.sidcookie for your subdomain - Copy the value and set it:
export SUBSTACK_SID="your-cookie-value"
Alternatively, inspect any network request in DevTools â Headers â Cookie and copy the substack.sid=... value.
Note: This cookie expires periodically. If you get a 401/403 error, refresh the cookie.