Automating Obsidian with OpenBSD
I'm trying something new with my Weeknotes, where I'm recording a daily note in Obsidian and then reviewing those notes at the end of the week to craft a weekly post. The idea is to sift through random notes and distill to a few solid paragraphs. In the end it becomes less of a bullet point list and more reflection.
I'm already using Obsidian's Daily Notes Core Plugin to automate creating these daily notes. I have a basic template set up and Obsidian creates a new note that ends up with a filename along the lines of W16 Monday April 16 2026.md
(this is important to my automation setup below).
There are various community plugins that accomplish some form of automation, but what I'm looking to do - inspired by Jamie Todd Rubin's post, "Practically Paperless with Obsidian, Episode 22: Daily Notes Revisited" - seems like it could be accomplished with a simple script that could be automated.
And, I have a handy place to store said automated script: my OpenBSD server. This whole endeavour is made possible thanks to setting up Syncthing on the server.
Full disclosure, I relied entirely on ChatGPT to get this done. However, it was incredibly simple to follow along so I understand a little bit of what's going on. I haven't included my verbatim chat but any code you see here comes unedited from ChatGPT.
The Instructions
Before I got started with trying to write a script, I realized I needed to make clear what it is I want to do. At the simplest level, I want to append a note with a string of text every day. Of course, it's slightly more complicated than that.
To be more specific, I want a weekly review file that lists my daily notes in order, in one sheet. One option would be to combine the .md
files, but the simplest method is to use Obsidian's built-in file embed:
![[15 Sunday April 13 2025]]
This yields something like this:
So from this you might see where I'm going:
- create a file every week (call it
W{week} Review.md
) on Monday at00:00 UTC-4
e.g.W16 Review.md
- Append with a link to the previous day's daily note (
![[{week} {day of week} {month} {DD}{yyyy}.md]]
- e.g.![[16 Monday April 14 2025]]
) at00:00 UTC-4
the following day
That's it. Something I could easily do myself (there is an icon in the command toolbar devoted to this), but I don't need to look at the review file until the end of the week.
I needed to tell ChatGPT where to find my files, so I gave it the filepath info. My Obsidian vault lives in /mnt/Obsidian/Infosphere/
and I have various subfolders there the scripts refer to.
The Scripts
I wanted to start simple, mainly to ensure my request was even possible. I asked ChatGPT for a script to create a .txt
file and append a different string every time it runs. For simplicity I said to just use Day 1
through Day 7
. The scripts are simple shell scripts - I'm not familiar with the language yet, but it looks easy to parse.
#!/bin/sh
# File to append to
FILE="/mnt/Obsidian/Infosphere/daily_log.txt"
# File to track the current day count
STATE_FILE="/mnt/Scripts/day_counter.txt"
# Initialize state file if it doesn't exist
if [ ! -f "$STATE_FILE" ]; then
echo 1 > "$STATE_FILE"
fi
# Read current day count
DAY=$(cat "$STATE_FILE")
# Append text to the file
echo "Day $DAY" >> "$FILE"
# Increment day (reset to 1 if > 7)
NEXT_DAY=$((DAY + 1))
if [ "$NEXT_DAY" -gt 7 ]; then
NEXT_DAY=1
fi
# Save next day count
echo "$NEXT_DAY" > "$STATE_FILE"
I had to also make sure the script had appropriate permissions to run:
chmod +x /mnt/Scripts/append_day.sh
With that done I ran the script to test it:
doas /mnt/Scripts/append_day.sh
A quick side note - the folder I created was a lower case scripts
but I guess something on the Syncthing side switched it to Scripts
? Not sure. I'm going with it.
Because I have Syncthing set up I was able to flip over to Windows Explorer and check my Infosphere folder right away and verify the file was created. It was, and running the script a second time appended the file. Great! I asked ChatGPT to re-write the script following the parameters I outlined above.
I did some further tests using .md
files and verified they showed up correctly in Obsidian before moving on. All was good here.
Because I need two actions - creating the weekly file, and amending the weekly file - I needed two scripts.
Script 1
#!/bin/sh
# Get ISO week number
WEEK_NUM=$(date +%V)
# Construct file path
FILE_PATH="/mnt/Obsidian/Infosphere/srgower.com/W${WEEK_NUM} Review.md"
# Create file if it doesn't exist
if [ ! -f "$FILE_PATH" ]; then
touch "$FILE_PATH"
fi
Some explanation of what's happening here is necessary. I'm using ISO Week standards for the week number. There's also a file check at the start. If it doesn't exist, the script will create a new file following that format. For example, next week's file will be W17 Review.md
. Super simple. I saved this as create_weekly_review.sh
and modified permissions again (with chmod +x
).
Script 2
This one is saved as append_daily_to_review.sh
and as the filename suggests, appends the text string to the review file.
#!/bin/sh
# Get ISO week number
WEEK_NUM=$(date +%V)
# Construct review file path
REVIEW_FILE="/mnt/Obsidian/Infosphere/srgower.com/W${WEEK_NUM} Review.md"
# Exit if the file doesn't exist (e.g. in case Monday script failed)
if [ ! -f "$REVIEW_FILE" ]; then
exit 1
fi
# Get full date parts
DAY_NAME=$(date +%A)
MONTH_NAME=$(date +%B)
DAY_NUM=$(date +%e | sed 's/ //g')
YEAR=$(date +%Y)
# Build daily filename
DAILY_FILENAME="${WEEK_NUM} ${DAY_NAME} ${MONTH_NAME} ${DAY_NUM} ${YEAR}"
# Build link
APPEND_STRING="![[${DAILY_FILENAME}]]"
# Append to weekly review file
echo "$APPEND_STRING" >> "$REVIEW_FILE"
One thing this script does is check if the weekly review file exists, and if not (if the Monday morning script failed), it will exit and therefore not append the file. chmod
again.
I'm not familiar with this bit of code: (date +%e | sed 's/ //g')
- I will research that at a later time.
Next is to automate running the scripts, which is done with a CRON job; I haven't done this before, although I have set up GitHub automations that use similar setups.
CRON Job
ChatGPT gave me the option of setting my system time to Eastern or convert to UTC; since I assumed I needed to convert anyway I opted to skip setting the system time zone. Working with UTC is fine.
ChatGPT wanted me to edit crontab
with vi
, but I'm not at all a fan of vi
so I told it to give me the instructions using mg
(which I'm familiar with from Sylvia's guides).
export VISUAL=mg && crontab -e
And enter this code:
# Every Monday at 12:00 AM Eastern (04:00 UTC) - Create weekly review
0 4 * * 1 /mnt/Scripts/create_weekly_review.sh
# Every day except Monday at 12:00 AM Eastern (04:00 UTC) - Append daily link
0 4 * * 2-7 /mnt/Scripts/append_daily_to_review.sh
I'm not well-versed in cronjob formatting so I looked up what the numbers mean. I know that at least the last number refers to the weekday, but not 100% sure of the others. You can read more here but here's what my specific example means:
0 - Minutes - in this case, zero.
4 - Hour(0-23) - 04
So we're running this job at 04:00 (UTC).
* - Day of month (1-31) - any day
* - Month (1-12) - any month
1 - Day of week (1-7) - Monday
And running on Monday, regardless of day or month. If I wanted it to run at 12:30am I'd use 30 4 * * 1
.
"You should see a message like crontab: installing new crontab
—that means it worked!" (From ChatGPT) I got that message, so we're good.
So now my crontab
contains these two commands that will run my shell scripts on a daily and weekly basis.
I didn't add error logging or anything - I'm going to live dangerously and find out if it works tomorrow.
It did not work. I got an email notification with this message:
/mnt/Scripts/append_daily_to_review.sh[27]: cannot create /mnt/Obsidian/Infosphere/srgower.com/W16 Review.md: Permission denied
This was at 12am this morning; so technically it did work in that the cronjob tried to execute the script, but did not have the proper permissions to write to the folders.
I did some troubleshooting and the solution was to add doas
to the cronjob. At this point ChatGPT also suggested adding logging, so I threw that in as well.
# Append daily note to weekly review at 12:00 AM Eastern (04:00 UTC), Tuesday through Sunday
0 4 * * 2-7 doas /mnt/Scripts/append_daily_to_review.sh >> /tmp/append_daily.log 2>&1
# Create weekly review file at 12:00 AM Eastern (04:00 UTC), Monday
0 4 * * 1 doas /mnt/Scripts/create_weekly_review.sh
I didn't want to wait until midnight Wednesday to see if it worked so I temporarily modified the cronjob to 22 16 * * 2-7
(run at 12:22PM Eastern) to check if that solved it.
It worked and appended the file, so I changed the cronjob back to 0 4 * * 2-7
. I noticed the script added a line before the new text string, so I may need to adjust that later.
Modification to Weekly Script
I decided I wanted to include YAML information to save me from doing it manually after the file is created. After all, if I'm automating it this far, I may as well go further! I gave ChatGPT the YAML info I wanted added, and it spat out the revised script. I further added an extra piece I wanted to embed that I changed after I started working on this project.
#!/bin/sh
# Get ISO week number
WEEK_NUM=$(date +%V)
# Construct file path and filename
FILE_PATH="/mnt/Obsidian/Infosphere/srgower.com/W${WEEK_NUM} Review.md"
# Only create the file if it doesn't exist
if [ ! -f "$FILE_PATH" ]; then
{
# Add YAML front matter
echo "---"
echo "tags:"
echo " - Weeknotes"
echo "---"
echo ""
echo "![[Things I Made this Week]]"
echo ""
} > "$FILE_PATH"
fi
Conclusion
This was a surprisingly easy process, and I'm amazed how simple shell scripts can be. The next thing I wanted to automate was renewing my SSL certificates, but I skimmed over the part of Derek's server guide that provided a crontab entry to do it automatically:
(crontab -1 2>/dev/null; echo "11\t3\t*\t5\tacmr-client $domain && rcctl reload relayd") crontab -
Looks like I can just add that to the crontab without issue (just the part in the echo
command). However that doesn't seem to be a valid setup so I'll fix that later.
Update: As I was re-reading through my post to check for missed errors, I had the realization that I'm running my CRONJOB at the wrong time. By running it at 00:00 UTC-4
I'm inserting today's daily note instead of yesterday's daily note. Rather than changing the script I think the simplest thing to do will be to change the CRONJOB to run at 23:59 UTC-4
(the full change will be 59 3 * * *
).
Update 2: It's a little more complicated than that. In double-checking my work with ChatGPT, it made me realize that 59 3 * * *
will only work until November, at which point I'd need to manually change it to account for end of DST. I worked out a script with it to create something that will check every hour if it's 23:59 Eastern; if it is, it will run my append script, otherwise it'll do nothing. If you were counting I'm at 3 scripts now, and one of them doesn't do much more than check to see what time it is to figure out if it should run the other script or not.
No change to the cronjob to create the weekly review file - that still occurs on Mondays at 00:00.
Update 3: I'm probably overthinking it, maybe it doesn't matter what time it runs? I might change things up again later.
Reply by email Share this post
Or if you prefer, find me on Mastodon. And there's also Bluesky!