So, I'm using Sketchybar on my office laptop for a while and I wanted a way to have a quick view of my next meeting incoming for the current day.

Get the meetings
As you may know, Sketchybar is based on bash script, so I needed a tool that expose the data.
After some research, I found meeting bar, combined with Apple Shortcut I can format a JSON with the informations I need.

Then in the terminal, you can run the command :
shortcuts run "Get Nearest Event Details"
Use the data
I'm not a bash expert so I chose a convenient method for me using bun.sh. I wrote a small script in TypeScript and created a single-file executable that will be executed by sketchybar !
First, I run the command by spawning it :
type nextEvent = {
title: string;
start: string;
end: string;
link: string;
};
const proc = Bun.spawn(["shortcuts", "run", "Get Nearest Event Details"]);
const nextEvent: nextEvent = await new Response(proc.stdout).json();
Then I check if the title is empty, meaning there are no meetings in the future. It's a personal choice but I prefer to avoid empty blocks to keep it readable.
if (nextEvent.title === "") {
Bun.spawn([
"sketchybar",
"--set",
"meeting",
"label.drawing=off",
"icon.drawing=off",
]);
}
Next, we can handle the display of our meeting. I chose 2 styles of display, emphasizing :
- the title when the meeting is in progress
- the hour when it's coming
I used date-fns to do the date check in order to keep it clear and maintainable. I also shrinked the size of the title to avoid some UI surprise when the title is quite long.
if ...
else if (isBefore(now, nextEvent.start)) {
Bun.spawn([
"sketchybar",
"--set",
"meeting",
"label.drawing=on",
"icon.drawing=on",
`label=${nextEvent.title.slice(0, 60)}`,
`icon=${format(nextEvent.start, "HH'h'mm")}`,
"icon.background.height=26",
`icon.background.color=${FLAMINGO}`,
"icon.font.size=14.0",
"icon.padding_right=8",
"icon.padding_left=8",
`icon.color=${BASE}`,
"icon.background.corner_radius=2",
"label.background.corner_radius=2",
"label.background.height=24",
"label.padding_left=8",
"label.padding_right=8",
`label.background.color=${SURFACE}`,
`label.color=${WHITE}`,
`click_script=open ${nextEvent.link}`,
]);
} else {
Bun.spawn([
"sketchybar",
"--set",
"meeting",
"label.drawing=on",
"icon.drawing=off",
`label=${nextEvent.title.slice(0, 60)}`,
"label.padding_left=8",
`label.color=${BASE}`,
`label.background.color=${FLAMINGO}`,
"label.background.height=24",
"label.background.corner_radius=4",
"label.font.size=14.0",
`click_script=open ${nextEvent.link}`,
]);
}
Here you can find the color I used :
const WHITE = "0xffffffff";
const FLAMINGO = "0xFFf2cdcd"; // #f2cdcd
const BASE = "0xe61e1e2e"; // #1e1e2e
const SURFACE = "0x9c623b20"; // #313244
Create and use the executable
Creating an executable with Bun is straighforward, just by running a command you will have an executable binary for your platform :
bun build ./index.ts --compile --outfile getnextmeeting
Now our executable is ready, we can give it to sketchybar !
I created a file meeting.sh
as I like to separate concerns but you can append it to the skechybarrc
file of course :
#!/bin/bash
sketchybar --add item meeting center \
--set meeting update_freq=30 \
script="$PLUGIN_DIR/meeting/getnextmeeting"