Applescript - export Omnifocus tasks to Obsidian checklist (or kanban)

Hope this is the right place to post this.

This script

  • creates a new .md in Vault using project title from Omnifocus

  • appends task’s title as a checklist item to that .md

  • IF the Task in Omnifocus has a note (text only)

    • encloses the added task in [[]] wiki brackets
    • creates separate .md with name of task
    • adds Omni note text to that .md in Obsidian

    To convert into kanban use this plugin GitHub - mgmeyers/obsidian-kanban: Create markdown-backed Kanban boards in Obsidian. , and just “Insert template” above the checklist.

tell application "OmniFocus"
	tell front window
		set my_trees to selected trees of content
		
		## INSERT YOUR OBSIDIAN VAULT PATH HERE
		
		tell application "Finder" to open ("/Users/XXXX/DT Documents/Vault/" as POSIX file)
		
		repeat with i from 1 to count of my_trees
			set my_selection to value of item i of my_trees
			set task_name to name of my_selection
			set task_note to note of my_selection
			set project_id to containing project of my_selection
			set project_name to name of project_id
			
			
			try
				tell application "Finder" to set theLocation to (folder of the front window as alias)
			end try
			
			if task_note is not "" then tell application "TextEdit"
				
				## INSERT YOUR OBSIDIAN VAULT PATH HERE
				
				set n to "/Users/XXXX/DT Documents/Vault/" & task_name & ".md"
				close access (open for access n)
				write task_note to n as "utf8" starting at eof
				write " 
" to n as "utf8" starting at eof
			end tell
			
			tell application "TextEdit"
				
				## INSERT YOUR OBSIDIAN VAULT PATH HERE
				
				set f to "/Users/XXXX/DT Documents/Vault/" & project_name & ".md"
				close access (open for access f)
				
				
				if task_note is not "" then set task_name to "[[" & task_name & "]]"
				
				
				write "- [ ] " & task_name & " " to f as "utf8" starting at eof
				write " 
" to f as "utf8" starting at eof
				
			end tell
			
			
		end repeat
		
	end tell
	
	
	
end tell

6 Likes

I’ve taken the liberty to restructure what you have posted. The primary issue is that you are opening and closing the files in TextEdit when you should be making a new document and saving it. I’ve also moved the Obsidian vault reference to a top level so that users have one place to change it. Finally, I collapsed the structure to a sequence of what are called run handlers, each completing their own focused goal.

(*
generate Obsidian files from a selection of OmniFocus projects
originator: JD
modified: jjw
2021-08-05
-- select a set of projects in OmniFocus and run this script
--> output is a set of markdown task lists in your Obsidian vault
Caveats: this flattens task lists; action groups are not supported
*)

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

-- define your vault path here
property ObsidianVault : "/Volumes/Databases/Obsidian/> inbox"

property CheckBox : "- [ ] "

on run {}
	set theProjectList to my getSelectedProjectsfromOF()
	if theProjectList is {} then return
	set theTextList to my generateMDTexts(theProjectList)
	my putProjectListinObsidianVault(theTextList)
end run

on getSelectedProjectsfromOF()
	set theList to {}
	tell application "OmniFocus"
		try
			set my_trees to the value of selected trees of content of front window
		on error
			return theList
		end try
		repeat with the_Tree in my_trees
			set theprojectname to name of containing project of the_Tree
			set theprojectID to id of containing project of the_Tree
			set theprojectnote to note of the_Tree
			set thetasklist to tasks of the_Tree
			copy {projectname:theprojectname, projectID:theprojectID, projectnote:theprojectnote, tasklist:thetasklist} to end of theList
		end repeat
	end tell
	return theList
end getSelectedProjectsfromOF

on generateMDTexts(theList)
	set theTextList to {}
	set theTasks to ""
	repeat with theProject in theList
		set theProjectTitle to ("[[" & projectname of theProject & "]]") & return
		set theprojectnote to the projectnote of theProject & return
		repeat with theTask in tasklist of theProject
			set theTasks to theTasks & (CheckBox & name of theTask) & return
		end repeat
		set theText to theProjectTitle & theprojectnote & theTasks
		copy {projectname:projectname of theProject, itsText:theText} to the end of theTextList
	end repeat
	return theTextList
end generateMDTexts

on putProjectListinObsidianVault(theList)
	tell application "Finder" to set theFolderPath to POSIX file ObsidianVault as alias
	repeat with theProject in theList
		set theFileName to (ObsidianVault & "/" & (projectname of theProject) & ".md") as text
		tell application "TextEdit"
			activate
			set theDoc to make new document with properties {text:itsText of theProject}
			tell theDoc to save in POSIX file theFileName
			close front window
		end tell
	end repeat
end putProjectListinObsidianVault

Proposed Improvements Needed

  • I imagine that some changes are needed to the structure of the text that is supposed to be generated for the markdown file. I am not exactly sure here what is supposed to be enclosed in [[ ]] for example. This can be changed in the handler generateMDTexts.

  • Folks may also want to include additional information such as due dates, defer dates, and so on. The items can be added to the list in the getSelectedPropertiesfromOF handler and then added to the text output appropriately in the generateMDTexts handler.

I recommend getting ScriptDebugger if you are at all serious about continuing with AppleScript programming.

Hope you find the changes useful.


JJW

2 Likes

Wow thank you! Yes that’s all over my head at the moment.

I’ve tried to quit Omnifocus a few times now, but what keeps me around is the combination of privacy and quick capture (from the ios share menu or global shortcut on Mac - and of more than just text!)

I keep trying to design “quick capture” shortcuts for both ios and Mac to send everything to DEVONthink, but haven’t been able to make anything nearly as quick and reliable.

this is my solution to keep OF as the catch all bucket, Even though I want most of that info in DT / Obsidian

FWIW: I would like to build a plugin that keeps certain Obsidian files and OmniFocus projects in sync. I think it would be really neat to use Obsidian ^block ids as a UUID for tasks in OF, and then OF can be a viewer for tasks in Obsidian while your Obsidian vault remains the “source of truth” for your tasks.

It’ll be a while before I get to play with these ideas, though!

2 Likes

This is great, thanks.

This would be an awesome plugin!

1 Like

Even so, your end result will likely be posted long before I can even begin to understand the principles behind it.

Glad to have you take interest in this.


JJW

1 Like

What are the main draws to OF for you?

I stopped using it a couple of years ago, but in terms of this plugin idea, I think of it in terms of the Model-View-Controller concept: OF would be a great View, and sometimes Controller, for tasks I store (Model) in Obsidian.

Theoretically you could build a similar interface for viewing and editing tasks in Obsidian, but it’d be a lot of work!