Looking for JavaScript examples for learning Devonthink Automation

I would also like to look into JavaScript as my automation scripting environment. I come from a programming background and possibly would feel more comfortable with its syntax.

In order to evaluate this I would like to know is there any added functionality achieved by using AppleScript rather than Javascript or is it just a preference in terms of working with its syntax?

The other thing is that I find is that I am the type of learner that likes to look at examples and thereby learn how things are done. There are many examples of Applescripts being used in DT3 that come with the product but what I would be grateful if some working javascripts that I could use as a basis of my learning and experimentation.

Thanks

Steven

Basically itā€™s just a preference but e.g. embedded scripts of smart rules & reminders do not yet support JavaScript, this will be possible in an upcoming release (which will also improve the overall compatibility to JavaScript)

Iā€™ve occasionally posted some JS examples here, which you might find in the forum if you look for ā€œApplication user:chrillekā€.
As @cgrunenberg said, you canā€™t yet use JS as external script in smart rules, but that will come apparently.

Basically, a JS script looks like this (with a self-execucting main function)

(() => {
  const app = Application("DEVONthink 3"); // note that you can't use the Application id here!
  const records = app.selectedRecords();
  records.forEach(r => {
   // do something with r here
  })
})()

You can use Script Editor (thatā€™s preinstalled anyway) to write JS script. Set the language to ā€œJavaScriptā€ in itā€™s upper left drop down. To find out which objects and methods are available in DT, open the function library in Script Editor, find DT and then select ā€œJavaScriptā€ in the top drop down of the function library window. Unfortunately Script Editor is so bad that it does not remember this choice (while it does remember your preferred programming language in the editor window ā€“ quality control is on a long, long holiday at Appleā€™s).

For more info on JavaScript for Automation (JXA), google for ā€œrelease notes JavaScript macosā€ ā€“ thatā€™s all youā€™ll the official documentation youā€™ll ever find. There are some more sources on the web, too, but most information is scattered about and scarce.

1 Like

Thanks @chrillek .

I appreciate the barebones startup script that was provided. It is very useful in getting started. Thank you.

A few of questions if I may.

Please excuse if the terminology i use is not correct

  • there seems to be some basic differences between how to interface with the Devonthink object using AppleScript VS JavaScript. An example would be getting the properties of a record. In the Devonthink libarary it looks like a property and would only require the dot syntax but rather it some sort of a function that requires () parenthesis. Is this correct?

  • how would setting the properties of a record work?

  • are there other basic differences that I should be aware of?

  • How to work with record properties thatt are 2 words like plain text1

  • why, do i find in the JavaScript in the forum code that invokes displayDialog of the app object but I donā€™t see it in the Applescript library

Anything that would help me clean this up is very appreciated.

Steven

display dialog is a command of Standard Additions, not DEVONthink.

Try thisā€¦

const app =  Application.currentApplication();
app.includeStandardAdditions=true;
app.displayDialog("Hi");

Note you have to include the Standard Additions as shown here.

You use function syntax to get properties and you use assignment to set properties:
const pt = record.plainText()
record.plainText = ā€žhiā€œ
(simple quotes in the last case, but my stupid phone keeps replacing themā€¦)
There are no two-word properties in JavaScript. Please make sure youā€™ve changed the language in the script editorā€™s function library to JavaScript!
You need to set standardAdditions to Zeit if you want to use any GUI methods (as explained by @BLUEFROG).
If you want to read or write files, you need to call the methods for that on the currentApplication object.

Ok, Thanks for getting me started.

DUHšŸ˜³, sorry I missed that.

OK, got it.


Is there a recommendation for something a bit more advanced for JavaScrip debugging similar to the ScriptDebugger product from Late Night Software?

I see that the Safari debugger can be invoked using the Script Editor. Is this the best way to go?

Steven

AFAIK it is the only way to attach a debugger to a running script. In my experience, it works not very reliably. And Safari has no way to drill down into objects, so this is not very useful in my experience.

@chrillek

Thanks, I appreciate your help.

As far as I know thereā€™s nothing comparable to Script Debugger. In fact people at the Script Debugger forum wrote that they are writing in JavaScript but to understand a new appā€™s dictionary they first explore the AppleScript dictionary in Script Debugger before they write in JavaScript.

Donā€™t know whether thatā€™s something for your (current) usage scenario but this post by @houthakker about using CodeRunner.app and ScriptEditor.app might be worth a look.

