Customizing Hook Integration with DEVONthink

The purpose of this web page is to illustrate how you could customize Hook to integrate differently with DEVONthink. Most users will be content with the built in integration.

However, users who primarily use DEVONthink to index folders will prefer the alternative scripts. When Copy Link is called on an item in DEVONthink with that integration, the resulting URL will have the form hook://file// rather than x-devonthink-item://. This will make the hooks you create in DEVONthink visible when you open the same file in third party apps (a different PDF viewer, like PDFpenPro or Skim), a different text editor (like BBEdit), etc. That’s because in those other apps , Hook currently has no way of knowing what the x-devonthink-item:// URL is. Instead, it constructs the hook://file// URL based on the file’s path.

For current information about using Hook with DEVONthink, please see Using Hook with DEVONthink by DEVONtechnologies


Prior to February 2020, Hook itself did not provide integration scripts for working with DEVONthink. Hook’s integration relied on certain defaults. We had published the information below on Hook’s website, both as tips for customizing Hook to work with DEVONthink, and as an example of Hook’s powerful integration framework.

The information below might still be useful to anyone who wants to customize how Hook integrates with DEVONthink, particularly if they are not upgrading to Hook 1.3.

However, most DEVONthink 3 users will likely prefer the integration scripts provided by CogSci Apps Corp. in Hook itself (and via its integration server).

DEVONthink integration information: Before February 2020

Note: Custom integration with DEVONthink requires DEVONthink Pro or DEVONthink Pro Office, basic DEVONthink does not have the required Applescript support.

There are two different ways Hook can integrate with DEVONthink. DEVONthink stores its documents as files in folders, and organizes them in a database. Hook can either link to the files themselves, or through the database.

By default, Hook links to the files. If you open a link to a document you linked in DEVONthink, Hook will open it with the default program for the document type (e.g. Preview for PDFs or TextEdit for RTFs) instead of opening it in DEVONthink.

If you link to the database, the links will open the linked documents in DEVONthink itself. This is special behaviour which requires custom integration scripts.

Hook doesn’t have any DEVONthink integration scripts, so if you want to customize Hook to work differently with DEVONthink, you’ll need to create a bundle of scripts from scratch. In Preferences>Scripts, click the + button at the bottom of the list of apps, and add DEVONthink to begin writing custom scripts for it.

Get Name

tell application id "DNtp"
    if exists (content record of current tab of window 1) then
        -- current open item
        get name of (content record of current tab of window 1)
    else if class of window 1 is in {viewer window, search window} then
        set selected_items to selection of window 1
        if (count of selected_items) = 1 then
            -- current selected item
            get name of item 1 in selected_items
        end if
    end if
end tell

Hook is always invoked on the frontmost window, which is window 1. There are two cases which we have to handle:

  • The most common case is that we are linking to a document which is open. It will be in the current tab, and we can get the name from that.
  • The other case is that an item is selected but not open (e.g. in list view or if if a folder is selected). We can get the name from the selection.

Get Address

tell application id "DNtp"
    if exists (content record of current tab of window 1) then
        -- current open item
        get reference URL of (content record of current tab of window 1)
    else if class of window 1 is in {viewer window, search window} then
        set selected_items to selection of window 1
        if (count of selected_items) = 1 then
            -- current selected item
            get reference URL of item 1 in selected_items
        end if
    end if
end tell

This is almost exactly like the script for Get Name except it returns the reference URL instead of the name.

  • If more than one document is selected, or if no documents are, Get Address (and Get Name) won’t return anything, which means that no valid resource is detected

And that’s all you need to do to customize Hook’s integration with DEVONthink! Now your links to DEVONthink documents will open in DEVONthink.

But what about the other script fields? Why didn’t we write an Open Item script?

Alternative: Combining get address and get name

It is now possible to leave the get name tab blank, and combine get address and get name into one. See Creating and Modifying Integration Scripts – Hook.

Open Item

Hook uses URLs to link items together. If DEVONthink didn’t already support URLs to open documents Hook could use an Open Item script to parse URLs and open linked content in DEVONthink. But DEVONthink has its own URL scheme, x-devonthink-item, and Hook can use it to link DEVONthink documents.

So an Open Item script is not necessary for integrating Hook with DEVONthink. But writing one anyway does allow us to further customize how Hook and DEVONthink behave.

DEVONthink’s default behaviour is to open linked documents in a new window. We can write an Open Item script to open links in a tab of the front window instead of a new window.

set itemURL to "$0"
set itemID to text ((length of "x-devonthink-item://") + 1) thru -1 of itemURL
tell application id "DNtp"
    set itemRec to get record with uuid itemID
    if window 1 exists then
        set itemTab to open tab for record itemRec in window 1
        set current tab of window 1 to itemTab
        open window for record itemRec
    end if
end tell

"$0" is replaced by the URL returned by Get Address.

The script parses document-identifier from x-devonthink-item://document-identifier and uses it to get the record and open it in the front window, only opening a new window if there are no pre-existing windows.


If we have a custom Open Item script we need to specify the scheme for it. Set the scheme to x-devonthink-item in the field under Open Item

Setting the scheme does two things:

  1. The URL returned by Get Address is transformed from x-devonthink-item://document-identifier into hook://x-devonthink-item/document-identifier. The new URL starts with hook:// so macOS passes it to Hook to handle instead of to the owner of the original scheme (e.g. x-devonthink-item).
  2. Hook uses the scheme to look up the appropriate Open Item script to use to handle each URL. When a URL like hook://x-devonthink-url/document-identifier opens Hook tries to find an Open Item script paired with the scheme x-devonthink-url

And that’s all you need to do to make your links to DEVONthink open neatly in tabs.

Hook to New

Hook to New creates a new document and bidirectionally links it to the current item. When you invoke Hook on the first item, you will see a link to the new document — and vice versa. There are two things to know about writing the New Item script.

  1. The variable “$title” will be replaced in the script with the name of the source document. It is typically used for naming the new document.
  2. The script must finish by returning the address of the new document so that Hook can link it with the source document.

There is a lot of room to customize the Hook to New script according to personal taste.

tell application id "DNtp"
    set newItem to create record with {name:"$title", type:text}
    get reference URL of newItem
end tell

This is the simplest possible script. It just creates a new empty text document in the DEVONthink Global Inbox.

property folderID : "3D175C4C-4F99-4824-A927-FC8B955B0165"
tell application id "DNtp"
    set newDocGroup to get record with uuid folderID
    set newItem to create record with {name:"$title", content:"# $title\n\n", type:markdown} in newDocGroup
    set refURL to reference URL of newItem
    set itemPath to path of newItem
end tell

tell application "BBEdit"
    open itemPath
    tell application "System Events"
        key code 125 using {command down}
    end tell
end tell

get refURL

This is a more elaborate script. It does a few things.

  • creates a new markdown document
  • gives it a title header (with two new lines)
  • puts it in a predetermined folder (you can get a folder’s ID by selecting a folder and using Hook to copy a link to it). Please note that this can be a folder that is indexed by DEVONthink.
  • opens the document in BBEdit
  • moves the cursor to the bottom of the document (ready to begin writing)

And that really is all you need to do to get started writing your own scripts to customize how Hook works for you.

If you do try your hand at writing custom Hook scripts, check out the forum! There are people who are interested in seeing what you’ve created and are happy to help if you get stuck.