Publish Content to Telegraph with Media
Publishes articles to Telegraph with images, diagrams, and YouTube embeds, using GitHub+jsDelivr for permanent media hosting.
Why it matters
Effortlessly publish rich content to Telegraph, including text, images, and YouTube embeds. Streamline your content creation and distribution process.
Outcomes
What it gets done
Create and format blog posts for Telegraph.
Embed images and diagrams directly into Telegraph pages.
Integrate YouTube videos seamlessly into your content.
Publish content automatically to your Telegraph account.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/telegraph-publisher | bash Overview
Telegraph Publisher
Publishes articles, reports, and documentation to Telegraph with images, YouTube embeds, and rendered diagrams, using a GitHub+jsDelivr workflow for stable permanent media hosting instead of Telegraph's unstable upload endpoint. Use when publishing an illustrated article or report to Telegraph, especially with images, diagrams, tables, or embedded video, or when long content needs automatic multi-page splitting.
What it does
This skill publishes content to Telegraph, the lightweight publishing platform, via its API, supporting images, YouTube embeds, PlantUML/Mermaid diagrams, and automatic splitting of long articles into linked multi-page sets. It's best suited for articles, research reports, documentation, and illustrated content. Rather than passing raw Markdown, it converts HTML fragments into Telegraph's required Node JSON format automatically, using a whitelist of supported tags (a, b, blockquote, code, figure, h3/h4, img, lists, p, pre, iframe, video, and more) - unsupported tags are stripped while their children are kept, and HTML tables specifically get converted into a readable monospace pre block since Telegraph has no native table node, with explicit guidance on when a table is more appropriate than a diagram (exact values matter) versus when a diagram is better (trends, flow, cohorts) and a mobile-first rule against wide dense tables that wrap badly on phones.
Its account model is API-only with no password or email: create_account.sh generates an access token plus a one-time auth URL to bind the API account to a browser session, after which pages are editable both via the API and at telegra.ph directly, with --revoke available to rotate a compromised token. For permanent media, the skill explicitly prefers a GitHub-backed workflow over Telegraph's own unofficial, unstable upload endpoint: images and diagrams are uploaded to a dedicated public GitHub assets repo, scoped to a fine-grained PAT with only Contents: Read and write on that one repo, and served via jsDelivr's CDN for stable permanent URLs, with a manifest tracking each page's uploaded assets by path and Git SHA so they can later be cleanly deleted via github_delete_page_assets.sh, keyed by Telegraph's stable path identifier rather than the page title, which can change. Telegraph's own upload.sh endpoint is explicitly demoted to a legacy fallback only, described as glitchy and unreliable behind corporate proxies/VPNs. Diagrams render through public PlantUML/Mermaid servers, a privacy consideration for confidential content, and can similarly be piped into the GitHub-backed permanent hosting flow. YouTube URLs are auto-normalized from watch?v=/youtu.be formats into embeddable iframe format. An optional integration with a separate fal-ai-image skill can generate illustrations before publishing, with a mandatory budget confirmation step (starting at $0.15/image) before generating anything.
When to use - and when NOT to
Use this skill when publishing an article, research report, or illustrated document to Telegraph, especially when the content includes images, diagrams, tables, or YouTube video embeds, or when a long article needs automatic splitting across multiple linked pages (content over roughly 60KB triggers auto-split with an index page).
It requires a TELEGRAPH_ACCESS_TOKEN, created via create_account.sh if none exists, and for stable permanent media, a separate GitHub repo and scoped PAT - without that GitHub setup, media falls back to Telegraph's unreliable unofficial upload endpoint. It only accepts HTML fragments as input in this version, not raw Markdown, and diagram rendering sends source content to public third-party servers, so it should not be used for confidential diagrams.
Inputs and outputs
Input is a page title plus content as an HTML string, an HTML file, or pre-built Node JSON, along with any local images/diagrams needing permanent hosting. Output is a published or edited Telegraph page, with media served via stable jsDelivr URLs when GitHub-backed hosting is used, long content automatically split into an indexed multi-page set, and a per-page manifest tracking uploaded assets for later cleanup.
sh scripts/create_page.sh --title "Article" --html-file article.html
Integrations
Built on the Telegraph API, a GitHub assets repo plus jsDelivr CDN for permanent media hosting, public PlantUML/Mermaid rendering servers for diagrams, and an optional fal-ai-image skill integration for generating illustrations before publishing.
Who it's for
Writers and researchers publishing illustrated articles, reports, or documentation to Telegraph who want reliable permanent media hosting, automatic long-article splitting, and clean diagram/table/video embedding rather than manually wrangling Telegraph's raw API and unstable upload endpoint.
Source README
telegraph-publisher
Publish content to Telegraph via API with media support.
Best for: articles, research reports, documentation, illustrated content.
STOP - Read Before Acting
- DO NOT pass raw markdown - convert to HTML fragment first (Telegraph API accepts Node JSON, the converter accepts HTML)
- DO NOT pass content larger than 64KB without using auto-split - the script handles this automatically
- DO NOT hardcode access tokens - use
config/.env - DO NOT skip account setup - run
create_account.shfirst if no token exists
Quick Start
No token? → sh scripts/create_account.sh --name "Name"
Have token? → Save to config/.env
Publish page? → sh scripts/create_page.sh --title "Title" --html "<p>Content</p>"
Edit page? → sh scripts/edit_page.sh --path "Path-03-09" --title "Title" --html "<p>New</p>"
List pages? → sh scripts/list_pages.sh
Account info? → sh scripts/account_info.sh
Permanent media? → sh scripts/github_upload.sh --file hero.webp --page-path page-path
Account & Ownership
Telegraph accounts are API-only (no password/email). Key concepts:
create_account.shgeneratesaccess_token+ one-timeauth_url- Open
auth_urlin browser to bind API account to browser session - Pages belong to the account whose token was used in
createPage - After browser binding: pages visible at telegra.ph, editable both via browser and API
- Use
--revoketo rotate token if compromised
See config/README.md for full ownership model.
Compatibility
Scripts are POSIX sh compatible - work in cloud sandboxes (/bin/sh) and locally.
Python scripts use stdlib only (html.parser, json, sys).
Config
Requires TELEGRAPH_ACCESS_TOKEN in config/.env or environment.
For permanent media hosting, prefer a separate public GitHub repo + jsDelivr CDN.
Reason: Telegraph's unofficial upload endpoint is unstable and should not be the default publishing path.
GitHub Setup (recommended)
The agent should assume this is the default permanent media backend.
Required GitHub config:
GITHUB_TOKEN=ghp_...
GITHUB_ASSETS_REPO=owner/repo
GITHUB_ASSETS_BRANCH=main
GITHUB_ASSETS_BASE_DIR=pages
GITHUB_MANIFESTS_DIR=manifests
Recommended setup:
- Create a separate public GitHub repo only for Telegraph media
- Create a fine-grained PAT only for that repo
- Grant only:
Contents:Read and write
- Save token and repo to
config/.env
Why this matters:
- permanent asset URLs via jsDelivr
- lower blast radius if token leaks
- no dependency on Telegraph's glitchy upload endpoint
- deterministic cleanup through page manifests
Agent rule:
- if local images/diagrams need permanent hosting and GitHub config exists, use GitHub-backed media workflow by default
- use
upload.shonly as a legacy fallback
Content Format
Telegraph API accepts an array of Node objects. This skill converts HTML fragments to Node JSON automatically.
Supported HTML tags (Telegraph API whitelist):a, aside, b, blockquote, br, code, em, figcaption, figure, h3, h4, hr, i, iframe, img, li, ol, p, pre, s, strong, u, ul, video
Only href and src attributes are preserved. Unsupported tags are stripped (children kept).
Special case:
- input HTML tables (
table,thead,tr,th,td) are converted into a readable monospacepreblock - use this for compact comparisons, domain spend breakdowns, KPI matrices, and similar tabular fragments
- do not force small tables into diagrams unless the user explicitly wants a visual chart instead of exact values
See references/CONTENT_FORMAT.md for Node format details.
Scripts
create_account.sh
sh scripts/create_account.sh --name "Author Name" [--author-url "https://..."]
sh scripts/create_account.sh --revoke # rotate token
account_info.sh
sh scripts/account_info.sh
sh scripts/account_info.sh --with-auth-url # include auth_url in output
create_page.sh
### From HTML string
sh scripts/create_page.sh --title "Article" --html "<h3>Hello</h3><p>World</p>"
### From HTML file
sh scripts/create_page.sh --title "Article" --html-file article.html
### From pre-built Node JSON
sh scripts/create_page.sh --title "Article" --content-file nodes.json
### With author info
sh scripts/create_page.sh --title "Article" --html-file a.html --author-name "Name"
| Param | Required | Description |
|---|---|---|
--title |
yes | Page title (1-256 chars) |
--html |
one of three | Inline HTML string |
--html-file |
one of three | Path to HTML file |
--content-file |
one of three | Path to Node JSON file |
--author-name |
no | Author name (0-128 chars) |
--author-url |
no | Author profile URL |
Auto-split: If content exceeds 60KB, automatically splits into multiple pages with an index page linking to parts.
edit_page.sh
sh scripts/edit_page.sh --path "Page-Title-03-09" --title "Updated Title" --html "<p>New content</p>"
| Param | Required | Description |
|---|---|---|
--path |
yes | Page path (from URL or create output) |
--title |
yes | Page title |
--html / --html-file / --content-file |
yes | New content |
--author-name |
no | Author name |
--author-url |
no | Author URL |
list_pages.sh
sh scripts/list_pages.sh
sh scripts/list_pages.sh --offset 0 --limit 20
github_upload.sh
Upload local media to the GitHub assets repo and update page manifest:
sh scripts/github_upload.sh --file ./hero.webp --page-path my-page-path
sh scripts/github_upload.sh --file ./diagram.png --page-path my-page-path --name diagram-01.png
| Param | Required | Description |
|---|---|---|
--file |
yes | Local asset file |
--page-path |
yes | Telegraph page path used as manifest/asset key |
--name |
no | Override stored filename in GitHub |
Output: commit-pinned jsDelivr URL.
Manifest behavior:
- assets go under
pages/<telegraph_path>/... - manifest goes under
manifests/<telegraph_path>.json - manifest stores asset paths and SHAs for later cleanup
github_delete_page_assets.sh
Delete all GitHub-backed assets for a page using its manifest:
sh scripts/github_delete_page_assets.sh --page-path my-page-path
| Param | Required | Description |
|---|---|---|
--page-path |
yes | Telegraph page path |
Cleanup rule:
- delete by manifest, not by title guessing
- use Telegraph
pathas the stable page identifier
upload.sh
Legacy fallback for local image/video upload to Telegraph:
### Best-effort only
URL=$(sh scripts/upload.sh --file /path/to/photo.jpg)
### Use in HTML
echo "<figure><img src=\"$URL\"><figcaption>My photo</figcaption></figure>"
| Param | Required | Description |
|---|---|---|
--file |
yes | Path to image/video (jpg, png, gif, webp, mp4; max 5MB) |
--insecure |
no | Skip SSL verification (for HTTPS-intercepting proxies/VPNs) |
Note: Uses unofficial telegra.ph/upload endpoint. Do not treat it as the primary workflow. Best-effort only - may fail behind corporate proxies/VPNs or without any obvious reason.
render_diagram.sh
Render PlantUML/Mermaid diagrams via public servers:
### Get render URL (image on public server)
sh scripts/render_diagram.sh --type plantuml --file arch.puml
### Render + upload to GitHub-backed permanent media
sh scripts/render_diagram.sh --type mermaid --file flow.mmd --github-page-path my-page-path --github-name cohort.png
### Legacy fallback: render + upload via Telegraph upload
sh scripts/render_diagram.sh --type mermaid --file flow.mmd --upload
| Param | Required | Description |
|---|---|---|
--type |
yes | plantuml or mermaid |
--file |
yes | Path to diagram source file |
--github-page-path |
no | Upload rendered file to GitHub assets under this Telegraph path |
--github-name |
no | Override GitHub filename for rendered asset |
--upload |
no | Legacy fallback: download rendered PNG and upload to Telegraph |
Privacy: Diagram source is sent to plantuml.com / mermaid.ink. Do not use for confidential content.
content_converter.py (internal)
### HTML → Node JSON
echo '<p>Hello <b>world</b></p>' | python3 scripts/content_converter.py
### Check serialized size (bytes)
cat nodes.json | python3 scripts/content_converter.py --check-size
### Split large content
cat nodes.json | python3 scripts/content_converter.py --split --output-dir /tmp/parts
Media Support
Images
Preferred workflow: upload local files to a dedicated public GitHub assets repo and serve them via jsDelivr.
Why GitHub is worth connecting:
- stable permanent URLs for Telegraph pages
- no dependency on Telegraph's glitchy unofficial upload endpoint
- predictable asset structure for cleanup
- easy separation between article content and media storage
Fallback workflow: use upload.sh only when GitHub-backed hosting is unavailable.
Recommended asset lifecycle:
- If a page contains local media, first create a draft/stub Telegraph page to get its final
path - Upload images/diagrams to GitHub under
pages/<telegraph_path>/...viagithub_upload.sh - Publish final content with jsDelivr URLs
- Store a manifest for that page with uploaded asset paths and GitHub blob SHAs
- On page cleanup/removal, run
github_delete_page_assets.sh --page-path <telegraph_path>
Agent decision rule:
- if the user wants permanent images, diagrams, or hero art, prefer GitHub-backed media
- if the page is temporary and the user explicitly accepts risk,
upload.shcan be used as fallback - if the page is being deleted or rebuilt, clean up assets through
github_delete_page_assets.sh
Do not key cleanup only by page title. Titles can change. Use Telegraph path as the primary page identifier.
If a two-pass draft flow is not available, use a temporary page key and persist a manifest mapping:telegraph_path -> github asset paths.
Legacy fallback: upload local files or use public URLs:
### Local file → Telegraph URL
URL=$(sh scripts/upload.sh --file photo.jpg)
Then embed in HTML:
<figure>
<img src="https://telegra.ph/file/abc123.jpg">
<figcaption>Photo caption</figcaption>
</figure>
See references/IMAGE_WORKFLOWS.md for workflows.
YouTube Embeds
YouTube URLs are automatically normalized to embed format:
<figure>
<iframe src="https://www.youtube.com/watch?v=VIDEO_ID"></iframe>
</figure>
The converter transforms watch?v= and youtu.be/ URLs to /embed/ format.
See references/YOUTUBE_EMBEDS.md for details.
Diagrams
Preferred workflow: render PlantUML/Mermaid, store the image in GitHub assets, then publish jsDelivr URL.
Legacy fallback: render PlantUML/Mermaid to image and upload:
### Preferred: render + GitHub upload
URL=$(sh scripts/render_diagram.sh --type plantuml --file arch.puml --github-page-path my-page-path --github-name arch.png)
### Legacy fallback
URL=$(sh scripts/render_diagram.sh --type plantuml --file arch.puml --upload)
See references/DIAGRAMS.md for details and privacy considerations.
Tables
Telegraph does not support real HTML tables as native nodes. This skill handles that by converting input HTML tables into a readable monospace pre block.
Use tables when:
- exact values matter more than visual storytelling
- the user needs a compact spend/domain breakdown
- the content should stay copyable and stable in Telegraph
Use diagrams when:
- you need trends, shares, flow, cohorts, or process explanation
- the user benefits from visual comparison more than exact cell-by-cell reading
Mobile-first rule:
- do not use
pretables for wide tables with 3+ dense columns or long labels - on mobile, wide monospace tables wrap badly and become unreadable
- for mobile-sensitive reports, prefer one of these:
- bar/pie/cohort diagram plus a short numeric summary
- bullet list or mini-cards: one metric/domain per row
- a narrow 2-column table only if the content still fits comfortably
Example input:
<table>
<thead>
<tr><th>Domain</th><th>Spend, USD</th></tr>
</thead>
<tbody>
<tr><td>metallik.ru</td><td>82,900</td></tr>
<tr><td>mir-shtaketnika.ru</td><td>38,367</td></tr>
</tbody>
</table>
This will be published as a boxed monospace table inside a pre block.
Optional: Illustrations with fal-ai-image
If the fal-ai-image skill is installed, you can generate illustrations before publishing:
- Read fal-ai-image SKILL.md first
- Confirm budget with user before generating (from $0.15/image)
- Generate images, save URLs
- Include URLs in HTML as
<figure><img src="URL"></figure> - Publish via
create_page.sh
See references/FAL_AI_INTEGRATION.md for house style guide and prompt examples.
Important: telegraph-publisher works fully without fal-ai-image. This is an optional enhancement.
Limitations (v1)
- Input: HTML fragments only (no markdown conversion)
- No caching of API responses
- Auto-split boundary: if a single HTML element exceeds 60KB, manual splitting required
upload.shuses unofficial Telegraph endpoint and should be treated as legacy fallback only- Diagram rendering sends source to public servers (privacy consideration)
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.