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

7 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

5 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!

7 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!

1 Like

How to modify this script to just copy the outline to clipboard? (or open in new file in Drafts?)

I believe you might succeed by changing TextEdit to Drafts.

Otherwise, remove all write statements, simply append the collection of text to a string variable, and then put the final string variable on the clipboard.


JJW

1 Like

@ryanjamurphy
Where we at? :joy:

Let me know if any way can contribute or parts having trouble with, I’ve been working on this as well.

1 Like

Sorry for the delayed response! I have been playing with ways of building the features I like about OmniFocus directly in Obsidian instead of trying to maintain a bridge between the two apps.

I now have ways of setting review and do dates for items in Obsidian and managing those using Dataview tables. It is working fairly well, though it isn’t shareable yet.

I’m REALLY looking forward to seeing the result of your efforts to build OmniFocus functionality into Obsidian.

I continue to look for ways to integrate my use of Obsidian, Omnifocus and DEVONthink, but with limited success. (I.e. functioning prototype, but still far too fussy, requires too much human intervention.)

I’m I correct to assume that you are making use of individual (atomic) notes as the basis for tasks (or at least mini-projects)? And then using dataview or dataviewjs to

  • create projects / mini-projects ?
  • create tasks within the projects (e.g. with Button plugin) ?
  • modifying existing projects/tasks using automation in situ (e.g. with MetaEdit plugin)?

Sorry for the delayed response. I aim to write up what I’m doing when it stabilizes (getting there, believe it or not). In the meantime, to answer briefly…

  • Not a lot of what I do is template-able. So I rarely use templates. My tasks are just lines starting with - [ ] . I try to be descriptive, and I have certain keywords like " Waiting for " that provide some inline “metadata”.
  • I tend to keep special “project notes” to track tasks on things like “stop the basement from flooding.” Those will contain tasks and, well, notes, on whatever the project is. I try not to overorganize these.
  • I keep track of everything with a Kanban board, some metadata, and a few dataview tricks.
    • I have a dataview search to show me projects that aren’t on the kanban board (untracked projects)
    • I keep review dates in project metadata, and I have dataview searches to show me e.g., things that are up for review today, or are overdue for a review.
  • The kanban board is composed of Status columns. When I move something from one column to another, it updates the Status metadata (via the Metaedit Kanban Helper integration).
  • I have a metadata next action key which is actually a one-line dataview thing—it shows me the next action, as in the first action to be found in the note, for the note. I reveal that on the Kanban and in dataview searches.

As is probably obvious, this requires a little bit of set up, hence why I haven’t shared it in full—writing it all up will take bandwidth I don’t have at the moment. I’m happy to try to answer specific questions if anyone has any!

1 Like

I’m very eager to see what you create!
Personally, I’m migrating more and more to Notion. I know it’s not in the spirit of all the things we love about Obsidian but… an example of “bandwidth” usage:

I’m growing lots of veggies & flowers. But starting seeds indoors is somehow incredibly challenging so I do a lot of experiments & take a lot of notes.

In obsidian each experiment is a dated note, with metadata, maybe with a picture attached, all organized by dataview. Not a huge project setting it up but definitely a half hour here and there to arranging the fields, fussing with dataview code, etc.

Of course every modification to the metadata fields means finding the corresponding formula and updating it too… remember where each dataviews lives, click into the code, keep your glossary handy…

Not my first time setting up something like that, but probably a Couple hours total, and I’m left w something difficult to update (re metadata fields for example).

how long would this take me in Notion:thinking:

I recreated the entire system in one trip to the toilet. :face_with_hand_over_mouth:
On an iPhone.
Writing this post took me longer.

Tap add page
Tap add database
Tap to add a few fields, drag them to where I want to see them…

3 Likes

Not actively using Obsidian, are other Kanban targets feasible? for example Trello.

I say “feasible” as I’m not necessarily asking anyone to build me this.

OT – I use this shortcut to put the tasks from the OF Forecast perspective onto the clipboard as markdown links. I call this shortcut with a Typinator expansion (.daily) that builds the content of my daily note by running this OF shortcut and other automation to gather info needed to start the day.

1 Like

I have set up Kanbans in Curio. The setup requires that you administer the cards manually. The connections between OmniFocus and Curio cards are handled through AppleScript.


JJW

1 Like