Scripts
This is a listing of all the scripts I use with Script Kit.
aws-cost.js
// Menu: View AWS Cost of time period// Description: Warning: This will cost $0.01 per runlet start = await arg('Enter start date (YYYY-MM-DD)')let end = await arg('Enter end date (YYYY-MM-DD)')let {stdout} = exec(`aws ce get-cost-and-usage --time-period Start=${start},End=${end} --granularity MONTHLY --metrics "BlendedCost"`)let data = JSON.parse(stdout)let monthCost = data.ResultsByTime[0].Total.BlendedCostlet { say } = await kit('speech')await say(`Your AWS bill is $${Number(monthCost.Amount).toFixed(2)}`)
build-portfolio.js
// Menu: Build Portfolio// Description: Runs a github actions workflow to build my site and deploy it to Netlify// Author: Benjamin Lannon// Twitter: @lannonbr// Shortcut: opt bconst workflowID = 50890;await arg("are you sure you want to build the site? Press enter to continue...");// triggers a workflow_dispatch event to my workflowconst { stderr, stdout } = exec(`/usr/local/bin/gh workflow run ${workflowID} --repo lannonbr/Portfolio`);console.log(stderr, stdout);
get-notion-events.js
// Name: Get Upcoming Notion Events/** @type {import("@johnlindquist/kit")} *//** @type {import("@notionhq/client")} */const { Client } = await npm("@notionhq/client");/** @type {import("dayjs")} */const dayjs = await npm("dayjs");const notion = new Client({ auth: process.env.NOTION_TOKEN });const database_id = process.env.NOTION_EVENT_DB;const response = await notion.databases.query({database_id,filter: {property: "Release",date: {on_or_after: dayjs().format("YYYY-MM-DD"),},},});const contents = response.results.map((item) => {const props = item.properties;return {name: props.Name.title[0].text.content,date: props.Release.date.start,type: props.Type.select.name,};});await arg("Here are the upcoming events",contents.map((item) => {return {name: `${item.type}: ${item.name}`,description: `Coming ${dayjs(item.date).format("MMMM DD, YYYY")}`,};}));
github-discussions.js
// Menu: GitHub Discussions// Description: Open the Discussions pane of a GitHub repo// Author: Benjamin Lannon// Twitter: @lannonbrlet repo = await arg("Enter repo (ex: johnlindquist/kit):");exec(`open https://github.com/${repo}/discussions`);
github-trending-puller.js
// Description: Pulls down trending repos from github and save to database// Schedule: 0 */4 * * *// Exclude: true/** @type typeof import('playwright') */const playwright = await npm("playwright");let dbDefaults = {};const langs = ["rust", "javascript", "typescript", "go", "python", "ruby"];for (const lang of langs) {dbDefaults[lang] = [];}const trendingDB = await db("github-trending", dbDefaults);const browser = await playwright.chromium.launch();for (const lang of langs) {const context = await browser.newContext();const page = await context.newPage();await page.goto(`https://github.com/trending/${lang}`);const repos = await page.evaluate(() => {const repos = document.querySelectorAll(".Box-row");const results = [];for (let repo of repos) {const repoName = repo.querySelector("h1 a").getAttribute("href").slice(1);let description = repo.querySelector("p")?.textContent.trim();const starCount = repo.querySelector("div span.d-inline-block.float-sm-right")?.textContent.trim();if (!description) {description = starCount;} else {description = `${starCount} | ${description}`;}results.push({name: repoName,value: `https://github.com/${repoName}`,description,});}return results;});trendingDB[lang] = repos;await trendingDB.write();}await browser.close();
github-trending.js
// Menu: GitHub Trending// Description: Show today's Trending GitHub Repos for various languagesconst trendingDB = await db("github-trending");const langs = ["rust", "javascript", "typescript", "go", "python", "ruby"];for (const lang of langs) {onTab(lang, async () => {const repo = await arg("Select a repo to open it", trendingDB[lang]);exec(`open ${repo}`);});}
lannonbr-garden.js
// Menu: Lannonbr.com Garden// Description: Search posts on lannonbr.com// Author: Benjamin Lannon// Twitter: @lannonbrlet resp = await get("https://lannonbr.com/posts.json");let post = await arg("What post do you want to read", resp.data.items);exec(`open ${post}`)copy(post);
learn-with-jason-search.js
// Menu: Learn with Jason Search// Description: Browse Learn With Jason Episodes// Author: Benjamin Lannon// Twitter: @lannonbrlet episode = await arg(`Search for an episode of Learn with Jason`,async () => {const resp = await get("https://www.learnwithjason.dev/episodes.json");console.log(JSON.stringify(resp.data.episodes[0], null, 2));return resp.data.episodes.map((episode) => {return {value: episode.slug.current,name: episode.title,};});});let url = `https://www.learnwithjason.dev/${episode}`;exec(`open ${url}`);
list-keyboard-shortcuts.js
// Menu: List Keyboard Shortcuts// Description: List out all scripts with keyboard shortcuts// Shortcut: opt s// Author: Benjamin Lannon// Twitter: @lannonbrlet scripts = await getScripts();let opts = [];for (let script of scripts) {if (script.shortcut) {opts.push({name: `${script.command}: ${script.shortcut}`,});}}await arg("Current shortcuts", opts);
nodejs-available-versions.js
// Menu: Available Node versions// Description: View all supported versions of NodeJS// Author: Benjamin Lannon// Twitter: @lannonbrlet resp = await get("https://raw.githubusercontent.com/nodejs/Release/main/schedule.json");const data = Object.entries(resp.data);/** @type typeof import('dayjs') */let dayjs = await npm("dayjs");let opts = [];for (let [version, info] of data) {let isSupported =dayjs(info.start).diff(dayjs(), "days") < 0 &&dayjs(info.end).diff(dayjs(), "days") > 0;if (isSupported) {opts.push({name: `Node ${version}`,description: `Maintainence ends on ${dayjs(info.end).format("MMMM DD, YYYY")}`,endDate: info.end,});}}opts = opts.sort((a, b) => {return dayjs(a.endDate).unix() - dayjs(b.endDate).unix();});await arg("These versions of NodeJS are currently maintained", opts);
notion-new-event.js
// Name: Create Notion Event/** @type {import("@johnlindquist/kit")} *//** @type {import("@notionhq/client")} */const { Client } = await npm("@notionhq/client");const eventName = await arg("Enter event name:");const date = await arg("Enter event date (YYYY-MM-DD):");const type = await arg("Enter event type:", ["Game", "Manga"]);const notion = new Client({ auth: process.env.NOTION_TOKEN });const database_id = process.env.NOTION_EVENT_DB;await notion.pages.create({parent: {database_id,},properties: {Name: {title: [{text: {content: eventName,},},],},Release: {date: {start: date,},},Type: {select: {name: type,},},},});
sleep-mac.js
// Menu: Sleep// Description: Put Mac into sleep modeapplescript('tell application "Finder" to sleep')
stock-price.js
// Shortcut: opt shift sconst { getCurrentPrice } = await npm("yahoo-stock-prices");let { say } = await kit("speech");let ticker = await arg("What stock do you want to check");const price = await getCurrentPrice(ticker.toUpperCase());say(`${ticker.toUpperCase()} is trading at $${price}`);
sync-scripts.js
// Menu: Sync Scripts// Description: Pull from backup scripts git repo & create shell scripts for ones that don't have one yet// Author: Benjamin Lannon// Twitter: @lannonbrexec('cd ~/.kenv/scripts && git pull origin main')await cli('create-all-bins')
tailwind-colors.js
let color = await arg(`Choose a color`, ["gray","red","yellow","green","blue","indigo","purple","pink",]);let mult = await arg(`Choose a multiple of 100`,`<div class="flex justify-center"><div class="w-10 h-10 text-${color}-100 flex items-center justify-center">100</div><div class="w-10 h-10 text-${color}-200 flex items-center justify-center">200</div><div class="w-10 h-10 text-${color}-300 flex items-center justify-center">300</div><div class="w-10 h-10 text-${color}-400 flex items-center justify-center">400</div><div class="w-10 h-10 text-${color}-500 flex items-center justify-center">500</div><div class="w-10 h-10 text-${color}-600 flex items-center justify-center">600</div><div class="w-10 h-10 text-${color}-700 flex items-center justify-center">700</div><div class="w-10 h-10 text-${color}-800 flex items-center justify-center">800</div><div class="w-10 h-10 text-${color}-900 flex items-center justify-center">900</div></div>`);let place = await arg("What are we styling", [{ name: "border", value: "border" },{ name: "text-color", value: "text" },{ name: "background", value: "bg" },]);copy(`${place}-${color}-${mult}`);
todoist-tasks.js
// Menu: Todoist Tasks// Description: View this week's tasks from Todoist// Author: Benjamin Lannon// Twitter: @lannonbr// Shortcut: opt t/** @type typeof import('todoist') */const todoistPackage = await npm("todoist");/** @type typeof import('dayjs') */const dayjs = await npm("dayjs");// API Token can be found here: https://todoist.com/prefs/integrationsconst token = await env("TODOIST_TOKEN");const client = todoistPackage.v8(token);await client.sync();let items = client.items.get();items = items.filter((item) => {let dueDate = dayjs(item.due.date);return dueDate.diff(dayjs(), "day") <= 7;}).sort((a, b) => {return dayjs(a.due.date).diff(dayjs(b.due.date));});await arg("View this week's tasks",items.map((item) => {return {name: item.content,description: `Due: ${item.due.date}`,};}));
twitter-validator.js
// Menu: Twitter Validator// Description: Open Twitter Opengraph image validator in default browser// Shortcut: opt shift texec("open https://cards-dev.twitter.com/validator");
unix-timestamp.js
// Menu: Unix Timestamp// Description: Copy current unix timestamp (in seconds) to clipboard// Shortcut: alt shift u/** @type typeof import('dayjs') */const dayjs = await npm('dayjs')await copy(dayjs().unix().toString())
uuid.js
// Menu: UUID// Description: Generate a v4 UUID and copy to clipboard// Shortcut: opt u// Author: Benjamin Lannon// Twitter: @lannonbrcopy(uuid())