Smartrule for making unique link to open annotation file in obsidian

Hello,

I want in a pdf with a annotation file place a link in the url, that after moving the annotation file to obsidian, can open that annotationfile in obsidian from Devonthink.

I have this script, placed in smart rules, but it does not work:

on run
    tell application id "DNtp"
        
        -- 1) Ensure at least one item is selected
        set sel to the selection
        if sel = {} then
            display alert "Error" message "Please select one or more items in DEVONthink."
            return
        end if

        -- 2) Process each selected item
        repeat with thePDF in sel
            try
                -- 2a) Only PDF documents
                if type of thePDF is not PDF document then
                    display dialog "Skipped (not a PDF): " & (name of thePDF) buttons {"OK"} default button 1
                    continue repeat
                end if

                -- 2b) Must have an annotation
                if not (exists annotation of thePDF) then
                    display dialog "Skipped (no annotation): " & (name of thePDF) buttons {"OK"} default button 1
                    continue repeat
                end if

                -- 3) Retrieve the DEVONthink UUID
                set theUUID to uuid of thePDF as text

                -- 4) Build your Obsidian search link
                set obsidianURL to "obsidian://search?query=" & theUUID

                -- 5) Write the link into the URL field
                set URL of thePDF to obsidianURL

                -- 6) Confirmation per file
                display dialog "URL information updated for:" & return & (name of thePDF) buttons {"OK"} default button 1

            on error errMsg
                display dialog "Error processing " & (name of thePDF) & ":" & return & errMsg buttons {"OK"} default button 1
            end try
        end repeat

        -- 7) Final notification
        display notification "All selected PDFs have been updated." with title "Process Complete"

    end tell
end run

Thanks for helping,

Freek

I am sorry, but how do I place a script in this forum? The end tell disappeared…

I already fixed this. In the future just use three backticks ``` before & after the script’s code.

1 Like

That is not how you write a script for smart rule. Check out the documentation, please.

Am I correct to assume that the code was mostly written by an AI?

1 Like

I have this script

Starting with Potemkin pastiche is understandably tempting,

but in fact costs you ( and others ) more time than simply starting with the documentation, experimenting, and asking for help.


Turns out that LLMs even slow down experienced coders who imagine that they are being helped. Subjective time feels shorter, but clock time turns out to be longer.

Dear Chrillek, you are right: AI. What is the best place to find good documentation to start automation? In the documentation on DT4 it is not clear for me, I am a psychologist and IT is just a way to organise myself… Where can I find good tutorials? Thanks,

Freek

on performSmartRule(theRecords)
	tell application id "DNtp"
		repeat with theRecord in theRecords
			if (annotation of theRecord) is not missing value then
				set theAnnotation to annotation of theRecord
				set annotationName to name without extension of theAnnotation
				set vaultName to "YourVaultName"
				set encodedVaultName to my encodeURIComponent(vaultName)
				set encodedAnnotationName to my encodeURIComponent(annotationName)
				set obsidianURL to "obsidian://open?vault=" & encodedVaultName & "&file=" & encodedAnnotationName
				set URL of theRecord to obsidianURL
			end if
		end repeat
	end tell
end performSmartRule

on encodeURIComponent(uri)
	run script "encodeURIComponent(" & (the quoted form of uri) & ");" in "JavaScript"
end encodeURIComponent

NOTE:
YourVaultName has to be changed to the actual name of your vault.

P.S: This code was written by Claude 4 Opus using an internal build of DEVONthink, I only added the URI encoding :smiling_face_with_horns:

2 Likes

This is nice cgrunenberg, but to have a solid reference, I want to have a unique identifier to that file. It is a link I want to copy to URL in the original pdf so I can launch the linked annotation file in obsidian from the pdf. Even names change afterwards… I hope this is possible…

I’m not really familiar with Obsidian, opening via names is the only method I’m aware of.

1 Like

There’s the chapter on automation in the DT manual. Which is good, though terse.

Then, if you create a smart rule, you might want to select a document type, namely PDF. Which obsoletes the check for PDF in the script. Next, select the “Execute script” action in the smart rule and select “AppleScript” or “JavaScript” (which I’d suggest, though AS is still prevalent here). That will open a small editor window with a scaffold. And as you can see, that is utterly different from your on run approach.

The key part here is the perform smart rule handler (or the performsmartrule function for JavaScript). You’ll see how that encompasses everything your script should do in the sample code @cgrunenberg/Claude posted.

I have a website for JavaScript automation on macOS (“JavaScript for Automation,” JXA). You’ll find a chapter on DT automation there. But the site is by no means a tutorial.

Now to the code (in JavaScript)

const vaultName = encodeURIComponent("YourVaultName");

function performsmartrule(records) {
  records.filter(r => r.annotationCount() > 0).forEach(r => {
    const encodedAnnotationName = encodeURIComponent(r.annotation.nameWithoutExtension();
    r.URL = `obsidian://open?vault=${vaultName}&file=${encodedAnotationName}
  })
}

