Scripts by Alarid

My attempt with Notion API

Hey folks 👋

So I have this big "Tasks" database in Notion where I put all my tasks (personal/work/projects). Each task has many properties, including a "Status" (ToDo, Doing, Done, ...) and a "Day" (_Monday, Tuesday, ...) which I use in a view called "Week planner". It's a board view, one column for each value of the property "Day", which allows me to have a nice view of what needs to be done this week. I found myself using mainly this view for inserting new tasks. In fact, if I need to do something for tomorrow or the day after, then I add a new task in this column.

Since Notion released their APIs, I thought "How cool it would be to do this with Kit!". I finally did it, and I'm loving it already. This is gonna save me so much time. If I'm working on something and a new task pop into my mind, I can add it from anywhere in a few seconds.

Here is the script for those interested (UPDATED VERSION: thanks John for the tips)

// Menu: New task
// Description: Add a new task in Notion
const { newTask, getProperties, syncProperties } = await lib("notion-tasks")
let taskName = await arg({
placeholder: "Task name",
hint: `Type "sync" to sync`,
})
if (taskName === "sync") {
try {
await syncProperties()
notify({
title: "✅ Notion sync",
message: "Tasks properties successfully cached locally",
})
} catch (err) {
notify({
title: "⛔️ Notion sync",
message: "Something went wrong",
})
console.error(err)
}
taskName = await arg("Task name")
}
const { statusOptions, dayOptions, tagOptions } = getProperties()
const status = await arg(
"Status",
statusOptions.map((opt) => opt.name)
)
const day = await arg(
"Day",
dayOptions.map((opt) => opt.name)
)
const tag = await arg(
"Tag",
tagOptions.map((opt) => opt.name)
)
try {
await newTask(taskName, status, day, tag)
send("HIDE_APP")
notify({
title: "✅ New task added",
message: `${taskName} for ${day} (${status})`,
})
} catch (err) {
send("HIDE_APP")
notify({
title: "⛔️ New task",
message: `Something went wrong`,
})
console.error(err)
}

And the lib file (.kenv/lib/notion-tasks.js)

const notionToken = await env("NOTION_USER_TOKEN")
const databaseId = "06d55db47a994f429132d5d8fd9edd2a"
const tasksDb = await db("tasks", {
properties: {
statusOptions: [],
dayOptions: [],
tagOptions: [],
},
})
export const getProperties = () => tasksDb.properties
export async function syncProperties() {
const { data } = await get(
`https://api.notion.com/v1/databases/${databaseId}`,
{
headers: {
Authorization: `Bearer ${notionToken}`,
"Content-Type": "application/json",
"Notion-Version": "2021-05-13",
},
}
)
const {
Status: {
select: { options: statusOptions },
},
Day: {
multi_select: { options: dayOptions },
},
Tag: {
multi_select: { options: tagOptions },
},
} = data.properties
tasksDb.properties = { statusOptions, dayOptions, tagOptions }
await tasksDb.write()
}
export async function newTask(taskName, status, day, tag) {
return await post(
"https://api.notion.com/v1/pages",
{
parent: { database_id: databaseId },
properties: {
Name: {
title: [{ text: { content: taskName } }],
},
Status: {
select: { name: status },
},
Day: {
multi_select: [{ name: day }],
},
Tag: {
multi_select: [{ name: tag }],
},
},
},
{
headers: {
Authorization: `Bearer ${notionToken}`,
"Content-Type": "application/json",
"Notion-Version": "2021-05-13",
},
}
)
}

~Maybe I'm missing something about caching though 😅~ Any feedback/improvement ideas appreciated. And once again, thanks @johnlindquist for this amazing app, I use it every single day and it has definitely made my life easier 🙏

Discuss Post

Open Github repository in browser

I created a simple script to open one of my Github repositories in the browser. It starts by fetching the repositories, and ask which one to open. Obviously, you would need to change Alarid to your GitHub username if you would like to use this script 😊

~~Also, if someone knows how to make a "loading state" to avoid having just an empty prompt while fetching, that would be awesome! It only takes a few seconds, but still...~~

UPDATE: thanks @johnlindquist for the tip on the loading state, here is the updated version:

// Menu: Open Github Repo
// Description: Open the repo page in the browser
const USERNAME = "Alarid"
let dots = 0
let placeholderIntervalId = setInterval(() => {
setPlaceholder(`Loading ${USERNAME} github repos`.padEnd(++dots, "."))
}, 100)
const response = await get(`https://api.github.com/users/${USERNAME}/repos`)
const repositories = response.data
clearInterval(placeholderIntervalId)
if (!repositories) exit(1)
const choice = await arg(
"Which project?",
repositories.map((repo) => ({
name: repo.name,
description: repo.description,
value: repo.html_url,
}))
)
exec(`open ${choice}`)
Discuss Post

Brave bookmarks recursively

Hey there 👋

I just discovered Script Kit today, and I absolutely love it, awesome idea @johnlindquist 🔥

I made a few changes to your script chrome-bookmarks so I can use it with Brave (small change), but also to parse the bookmarks JSON recursively. This is particularly useful to me as I nest all my bookmarks in subfolders of the bookmark bar. With this change, I can open any bookmark (however deep it is nested in the bookmarks JSON).

I thought I'd share the script here, in case anyone find it useful too.

// Menu: Brave Bookmarks
// Description: Select and open a bookmark from Brave
function parseBookmarks(node) {
const bookmarks = [];
node.forEach((item) => {
if (item.type === "url") {
bookmarks.push(item);
} else if (item.type === "folder") {
bookmarks.push(...parseBookmarks(item.children));
}
});
return bookmarks;
}
let bookmarksFile = await readFile(
home(
"Library/Application Support/BraveSoftware/Brave-Browser/Default/Bookmarks"
)
);
const rootNode = JSON.parse(bookmarksFile);
const bookmarkBar = rootNode.roots.bookmark_bar;
const bookmarks = parseBookmarks(bookmarkBar.children);
let url = await arg(
"Select bookmark",
bookmarks.map(({ name, url }) => {
return {
name: name || url,
description: url,
value: url,
};
})
);
exec(`open ${url}`);
Discuss Post