Publish is a Notion integration & server that enables publishing data-driven content by people not experienced with databases. It's basically just a big spreadsheet.
Publish downloads and caches Notion database content and serves it on it's own web server. This includes attached images. Publish will even process the images into standardized .webp
format (600px thumbnail size and 4K large size) for efficiency.
It does not work with regular pages (markdown content). Only databases.
It uses notion_flatten
's flattened data structure.
There are two ways to ensure Publish will cache a page. One is to statically add it to the Publish cache list in data/clubs.ts
.
The other is to add it in a database page under a column named ID
, and adding that page's ID to the Publish dynamicDatabase
cache list in data/clubs.ts
.
Example:
[
{
id: "myAwoo", // arbitrary, publish from PUBLISH.TLD/?club=myAwoo
name: "National Art Honors Society", // also arbitrary, for vanity
short: "nahs", // used in logging
dynamicDatabases: [
"1234" // Notion database ID for a database with a column called ID, with more Notion database IDs inside to be cached
],
databases: [
"5678", // Notion database ID to always cache
],
}
]
:dbID
is the Notion page's ID. See above on how to make sure Publish caches this page.
publish.tld/cache/:dbID.json
- flat list of pages from the database (see notion_flatten above for exact format)
- typically, you should be querying this route and using the URLs returned inside it to access images!
- rows with files attached have additional or modified properties:
{
"type": "file",
"name": "ABCDE.png", // new name of file
"url": "https://db.lahs.club/view/dbID/ABCDE.webp", // 4K webp
"id": "ABCDE", // new id of file
"icon": "https://db.lahs.club/icon/dbID/ABCDE.webp", // 600px webp
"original": "https://db.lahs.club/content/dbID/ABCDE.png" // originally downloaded file
}
publish.tld/content/:dbID/:image
- original image downloaded from Notion, where :image
is something like "ABCDEF.jpg"
publish.tld/icon/:dbID/:imageID.webp
- 600px processed thumbnail
publish.tld/meta/:dbID.json
- metadata about the database, including property info, last updated when, etc. (see notion_flatten for exact spec)
publish.tld/view/:dbID/:image.webp
- 4K processed image
It is highly recommended to use Docker volume/bind mounts, etc. to store the cached content in case the container is restarted.
docker build -t publish .
docker run \
--name=publish \
--restart=always \
--env NOTION_TOKEN=secret_... \
-p 8000:8000 \
-v /root/publish/cache:/app/app/cache \
-v /root/publish/content:/app/app/content \
-v /root/publish/meta:/app/app/meta \
-v /root/publish/view:/app/app/view \
-v /root/publish/icon:/app/app/icon \
-d \
publish
- /embed
- https://publish.tld/?club=myAwoo (or whatever you set in clubs.ts, see above)
- Grant access to all pages you set to cache above by inviting your integration, make sure you deployed Publish with that secret
- Hit the Publish button on the widget
- Win! (test
/cache/:dbID.json
to see if it's working)
Make sure you have a valid Notion integration secret, and it's added to all databases you want to cache. Publish will throw errors if it can't access the page.
If you're running this on like, a literal potato, for very large databases this thing can take actually forever because image processing is computationally intensive. About 3GB of image files takes over an hour to process on an entry level DigitalOcean droplet. docker stats
is useful here on the server side.
PR! :3
- MIT
- sharp (nodejs)
- deno
- oak
- nanoid
- notion_flatten