Last active
October 25, 2023 07:55
-
-
Save kebot/90de9c41742cacf371368d85870c4a75 to your computer and use it in GitHub Desktop.
Generate Epub for Omnivore Articles (new version see here -> https://github.com/agrmohit/omnivore-epub )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// get a list of articles based on search endpoint | |
import { gql, GraphQLClient } from 'npm:graphql-request' | |
import sanitizeHtml from 'npm:sanitize-html' | |
import epub, { Chapter } from 'npm:epub-gen-memory' | |
const OMNIVORE_API_KEY = '' | |
const OMNIVORE_ENDPOINT = 'https://api-prod.omnivore.app/api/graphql' | |
const graphQLClient = new GraphQLClient(OMNIVORE_ENDPOINT, { | |
headers: { | |
authorization: OMNIVORE_API_KEY | |
} | |
}) | |
async function getUnreadArticles () { | |
const query = gql` | |
{ | |
articles { | |
... on ArticlesSuccess { | |
edges { | |
cursor, | |
node { | |
title | |
slug | |
description | |
url | |
savedAt | |
language | |
subscription | |
isArchived | |
author | |
} | |
} | |
} | |
} | |
} | |
` | |
type Edge = { | |
cursor: string, | |
node: { | |
title: string, | |
slug: string, | |
url: string | |
savedAt: string | |
language: string | |
subscription: string | |
isArchived: boolean | |
author: string | |
} | |
} | |
const data = await graphQLClient.request<{articles: { edges: Edge[] }}>(query) | |
return data.articles.edges.map(e => e.node) | |
} | |
async function getArticle (slug: string) { | |
const query = gql`{ | |
article (username: "K.Y.", slug: "${slug}") { | |
... on ArticleSuccess { | |
article { | |
id, slug, url, content | |
} | |
} | |
} | |
}` | |
const data = await graphQLClient.request<{ | |
article: { | |
article: { | |
id: string, | |
slug: string, | |
url: string, | |
content: string | |
} | |
} | |
}>(query) | |
const sanitizedArticle = sanitizeHtml(data.article.article.content) | |
return { | |
...data.article.article, | |
content: sanitizedArticle | |
} | |
} | |
// mark sended | |
async function makeMagazine () { | |
console.log('〰️ getting article list') | |
const articles = await getUnreadArticles() | |
console.log('🤖 done') | |
const chapters: Chapter[] = [] | |
for (const article of articles) { | |
if (!article.isArchived) { | |
console.log(`fetching ${article.title}`) | |
const content = (await getArticle(article.slug)).content | |
chapters.push({ | |
title: article.title, | |
author: article.author, | |
content, | |
url: article.url | |
}) | |
console.log(`✅ done`) | |
} | |
} | |
// make a PDF and save it | |
const fileBuffer = await epub.default({ | |
title: 'Test Articles', | |
author: 'Omnivore', | |
// cover: article.image, | |
}, chapters) | |
await Deno.writeFile('./output.epub', fileBuffer) | |
console.log('📚 Success') | |
} | |
await makeMagazine() | |
Deno.exit() |
There has been a change in omnivore api which results in this script breaking. I have a fixed version with a few more changes here
nice, let's use https://github.com/agrmohit/omnivore-epub for future update of this project
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@kebot I added a tiny bit of error checking on chapters since it failed on one of my articles: https://gist.github.com/shombando/87a58583f02bb543b0a98bb24f813039/revisions?diff=unified
Thanks for making this excellent and concise script.