Skip to content

Instantly share code, notes, and snippets.

@lmorchard
Last active January 25, 2024 17:50
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lmorchard/f1f2508a9586d8e92efd84686c029f16 to your computer and use it in GitHub Desktop.
Save lmorchard/f1f2508a9586d8e92efd84686c029f16 to your computer and use it in GitHub Desktop.
Substack to OPML export
// To use this script:
//
// 1. Copy this whole gist
// 2. Log into your account on substack.com
// 3. On a substack.com page, open the JavaScript console in your browser's web dev tools
// 4. Paste this into the console and hit return.
// 5. You should see substack-publications.opml has been downloaded.
//
// If you'd like to grab this code and improve it or turn it into a better tool, go right ahead!
// Maybe drop me a toot at @lmorchard@hackers.town or @lmorchard@toot.lmorchard.com if you liked it.
fetch("https://substack.com/api/v1/subscriptions")
.then(res => res.json())
.then(subscriptionsData => {
const feeds = subscriptionsData.publications.map(item => ({
text: item.name,
type: "rss",
htmlUrl: item.base_url,
xmlUrl: item.base_url + "/feed"
}));
const nodes = feeds.map(feed => `
<outline type="rss"
text="${feed.text}"
htmlUrl="${feed.htmlUrl}"
xmlUrl="${feed.xmlUrl}" />
`.trim());
const opml = `
<opml version='2.0'>
<body>
<outline text="Substack Publications" title="Substack Publications">
${nodes.join("\n")}
</outline>
</body>
</opml>
`.trim();
const data = new Blob([opml], {type: "application/xml"});
const url = window.URL.createObjectURL(data);
const a = document.createElement("a");
a.textContent = "DOWNLOAD SUBSTACK OPML EXPORT";
a.href = url;
a.download = "substack-publications.opml";
document.body.insertBefore(a, document.body.firstChild);
a.click();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment