Apple Notes Core Workflow A — Note Management Automation
Overview
Primary workflow: automate Apple Notes management with batch creation, template-based note generation, folder organization, and content sync from external sources (Markdown files, RSS, calendar events).
Instructions
Step 1: Batch Note Creator from Markdown Files
#!/bin/bash
# scripts/markdown-to-notes.sh — Import Markdown files as Apple Notes
FOLDER_NAME="${1:-Imported}"
for md_file in *.md; do
[ -f "$md_file" ] || continue
title=$(head -1 "$md_file" | sed 's/^#\s*//')
# Convert Markdown to basic HTML
body=$(cat "$md_file" | sed 's/^# /<h1>/;s/$/<\/h1>/' | sed 's/^## /<h2>/;s/$/<\/h2>/' | sed 's/^- /<li>/;s/$/<\/li>/' | sed 's/^$/<br>/')
osascript -l JavaScript -e "
const Notes = Application('Notes');
const account = Notes.defaultAccount;
let folder = account.folders().find(f => f.name() === '$FOLDER_NAME');
if (!folder) {
folder = Notes.Folder({ name: '$FOLDER_NAME' });
account.folders.push(folder);
}
const note = Notes.Note({ name: '$title', body: \`$body\` });
folder.notes.push(note);
'Created: $title';
"
echo "Imported: $md_file → $title"
done
Step 2: Note Template Engine (JXA)
// scripts/note-template.js — Run with: osascript -l JavaScript scripts/note-template.js
const Notes = Application('Notes');
const TEMPLATES = {
meeting: (data) => `
<h1>${data.title || 'Meeting Notes'}</h1>
<p><strong>Date:</strong> ${new Date().toLocaleDateString()}</p>
<p><strong>Attendees:</strong> ${data.attendees || 'TBD'}</p>
<h2>Agenda</h2><ul><li></li></ul>
<h2>Action Items</h2><ul><li></li></ul>
<h2>Notes</h2><p></p>
`,
daily: (data) => `
<h1>Daily Log — ${new Date().toLocaleDateString()}</h1>
<h2>Tasks</h2><ul><li></li></ul>
<h2>Accomplishments</h2><ul><li></li></ul>
<h2>Blockers</h2><ul><li></li></ul>
`,
project: (data) => `
<h1>${data.title || 'Project'}</h1>
<p><strong>Status:</strong> ${data.status || 'Active'}</p>
<h2>Overview</h2><p></p>
<h2>Requirements</h2><ul><li></li></ul>
<h2>Timeline</h2><ul><li></li></ul>
`,
};
function createFromTemplate(templateName, data, folderName) {
const template = TEMPLATES[templateName];
if (!template) throw new Error(`Unknown template: ${templateName}`);
const account = Notes.defaultAccount;
let folder = account.folders().find(f => f.name() === folderName);
if (!folder) {
folder = Notes.Folder({ name: folderName });
account.folders.push(folder);
}
const body = template(data);
const note = Notes.Note({ name: data.title || templateName, body });
folder.notes.push(note);
return note.id();
}
// Usage: create meeting notes
createFromTemplate('meeting', {
title: 'Sprint Planning',
attendees: 'Team Alpha',
}, 'Meetings');
Step 3: Folder Organization Script
# Organize notes into folders based on naming conventions
osascript -l JavaScript -e '
const Notes = Application("Notes");
const account = Notes.defaultAccount;
const allNotes = account.notes();
const rules = [
{ pattern: /^Meeting:/i, folder: "Meetings" },
{ pattern: /^Project:/i, folder: "Projects" },
{ pattern: /^Daily/i, folder: "Daily Logs" },
{ pattern: /^TODO/i, folder: "Tasks" },
];
let moved = 0;
for (const note of allNotes) {
const name = note.name();
for (const rule of rules) {
if (rule.pattern.test(name)) {
let folder = account.folders().find(f => f.name() === rule.folder);
if (!folder) {
folder = Notes.Folder({ name: rule.folder });
account.folders.push(folder);
}
Notes.move(note, { to: folder });
moved++;
break;
}
}
}
`Organized ${moved} notes into folders`;
'
Output
- Batch Markdown file → Apple Notes importer
- Template engine with meeting/daily/project templates
- Rule-based folder organization
- Folder creation on-demand
Error Handling
| Error |
Cause |
Solution |
Can't move note |
Note is locked |
Unlock note in Notes.app first |
| HTML rendering issues |
Invalid HTML tags |
Use basic tags: h1, h2, p, ul, li, strong |
| Slow batch import |
iCloud sync throttling |
Add 1s delay between note creates |
| Duplicate notes |
Script run twice |
Check for existing note by name before creating |
Resources
Next Steps
For exporting and converting notes, see apple-notes-core-workflow-b.
1---2name: apple-notes-core-workflow-a3description: |4 Build automated note management workflows with Apple Notes JXA scripts.5 Use when batch-creating notes, syncing content from external sources,6 organizing notes into folder hierarchies, or building note templates.7 Trigger: "apple notes workflow", "batch notes", "note templates",8 "organize apple notes", "sync notes".9allowed-tools: Read, Write, Edit, Bash(osascript:*), Bash(node:*), Grep10version: 1.0.011license: MIT12author: Jeremy Longshore <jeremy@intentsolutions.io>13tags: [saas, macos, apple-notes, automation, workflow]14compatible-with: claude-code15---1617# Apple Notes Core Workflow A — Note Management Automation1819## Overview2021Primary workflow: automate Apple Notes management with batch creation, template-based note generation, folder organization, and content sync from external sources (Markdown files, RSS, calendar events).2223## Instructions2425### Step 1: Batch Note Creator from Markdown Files2627```bash28#!/bin/bash29# scripts/markdown-to-notes.sh — Import Markdown files as Apple Notes3031FOLDER_NAME="${1:-Imported}"3233for md_file in *.md; do34 [ -f "$md_file" ] || continue35 title=$(head -1 "$md_file" | sed 's/^#\s*//')36 # Convert Markdown to basic HTML37 body=$(cat "$md_file" | sed 's/^# /<h1>/;s/$/<\/h1>/' | sed 's/^## /<h2>/;s/$/<\/h2>/' | sed 's/^- /<li>/;s/$/<\/li>/' | sed 's/^$/<br>/')3839 osascript -l JavaScript -e "40 const Notes = Application('Notes');41 const account = Notes.defaultAccount;42 let folder = account.folders().find(f => f.name() === '$FOLDER_NAME');43 if (!folder) {44 folder = Notes.Folder({ name: '$FOLDER_NAME' });45 account.folders.push(folder);46 }47 const note = Notes.Note({ name: '$title', body: \`$body\` });48 folder.notes.push(note);49 'Created: $title';50 "51 echo "Imported: $md_file → $title"52done53```5455### Step 2: Note Template Engine (JXA)5657```javascript58// scripts/note-template.js — Run with: osascript -l JavaScript scripts/note-template.js59const Notes = Application('Notes');6061const TEMPLATES = {62 meeting: (data) => `63 <h1>${data.title || 'Meeting Notes'}</h1>64 <p><strong>Date:</strong> ${new Date().toLocaleDateString()}</p>65 <p><strong>Attendees:</strong> ${data.attendees || 'TBD'}</p>66 <h2>Agenda</h2><ul><li></li></ul>67 <h2>Action Items</h2><ul><li></li></ul>68 <h2>Notes</h2><p></p>69 `,70 daily: (data) => `71 <h1>Daily Log — ${new Date().toLocaleDateString()}</h1>72 <h2>Tasks</h2><ul><li></li></ul>73 <h2>Accomplishments</h2><ul><li></li></ul>74 <h2>Blockers</h2><ul><li></li></ul>75 `,76 project: (data) => `77 <h1>${data.title || 'Project'}</h1>78 <p><strong>Status:</strong> ${data.status || 'Active'}</p>79 <h2>Overview</h2><p></p>80 <h2>Requirements</h2><ul><li></li></ul>81 <h2>Timeline</h2><ul><li></li></ul>82 `,83};8485function createFromTemplate(templateName, data, folderName) {86 const template = TEMPLATES[templateName];87 if (!template) throw new Error(`Unknown template: ${templateName}`);8889 const account = Notes.defaultAccount;90 let folder = account.folders().find(f => f.name() === folderName);91 if (!folder) {92 folder = Notes.Folder({ name: folderName });93 account.folders.push(folder);94 }9596 const body = template(data);97 const note = Notes.Note({ name: data.title || templateName, body });98 folder.notes.push(note);99 return note.id();100}101102// Usage: create meeting notes103createFromTemplate('meeting', {104 title: 'Sprint Planning',105 attendees: 'Team Alpha',106}, 'Meetings');107```108109### Step 3: Folder Organization Script110111```bash112# Organize notes into folders based on naming conventions113osascript -l JavaScript -e '114 const Notes = Application("Notes");115 const account = Notes.defaultAccount;116 const allNotes = account.notes();117118 const rules = [119 { pattern: /^Meeting:/i, folder: "Meetings" },120 { pattern: /^Project:/i, folder: "Projects" },121 { pattern: /^Daily/i, folder: "Daily Logs" },122 { pattern: /^TODO/i, folder: "Tasks" },123 ];124125 let moved = 0;126 for (const note of allNotes) {127 const name = note.name();128 for (const rule of rules) {129 if (rule.pattern.test(name)) {130 let folder = account.folders().find(f => f.name() === rule.folder);131 if (!folder) {132 folder = Notes.Folder({ name: rule.folder });133 account.folders.push(folder);134 }135 Notes.move(note, { to: folder });136 moved++;137 break;138 }139 }140 }141 `Organized ${moved} notes into folders`;142'143```144145## Output146147- Batch Markdown file → Apple Notes importer148- Template engine with meeting/daily/project templates149- Rule-based folder organization150- Folder creation on-demand151152## Error Handling153154| Error | Cause | Solution |155|-------|-------|----------|156| `Can't move note` | Note is locked | Unlock note in Notes.app first |157| HTML rendering issues | Invalid HTML tags | Use basic tags: h1, h2, p, ul, li, strong |158| Slow batch import | iCloud sync throttling | Add 1s delay between note creates |159| Duplicate notes | Script run twice | Check for existing note by name before creating |160161## Resources162163- [AppleScript Notes Guide](https://www.macosxautomation.com/applescript/notes/)164- [JXA Examples](https://jxa-examples.akjems.com/)165166## Next Steps167168For exporting and converting notes, see `apple-notes-core-workflow-b`.169