Content Publisher
When to Use
Trigger phrases:
- "content publisher"
- "Help me with content publisher"
Use cases:
- When the task matches this skill's domain expertise
When NOT to use:
- For tasks outside this skill's scope
Automates drafting and publishing articles to Substack and Medium with workflow automation.
When NOT to Use
- For one-off tasks that will never repeat
- When the process requires human judgment at every step
- When the cost of automation exceeds the cost of manual execution
Overview
Content Publisher automates workflow automation to reduce manual effort and increase reliability.
Workflow
# Example: Workflow automation
import schedule
import time
def run_workflow():
data = fetch_data()
processed = transform(data)
deliver(processed)
schedule.every().hour.do(run_workflow)
while True:
schedule.run_pending()
time.sleep(60)
- Define triggers — Set up events or schedules that initiate the automation
- Configure inputs — Specify data sources and parameters
- Design pipeline — Define the sequence of automated steps
- Add error handling — Set up retries, alerts, and fallback paths
- Test end-to-end — Validate the full automation with realistic data
- Deploy and monitor — Activate and track performance
Code Examples
Python: Medium Draft
import os, requests
def publish_medium(title, body, tags):
token = os.environ["MEDIUM_TOKEN"]
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
user = requests.get("https://api.medium.com/v1/me", headers=headers).json()["data"]["id"]
payload = {"title": title, "contentFormat": "markdown", "content": body,
"tags": tags[:5], "publishStatus": "draft"}
resp = requests.post(f"https://api.medium.com/v1/users/{user}/posts", headers=headers, json=payload)
resp.raise_for_status()
return resp.json()["data"]["url"]
Node.js: WordPress Post
export async function publishWP(title, content, tags) {
const auth = Buffer.from(`${process.env.WP_USER}:${process.env.WP_APP_PASSWORD}`).toString("base64");
const resp = await fetch(`${process.env.WP_URL}/wp-json/wp/v2/posts`, {
method: "POST", headers: { Authorization: `Basic ${auth}`, "Content-Type": "application/json" },
body: JSON.stringify({ title, content, status: "draft", tags }),
});
if (!resp.ok) throw new Error(`WP ${resp.status}`);
return (await resp.json()).link;
}
Configuration
- Set trigger conditions (schedule, webhook, event)
- Define input validation rules
- Configure notification channels for alerts
- Set retry policies and timeout limits
Best Practices
- Start with simple automations and iterate
- Add logging at every step for debugging
- Use idempotent operations where possible
- Test with edge cases before deploying
Common Issues & Troubleshooting
| Problem |
Solution |
| Medium 403 Forbidden |
Token expired. Regenerate in Settings → Security → Integration tokens. |
| Substack draft missing |
Session cookie expires ~24h. Re-authenticate and extract fresh SUBSTACK_SESSION. |
| WordPress 401 Unauthorized |
Wrong app password or URL. Verify WP_URL ends with /wp-json/wp/v2/. |
| Cross-post formatting differs |
Unsupported Markdown features. Strip footnotes and uncommon extensions before dispatch. |
| Medium tag limit (max 5) |
API rejects >5 tags. Truncate to tags[:5] in the request payload. |
Anti-Rationalization Table
| Rationalization |
Reality |
| "Manual is faster for one-off tasks" |
One-off tasks become recurring. Automate early, save time later. |
| "I will add error handling later" |
You never do. Handle errors from day one. |
| "Automation is overkill" |
If you do it twice, automate it. If you do it daily, it is critical infrastructure. |
Process
- Research — Analyze target audience, competitors, and trending topics
- Create — Generate content following brand guidelines and best practices
- Publish & Optimize — Distribute to target platforms, track performance, iterate
Monetization
- Content syndication service — Offer automated cross-publishing to bloggers and small businesses. Google Doc or Markdown → Substack + Medium + WP.
- Newsletter arbitrage — Repurpose top Medium articles to a paid Substack newsletter; auto-forward new Substack posts back to Medium for discovery traffic.
- SEO content agency — Combine automated publishing with SEO analysis as a "write once, rank everywhere" retainer service for clients.
- Publishing templates & scripts — Sell reusable publishing workflows, editorial calendar templates, and API integration scripts as digital products.
Verification
1---2name: content-publisher3description: Use when automating drafting and publishing articles to Substack and Medium with SEO optimization, editorial calendars, and cross-platform distribution.4license: Apache-2.05---67# Content Publisher89## When to Use1011**Trigger phrases:**12- "content publisher"13- "Help me with content publisher"1415**Use cases:**16- When the task matches this skill's domain expertise1718**When NOT to use:**19- For tasks outside this skill's scope202122Automates drafting and publishing articles to Substack and Medium with workflow automation.232425## When NOT to Use2627- For one-off tasks that will never repeat28- When the process requires human judgment at every step29- When the cost of automation exceeds the cost of manual execution303132## Overview3334Content Publisher automates workflow automation to reduce manual effort and increase reliability.3536## Workflow3738```python39# Example: Workflow automation40import schedule41import time4243def run_workflow():44 data = fetch_data()45 processed = transform(data)46 deliver(processed)4748schedule.every().hour.do(run_workflow)49while True:50 schedule.run_pending()51 time.sleep(60)52```53541. **Define triggers** — Set up events or schedules that initiate the automation552. **Configure inputs** — Specify data sources and parameters563. **Design pipeline** — Define the sequence of automated steps574. **Add error handling** — Set up retries, alerts, and fallback paths585. **Test end-to-end** — Validate the full automation with realistic data596. **Deploy and monitor** — Activate and track performance606162## Code Examples6364### Python: Medium Draft65```python66import os, requests6768def publish_medium(title, body, tags):69 token = os.environ["MEDIUM_TOKEN"]70 headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}71 user = requests.get("https://api.medium.com/v1/me", headers=headers).json()["data"]["id"]72 payload = {"title": title, "contentFormat": "markdown", "content": body,73 "tags": tags[:5], "publishStatus": "draft"}74 resp = requests.post(f"https://api.medium.com/v1/users/{user}/posts", headers=headers, json=payload)75 resp.raise_for_status()76 return resp.json()["data"]["url"]77```7879### Node.js: WordPress Post80```javascript81export async function publishWP(title, content, tags) {82 const auth = Buffer.from(`${process.env.WP_USER}:${process.env.WP_APP_PASSWORD}`).toString("base64");83 const resp = await fetch(`${process.env.WP_URL}/wp-json/wp/v2/posts`, {84 method: "POST", headers: { Authorization: `Basic ${auth}`, "Content-Type": "application/json" },85 body: JSON.stringify({ title, content, status: "draft", tags }),86 });87 if (!resp.ok) throw new Error(`WP ${resp.status}`);88 return (await resp.json()).link;89}90```9192## Configuration9394- Set trigger conditions (schedule, webhook, event)95- Define input validation rules96- Configure notification channels for alerts97- Set retry policies and timeout limits9899## Best Practices100101- Start with simple automations and iterate102- Add logging at every step for debugging103- Use idempotent operations where possible104- Test with edge cases before deploying105106## Common Issues & Troubleshooting107108| Problem | Solution |109|---|---|110| Medium 403 Forbidden | Token expired. Regenerate in Settings → Security → Integration tokens. |111| Substack draft missing | Session cookie expires ~24h. Re-authenticate and extract fresh `SUBSTACK_SESSION`. |112| WordPress 401 Unauthorized | Wrong app password or URL. Verify `WP_URL` ends with `/wp-json/wp/v2/`. |113| Cross-post formatting differs | Unsupported Markdown features. Strip footnotes and uncommon extensions before dispatch. |114| Medium tag limit (max 5) | API rejects >5 tags. Truncate to `tags[:5]` in the request payload. |115116## Anti-Rationalization Table117118| Rationalization | Reality |119|---|---|120| "Manual is faster for one-off tasks" | One-off tasks become recurring. Automate early, save time later. |121| "I will add error handling later" | You never do. Handle errors from day one. |122| "Automation is overkill" | If you do it twice, automate it. If you do it daily, it is critical infrastructure. |123124125## Process1261271. **Research** — Analyze target audience, competitors, and trending topics1281. **Create** — Generate content following brand guidelines and best practices1291. **Publish & Optimize** — Distribute to target platforms, track performance, iterate130131## Monetization132133- **Content syndication service** — Offer automated cross-publishing to bloggers and small businesses. Google Doc or Markdown → Substack + Medium + WP.134- **Newsletter arbitrage** — Repurpose top Medium articles to a paid Substack newsletter; auto-forward new Substack posts back to Medium for discovery traffic.135- **SEO content agency** — Combine automated publishing with SEO analysis as a "write once, rank everywhere" retainer service for clients.136- **Publishing templates & scripts** — Sell reusable publishing workflows, editorial calendar templates, and API integration scripts as digital products.137138## Verification139140- [ ] All steps executed successfully141- [ ] Results validated against acceptance criteria142- [ ] Error handling tested with edge cases143- [ ] Documentation updated with findings