user@argobox:~/journal/2024-05-18-the-vault-that-opens-itself
$ cat entry.md

The Vault That Opens Itself

○ NOT REVIEWED

The Vault That Opens Itself

Date: May 18, 2024 Issue: Daily notes don’t create themselves Solution: Bash script + URI scheme + cron Result: Notes exist by the time I arrive


The Problem

Obsidian’s daily notes are powerful, but they require you to be there. Open Obsidian, click the daily note button, template applies, note exists.

What if I’m not at the computer at midnight? What if I want the note to exist before I wake up?

Manual creation defeats the purpose. I wanted automation.


The Templater Issue

Templater can auto-create notes on file creation. But it needs Obsidian running. If Obsidian isn’t open, Templater isn’t processing.

And running Obsidian 24/7 in the background? No thanks.


The Solution: URI Scheme

Obsidian has a URI scheme: obsidian://

This lets external programs interact with the vault:

# Open a specific note
obsidian://open?vault=MyVault&file=Daily/2024-05-18

# Create a new note
obsidian://new?vault=MyVault&file=Daily/2024-05-18

The new action creates the file if it doesn’t exist. And if Obsidian is configured with a template for that folder, the template applies.


The Script

#!/bin/bash
# create-daily-note.sh

VAULT="Vault"
DATE=$(date +%Y-%m-%d)
YEAR=$(date +%Y)
MONTH=$(date +%m)

# The file path within the vault
FILE="Daily/${YEAR}/${MONTH}/${DATE}"

# Check if file already exists
VAULT_PATH="$HOME/Documents/Obsidian/${VAULT}"
FULL_PATH="${VAULT_PATH}/${FILE}.md"

if [ -f "$FULL_PATH" ]; then
    echo "Daily note already exists: $DATE"
    exit 0
fi

# Trigger Obsidian to create the note
xdg-open "obsidian://new?vault=${VAULT}&file=${FILE}" 2>/dev/null

echo "Created daily note: $DATE"

The xdg-open command passes the URI to the system. The system knows Obsidian handles obsidian:// URIs.


The Cron Job

crontab -e
# Create daily note at midnight
0 0 * * * /home/argo/scripts/create-daily-note.sh >> /home/argo/logs/daily-note.log 2>&1

# Also create at 6am in case midnight failed
0 6 * * * /home/argo/scripts/create-daily-note.sh >> /home/argo/logs/daily-note.log 2>&1

Midnight run catches the day change. 6am run is backup in case the system was off at midnight.


The Headless Problem

The script works when I’m logged into a desktop session. But what if the machine is running headless? No display, no xdg-open.

Solution: Create the file directly, including template content:

#!/bin/bash
# create-daily-note-headless.sh

VAULT_PATH="$HOME/Documents/Obsidian/Vault"
TEMPLATE_PATH="${VAULT_PATH}/Templates/Daily Note.md"
DATE=$(date +%Y-%m-%d)
YEAR=$(date +%Y)
MONTH=$(date +%m)
DAY_NAME=$(date +%A)
FULL_DATE=$(date +"%B %d, %Y")

OUTPUT_DIR="${VAULT_PATH}/Daily/${YEAR}/${MONTH}"
OUTPUT_FILE="${OUTPUT_DIR}/${DATE}.md"

# Create directory if needed
mkdir -p "$OUTPUT_DIR"

# Skip if exists
if [ -f "$OUTPUT_FILE" ]; then
    exit 0
fi

# Read template and replace variables
cat "$TEMPLATE_PATH" | \
    sed "s/{{date}}/${DATE}/g" | \
    sed "s/{{day}}/${DAY_NAME}/g" | \
    sed "s/{{fulldate}}/${FULL_DATE}/g" \
    > "$OUTPUT_FILE"

echo "Created: $OUTPUT_FILE"

This bypasses Obsidian entirely. Pure file creation. Template variables processed by sed.


The Template Variables

Templater uses <% tp.date.now() %>. But if we’re creating files without Obsidian, we need simpler placeholders:

---
date: {{date}}
day: {{day}}
---

# {{fulldate}}

## Goals
- [ ]

## Notes


## End of Day

The bash script replaces {{date}}, {{day}}, and {{fulldate}} before writing.


The Result

Every morning, the daily note exists. Whether I was at the computer or not. Whether Obsidian was open or not.

The note is there, waiting, with the template applied, ready for my thoughts.


What I Learned

URI schemes are APIs. Obsidian’s obsidian:// is a way for external tools to interact with the vault.

Cron is reliable. It runs whether you’re logged in or not. Perfect for maintenance tasks.

Have a fallback. The headless script works when the URI scheme doesn’t. Belt and suspenders.

Templates are just text. When Templater isn’t available, sed works fine for simple replacements.


The best automation is the kind you forget exists. Until you realize your notes have been creating themselves for months.