And thereā€™s this post about ScriptEditor.app and automatically showing the debugger in Safari.

If I wanted to learn JavaScript I would read everything from @houthakker / @RobTrew / @complexpoint / @drafts8. Hard to understand, especially as a starter (I guess), but it seems he also often posts references and nice things to know.

Definitely. At least what Iā€™ve seen from @houthakker requires a solid grasp of JS already. @robtrew follows a functional programming paradigm (and hardly documents anything at all). I couldnā€™t really find anything from the other two people ā€“ or are the four monikers referrint to the same persion?

Anyway, Iā€™d suggest something a bit simpler than fully blown functional programming to get going with JS. There should be lots of tutorials out there, some might even be good :wink: At least, I have fond memories of the Oā€™Reilly book(s) on JS.

1 Like

Itā€˜s one person. Search for @complexpoint at the Keyboard Maestro forum and for @draft8 at the Omni forums.

I second that advise. As I follow the functional programming paradigm (and code in JavaScript For Automation), his advice and examples has been extremely valuable in my learning process. My journey started many years ago. Previously, I did every automation in AppleScript.

Those are amazing news. Improved compatibility with JavaScript sounds great.

Some hours ago I discovered that itā€™s possible to set a OmniFocus tagā€™s note via AppleScript. The OP wanted a way to access the note via UI but for me it would be enough to set the note to a DEVONthink link and use another script to open the link (in order to write down a tagā€™s description etc.). Hereā€™s the thread Feature Request: Add Notes to Tags - OmniFocus .

Any advantage if I would try to do it via JavaScript? Iā€™ve zero JavaScript knowledge but this might be a good starting project, or?

I havenā€™t looked at your specific example, yet. However, Omni has developed Omni Automation API in recent years. Since it is cross-platform, the same Plug-In developed could be used in macOS and/or iOS/iPadOS. Iā€™ve also found that API is much faster when doing large queries of the database than AppleScript (or JXA).

JS has richer array methods compared to AppleScript. Things like .map, .filter and .reduce are always welcomed.

1 Like

In general, JS tends to be less verbose. Less typing is an advantage, in my opinion. But the real advantages are in the methods available for string processing (and reg exes), array methods etc.

I wouldnā€™t know how to go about converting the script youā€™re referring to to JS since I donā€™t have OmniFocus installed. Basically, it might look like this

const app = Application("OmniFocus");
app.includeStandardAdditions = true; // you need that for the dialogs later on 
const selection = app.defaultDocument.documentWindows[0].content.selectedTrees();
if (selection.length !== 0) {
ā€¦  
} else {
  ...
}

You might want to read Appleā€™s (only) text on JXA: OS X 10.10 Release Notes
it explains some of the concepts, albeit incredibly tersely.

1 Like

@pete31 thanks, very helpful. I thought that the power of script debugger was strictly with debugging using breakpoint and examining variable.

I appreciate you pointing me in this direction. A starting point to understand.

@chrillek

Thanks for sharing.

I am starting to lean towards starting out with AppleScript mainly because of the many scripts that are in the forum and come with DT3. Also having a product like Script Debugger really makes a difference.

Thanks all.

Steven

1 Like

Thatā€™s of course your prerogative. Personally, I didnā€™t miss a JS debugger when writing scripts for DT: about 99% of the problems arose before running the script, the rest was due to imperfections in DTā€™s JS binding. The latter has been announced to be fixed in (one of) the next release(s).

A debugger is certainly helpful for runtime problems. But I see this kind of issues not really happening in the context of DT. It would also help in inspecting the JXA objectsā€™s structures, given that it is nearly impossible to use the usual JS tools for that. But then thereā€™s the documentation (aka function library) which already gives a lot of information. Or should be.

1 Like

Since @pete31 pointed out CodeRunner (thanks again for that!), I got this app and it looks a lot more suited to JavaScript development than Script Editor. In fact, one can add a new language definition for JXA to it like so

That permits to run JXA applications from CodeRunner (just like from Script Editor), with the added benefit that CodeRunner knows all about JS syntax etc. and is a lot more comfy to work with (I did say that already, didnā€™t I?). As a proof of concept, I used a very simple JXA script

(() => {
	const app = Application("Mail");
	app.accounts().forEach(a => {
		console.log(a.name())
	})
})()

It just gets the names of all the mail accounts. I apologize for it being OT here, but I am currently on a machine without DT (which is hard to believe, I know).

2 Likes