Created
November 28, 2021 00:08
-
-
Save altrim/141e25b46ba5fc8be4adb1517fb6d16e to your computer and use it in GitHub Desktop.
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
import "@johnlindquist/kit"; | |
// Menu: Notion Thoughts | |
// Description: Add quick thoughts to a notion journal page | |
// Author: Altrim Beqiri | |
// Twitter: @altrimbeqiri | |
/** @type {typeof import("@notionhq/client")} */ | |
const { Client } = await npm("@notionhq/client"); | |
/** @type {typeof import("date-fns")} */ | |
const { format, parseISO, formatISO, isSameMinute } = await npm("date-fns"); | |
const NOTION_URL = await env("NOTION_URL"); | |
const DATABASE_ID = await env("NOTION_DATABASE_ID"); | |
const TOKEN = await env("NOTION_TOKEN"); | |
const notion = new Client({ | |
auth: TOKEN, | |
}); | |
/** | |
* Create a heading two block | |
* | |
* @param content | |
* @returns block object https://developers.notion.com/reference/block#heading-two-blocks | |
*/ | |
const createHeadingBlock = (content: string) => { | |
return { | |
object: "block", | |
type: "heading_2", | |
heading_2: { | |
text: [ | |
{ | |
type: "text", | |
text: { | |
content, | |
}, | |
}, | |
], | |
}, | |
}; | |
}; | |
/** | |
* Create a bulleted litst item block | |
* | |
* @param content | |
* @returns block object https://developers.notion.com/reference/block#bulleted-list-item-blocks | |
*/ | |
const createBulletItemBlock = (content: string) => { | |
return { | |
object: "block", | |
type: "bulleted_list_item", | |
bulleted_list_item: { | |
text: [ | |
{ | |
type: "text", | |
text: { | |
content, | |
}, | |
}, | |
], | |
}, | |
}; | |
}; | |
/** | |
* Query the database by the name and today's date | |
* | |
* https://developers.notion.com/reference/post-database-query | |
* @returns database object https://developers.notion.com/reference/database | |
*/ | |
const queryDatabase = async () => | |
await notion.databases.query({ | |
database_id: DATABASE_ID, | |
filter: { | |
and: [ | |
{ | |
property: "Name", | |
text: { | |
contains: "Thoughts", | |
}, | |
}, | |
{ | |
property: "Created", | |
created_time: { | |
equals: formatISO(new Date(), { representation: "date" }), | |
}, | |
}, | |
], | |
}, | |
sorts: [ | |
{ | |
property: "Created", | |
direction: "ascending", | |
}, | |
], | |
}); | |
/** | |
* Create a new page in the database with today's date and a Daily tag | |
* | |
* https://developers.notion.com/reference/create-a-database | |
* @returns https://developers.notion.com/reference/page | |
*/ | |
const createPage = async () => | |
await notion.pages.create({ | |
parent: { | |
database_id: DATABASE_ID, | |
}, | |
icon: { | |
type: "emoji", | |
emoji: "📝", | |
}, | |
properties: { | |
Name: { | |
title: [ | |
{ | |
text: { | |
content: `${format(new Date(), "yyyy-MM-dd")} - Thoughts`, | |
}, | |
}, | |
], | |
}, | |
Tags: { | |
multi_select: [{ name: "Daily" }], | |
}, | |
}, | |
children: [createHeadingBlock(`${format(new Date(), "HH:mm")}`)], | |
}); | |
const hasThoughtsForTheDay = (thoughts?: any[]) => thoughts && thoughts.length > 0; | |
// Query the database for the page that contains the "Thoughts" label and the today's date | |
const { results: database } = await queryDatabase(); | |
// If we don't have a page for today we create a new one | |
const page = hasThoughtsForTheDay(database) ? database[0] : await createPage(); | |
while (true) { | |
const thought = await arg({ | |
placeholder: "Thought:", | |
hint: `Type "open" to open journal in browser`, | |
}); | |
// Will open the journal in a new tab in your default browser and exit the script | |
if (thought === "open") { | |
focusTab(`${NOTION_URL}/${DATABASE_ID}`); | |
break; | |
} | |
// List all the children in the page | |
const { results: children } = await notion.blocks.children.list({ | |
block_id: page.id, | |
page_size: 42, // The number of items from the full list desired in the response. Maximum: 100 | |
}); | |
// Get last heading block we have on the page | |
const headingBlock = [...children].reverse().find((obj: any) => obj.type === "heading_2"); | |
// Check if the last heading is not same time as the current time we need to create a new heading block | |
const isSameTime = isSameMinute(parseISO(headingBlock?.created_time), new Date()); | |
if (!isSameTime) { | |
await notion.blocks.children.append({ | |
block_id: page.id, | |
children: [createHeadingBlock(format(new Date(), "HH:mm"))], | |
}); | |
} | |
// Append the item to the last heading block | |
await notion.blocks.children.append({ | |
block_id: page.id, | |
children: [createBulletItemBlock(thought)], | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment