Integrating Omnifocus 2 with Devonthink Pro (Rob Trew scripts)

I’m working through adding this to my system, but I’m having trouble trying to get KM to recognise the area of the OF note to activate a switch to either DevonThink or OmniOutliner.

It seems that KM just can’t ‘see’ the text image to be able to activate the click action.

I’ve tried taking my own screenshot and replacing the built-in as well as mucking around with fuzziness, but it’s not working.

Any ideas?

To respond to my own thread to help others; I discovered that I had to recreate the screenshots of the text in KM - I think my font must have been different.

I also went into System Preferences and toggled the reduce transparency setting to prevent colour bleed - although not sure this has any impact, to be honest.

Now, though, with my own screenshot, the text is recognised consistently and the script works.

I used the Rob Trew versions back in OF1 days, and it’s nice to have them back again!

If you like, I am leaving here two scripts I wrote in JXA to open DT link and OO link

Usage:

  • Select a project
  • Run script (or use a KM Execute Javascript Action)

P.S.: In one of the above posts, there is an AppleScript version.

(() => {
	// Data List JS ----------------------------------------------------------

	// bindMay (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
	const bindMay = (mb, mf) =>
		mb.nothing ? mb : mf(mb.just);

	// just :: a -> Just a
	const just = x => ({
		nothing: false,
		just: x
	});

	// nothing :: () -> Nothing
	const nothing = (optionalMsg) => ({
		nothing: true,
		msg: optionalMsg
	});

	// OF Functions -----------------------------------
	
	// projectMay :: Window -> Maybe Project
	const projectMay = win => {
		const seln = win.content.selectedTrees.value();
		return seln.length > 0 ?
			(Object.keys(seln[0].properties()).includes('reviewInterval')) ?
			just(seln[0]) : nothing('No projects selected') :
			nothing('No selection')
	}
	
	// linkMay :: OF Project -> URL String
	const linkMay = x => {
		try {
			return {
				nothing: false,
				just: x.note.paragraphs[0].style.attributes['link'].value()
			};
		} catch (e) {
			return {
				nothing: true,
				msg: 'No link in note'
			};
		}
	};

	// groupMay :: URL String -> maybe DT record
	const groupMay = x => {
		const strUUID = x.split('//')[1]
		return dt.getRecordWithUuid(strUUID) == null ?
			nothing('') :
			just(x)
	};

	// MAIN
	const
		ca = Application.currentApplication(),
		sa = (ca.includeStandardAdditions = true, ca),
		dt = Application('DEVONthink Pro'),
		of = Application('OmniFocus'),
		oDoc = of.defaultDocument,
		oWin = oDoc.documentWindows[0];
		
	const mb = bindMay(bindMay(projectMay(oWin), linkMay), groupMay)
	return (mb.nothing) ? mb.msg : ca.openLocation(mb.just)
})();
Open OO Link Code
(() => {
    // Data List JS ----------------------------------------------------------

    // bindMay (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
    const bindMay = (mb, mf) =>
        mb.nothing ? mb : mf(mb.just);

    // Data List JS ----------------------------------------------------------

    // just :: a -> Just a
    const just = x => ({
        nothing: false,
        just: x
    });

    // nothing :: () -> Nothing
    const nothing = (optionalMsg) => ({
        nothing: true,
        msg: optionalMsg
    });
    // OF Functions -----------------------------------
    
    // projectMay :: Window -> Maybe Project
    const projectMay = win => {
        const seln = win.content.selectedTrees.value();
        return seln.length > 0 ?
            (Object.keys(seln[0].properties()).includes('reviewInterval')) ?
            just(seln[0]) : nothing('No projects selected') :
            nothing('No selection')
    }
    
    // linkMay :: OF Project -> URL String
    const linkMay = x => {
        try {
            return {
                nothing: false,
                just: x.note.paragraphs[2].style.attributes['link'].value()
            };
        } catch (e) {
            return {
                nothing: true,
                msg: 'No link in note'
            };
        }
    };

    // groupMay :: URL String -> maybe DT record
    const groupMay = x => {
        const strUUID = x.split('//')[1]
        return dt.getRecordWithUuid(strUUID) == null ?
            nothing('') :
            just(x)
    };

    // MAIN
    const
        ca = Application.currentApplication(),
        sa = (ca.includeStandardAdditions = true, ca),
        dt = Application('DEVONthink Pro'),
        of = Application('OmniFocus'),
        oDoc = of.defaultDocument,
        oWin = oDoc.documentWindows[0];
        
    const mb = bindMay(bindMay(projectMay(oWin), linkMay), groupMay)
    return (mb.nothing) ? mb.msg : ca.openLocation(mb.just)
})();
2 Likes