This is deliberately written very compactly. For educational purposes, one should use additional variables like @cgrunenberg/Claude did in their script.
The most notable difference is that with JavaScript, one doesn’t need to run a script to perform URI encoding – the necessary function is built-in. Another detail is that I moved the vault definition outside the loop because imo that should be done only once. Claude doesn’t care about invariants inside loops, apparently.

Disclaimer: Since I do not have Obsidian, I didn’t test the code.

2 Likes

Trying to make it a bit more clear:

PDF - make Annotation - Make unique ID and link - place it in URL of pdf - rename and move file to obsidian. Working in DT I can then launch the url and open the annotation file (in Obsidian)

Thanks for helping me out…

Who makes that ID? What does the link point to?

Which file – the PDF? the annotation?

Can the link point to the annotation file that has been moved to Obsidian? The pdf stays in DT and the Annotation goes to Obsidian…

Perhaps. I don’t know this software. In DT, one would have to create the file first to be able to get a reference to it afterward.

But from the very cursory search I did, Obsidian does not seem to support OSA (Open Scripting Architecture) – so neither AppleScript nor JXA are available to automate it. Personally, I wouldn’t go down that way. Too much trouble, too many unknowns.

1 Like

This code was written by Claude 4 Opus

Understandable to want to slow yourself down,
and take a bit longer over things, in summer.

Good for health and recovery   :sun_with_face:

Sure, you got me. That was the actual intention.

1 Like
  • Is your Obsidian vault indexed in DEVONthink?
  • Why move an annotation file to Obsidian? Why not create the note in Obsidian directly?
  • If you want to move it… What is the destination? (beyond “Obsidian”)
  • Do you want the file to stay linked as an annotation in DEVONthink, or do you want to “export” it and break the link?

I think it would be easier if you gave a more general description of your setup, goal and reasoning.


The core Obsidian URI-scheme is documented here:

Based on this thread in the Obsidian forum, I gather that Obsidian core has no concept of UUIDs:

But I think it should be possible to do what you want with the Advanced URI plugin. This URI-scheme can work with files based on a UUID stored in the metadata header/“frontmatter” of the file itself – see: File identifiers - Advanced URI Documentation.

I use Devonthink for gathering research articles, texts, book, powerpoints etc… I use Obsidian to create a second brain.
The annotation files become notes in Obsidian with yaml and links, so I can create links, resume, create my own idea’s. But always come back to the basic text if needed.
With DT creating annotations with yaml and a back-link (in the Obsidian file the backlink to DT is in the note), I rename the annotation and move it to Obsidian. This process is already automated.
What happens a lot is that the link between the original text and the annotation get’s lost, so I want to be sure that the Obsidian link can be found in the metadata of the original text.

  • my Obsidian vault is indexed in Devonthink
  • the annotation file let’s me insert info from the pdf, like the backlink
  • the destination is becoming a note in Obsidian, this is info for my second brain
  • I want the link to stay between the two files
    Does this help?
    Thanks for your answer, I will give it a try!

What is the benefit of Obsidian in this scenario? In what you’re writing, I’m not reading anything that DEVONthink isn’t capable of.

1 Like

Perhaps this might be a case for Hookmark:

1 Like