I’ve tried using this Interactive Inbox script, but I get an error upon compile

Can't get script "omnifocus"

This is triggered by line 3 of the script.

Can you suggest what I need to do to fix it?

In looking for an answer, I dug some more and found that the Interactive Inbox script is the work of Brandon Pittman. I forgot that he had a “library” script that needed to be placed in an OF directory for the inbox script to work. You can find directions at the link above.

1 Like

Thank you so much; that did the trick!

The script broke down, I do not know why. I get the following error:

/Users/bertkruisdijk/Library/Application Scripts/com.omnigroup.OmniFocus3.MacAppStore/DTPO.scptd: execution error: OmniFocus kreeg een fout: Error: near “Support”: syntax error (1)\

I have tried to find answers/ solutions but not succeeded. Can somebody give me a hint?

Your path contains a space (near “Support”), and what happens is explained here:

Mac Automation Scripting Guide

Quoting Strings
The shell uses space characters to separate parameters and gives special meaning to certain punctuation marks, such as $ , ( , ) , and * . To ensure that strings are treated as expected—for example, spaces aren’t seen as delimiters—it’s best to wrap strings in quotes. This process is known as quoting . If your string contains quotes, they must also be escaped (preceded by a / character) so they are interpreted as part of the string.

set thePath to "/Library/Application Support/"
do shell script "ls " & thePath
--> Result: error "ls: /Library/Application: No such file or directory\rls: Support: No such file or directory" number 1

It’s necessary to properly quote the string in order to run a shell script.

Change this line:

set strNoteXML to do shell script "sqlite3 " & pstrDBPath & space & quoted form of strQuery

to this line of code…

set strNoteXML to do shell script "sqlite3 " & quoted form of pstrDBPath & space & quoted form of strQuery

Thank you very much for this. It solved the problem I was facing. Again thanks for your effort!!

I am now encountering a new problem:

I am using this path:
property pstrDBPath : “~/Library/Containers/com.omnigroup.OmniFocus3.MacAppStore/Data/Library/Application Support/OmniFocus/OmniFocus Caches⁨/OmniFocusDatabase”

Is this not working anymore because the database is encrypted?

You are welcome.

The problem is your path contains a tilde ~ and it does not expand automatically. Use full path, instead.

Tell me if you have any remaining issues.

I have tried the following path:

property pstrDBPath : "$HOME/Library/Containers/com.omnigroup.OmniFocus3.MacAppStore/Data/Library/Caches/com.omnigroup.OmniFocus3.MacAppStore/OmniFocusDatabase"

This is not working.

I have also tried the following:
property pstrDBPath : "Macintosh HD/Users⁩/bertkruisdijk⁩/Library⁩/Containers⁩/com.omnigroup.OmniFocus3.MacAppStore⁩/Data⁩/Library⁩/Application Support⁩/OmniFocus⁩/⁨OmniFocus Caches⁩/OmniFocusDatabase

This was also not successful. I have looked for other possibilities but I am stuck. Can you give me a hint?

This looks similar to disk access permissions issues I’ve seen with other apps. In Preferences, Security and Privacy, Privacy tab, give AppleScript all disk access. That might help

Thanks Nick, I have tried this but is not the solution for me.

I can help, of course.

Try with this line:

property pstrDBPath : "/Users⁩/bertkruisdijk⁩/Library⁩/Containers⁩/com.omnigroup.OmniFocus3.MacAppStore⁩/Data⁩/Library⁩/Application Support⁩/OmniFocus⁩/⁨OmniFocus Caches⁩/OmniFocusDatabase"

Your path didn’t have an end quote.

As a footnote, see under Posix file paths in the AppleScript documentation here:

https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/ReferenceFilesandFolders.html

Note that:

  • the $HOME and ~ prefixes are understood (and automatically expanded, given the right quote marks) in Terminal.app (the Bash shell), but are not part of AppleScript.
  • The Macintosh HD prefix is recognised by the legacy colon-separated file path references (also described in the link above), but is not part of the default (forward slash delimited) Posix file path references.
2 Likes

Thanks for your help. I did paste the line but the problem persist. Do you have any other idea’s or suggestions. Your splendid help is welcome here.

Of course. I don’t have any problems with the script so I think we can work it out.

Could you post a screenshot of the error message? Also, what OS version do you have?

Thanks that you are willing to spend some time on my problem. The requested info below:

20190531-6440-Version%20OSX

Problem solved thanks to the great help on this forum!

For future reference my problem was that in the path to the OmniFocus Database, in the script hidden “?” were included (see picture). I do not know how or when this happened but with the great help of unlocked2412 was this discovered and solved using BBEdit.

I now can continue to enjoy this great script in my workflow.

3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.