Also, I think I found a bug: your get name script is struggling to get accented characters (such as ã, á, â…) correctly. See attached image bellow for an example:
It should read 2020.2. Supervisões de…
Perhaps this is something easily fixable, perhaps it’s not… I don’t know JavaScript enough to judge it.
Anyway, this is still the best way to extract links to Obsidian notes via Automation
@ldebritto I don’t have any accented characters in notes yet, but I can take a look. Is that screenshot from Hook when you go to link? Does it display correctly in Obsidian?
Looked into it a bit, and I think this might be an Obsidian bug? I’m pulling things from .obsidian/workspace (which is a JSON file), and the filename in lastOpenFiles has the bad characters instead of the accents.
It looks like like the metadata cache in ~/Library/Application Support/obsidian/ObsidianCache/<vault id>.json has the correct characters though. I’m not sure if there’s any way to work around it, since that is keyed by the filename, and the last file we know the name on is wrong
Using AppleScript and two handlers (one for JSON Parsing and other for URL encoding, both from stackoverflow), I’ve managed to make a version that will work following the same @technicalpickles specifications for getting the URL.
As a known but very likely workable limitation, I couldn’t make the script work properly with multiple vaults, and thus there’s a segment still in progress. Somebody with better AppleScript knowledge could possibly make a better job here.
This is the Get URL script:
# GOAL
-- Fetches an Obsidian URI link trough AppleScript on the background
-- Known limitations: currently works only with one vault
# WORKFLOW
-- Step 0: replace selected variables with your own data
-- Step 1A: gets last vault from Obsidian JSON
-- Step 1B: gets last file relative path via parsing of JSON
-- Step 2: encodes the relative path to URL format
-- Step 3: generates obsidian link
# HANDLERS
-- Uses a JSONtoRecord handler from user CJK posted at Stackoverflow (https://stackoverflow.com/a/51623993/13936032)
use framework "Foundation"
use scripting additions
--------------------------------------------------------------------------------
property ca : a reference to current application
property NSData : a reference to ca's NSData
property NSDictionary : a reference to ca's NSDictionary
property NSJSONSerialization : a reference to ca's NSJSONSerialization
property NSString : a reference to ca's NSString
property NSUTF8StringEncoding : a reference to 4
--------------------------------------------------------------------------------
on JSONtoRecord from fp
local fp
set JSONdata to NSData's dataWithContentsOfFile:fp
set [x, E] to (NSJSONSerialization's ¬
JSONObjectWithData:JSONdata ¬
options:0 ¬
|error|:(reference))
if E ≠ missing value then error E
tell x to if its isKindOfClass:NSDictionary then ¬
return it as record
x as list
end JSONtoRecord
--------------------------------------------------------------------------------
-- This second handler encodes the URL format without errors
on urlEncode(input)
tell current application's NSString to set rawUrl to stringWithString_(input)
set theEncodedURL to rawUrl's stringByAddingPercentEscapesUsingEncoding:4 -- 4 is NSUTF8StringEncoding
return theEncodedURL as Unicode text
end urlEncode
# START OF THE STEPS
(*
# IN PROGRESS - STEP 1A - Gets lastVault Name and Path data from obsidian.json at home folder
-- Gets the last vault JSON info
set home to the path to home folder
set v to the POSIX path of home & "Library/Application Support/obsidian/obsidian.json"
set JSONVaultRecord to JSONtoRecord from v
set lastVaultID to last_open of JSONVaultRecord
set lastVault to lastVaultID of vaults of JSONVaultRecord
set vaultPath to |path| of lastVault
*)
# STEP 1B - Gets user inputted vault Name and Path
set vaultName to "Obsidian"
set vaultPOSIXPath to "/Users/xxx/Documents/Obsdian/"
# STEP 2 - Gets relative path to lastOpenFile
-- Gets the workspace JSON file
set f to vaultPOSIXPath & ".obsidian/workspace"
set JSONFilesRecord to JSONtoRecord from f
set lastOpenFile to item 1 of lastOpenFiles of JSONFilesRecord
# STEP 3 - Encodes the relative path to a URL-friendly format
set encodedRelativePath to urlEncode(lastOpenFile)
# STEP 4 - Mounts the URI scheme link from variables vaultName and encodedRelativePath
set obsidianURL to "obsidian://open?vault=" & vaultName & "&file=" & encodedRelativePath
return obsidianURL
This is the Get Name script:
# GOAL
-- Fetches an Obsidian URI link trough AppleScript on the background
-- Known limitations: currently works only with one vault
# WORKFLOW
-- Step 0: replace selected variables with your own data
-- Step 1A: gets last vault from Obsidian JSON
-- Step 1B: gets last file relative path via parsing of JSON
-- Step 2: encodes the relative path to URL format
-- Step 3: generates obsidian link
# HANDLERS
-- Uses a JSONtoRecord handler from user CJK posted at Stackoverflow (https://stackoverflow.com/a/51623993/13936032)
use framework "Foundation"
use scripting additions
--------------------------------------------------------------------------------
property ca : a reference to current application
property NSData : a reference to ca's NSData
property NSDictionary : a reference to ca's NSDictionary
property NSJSONSerialization : a reference to ca's NSJSONSerialization
property NSString : a reference to ca's NSString
property NSUTF8StringEncoding : a reference to 4
--------------------------------------------------------------------------------
on JSONtoRecord from fp
local fp
set JSONdata to NSData's dataWithContentsOfFile:fp
set [x, E] to (NSJSONSerialization's ¬
JSONObjectWithData:JSONdata ¬
options:0 ¬
|error|:(reference))
if E ≠ missing value then error E
tell x to if its isKindOfClass:NSDictionary then ¬
return it as record
x as list
end JSONtoRecord
--------------------------------------------------------------------------------
-- This second handler encodes the URL format without errors
on urlEncode(input)
tell current application's NSString to set rawUrl to stringWithString_(input)
set theEncodedURL to rawUrl's stringByAddingPercentEscapesUsingEncoding:4 -- 4 is NSUTF8StringEncoding
return theEncodedURL as Unicode text
end urlEncode
(*
# IN PROGRESS STEP 1A - Gets lastVault Name and Path data from obsidian.json at home folder
-- Gets the last vault JSON info
set home to the path to home folder
set v to the POSIX path of home & "Library/Application Support/obsidian/obsidian.json"
set JSONVaultRecord to JSONtoRecord from v
set lastVaultID to last_open of JSONVaultRecord
set lastVault to lastVaultID of vaults of JSONVaultRecord
set vaultPath to |path| of lastVault
*)
# STEP 1B - Gets user inputted vault Name and Path
set vaultName to "Obsidian"
set vaultPOSIXPath to "/Users/xxx/Documents/Obsdian/"
# STEP 2 - Gets relative path to lastOpenFile
-- Gets the workspace JSON file
set f to vaultPOSIXPath & ".obsidian/workspace"
set JSONFilesRecord to JSONtoRecord from f
set lastOpenFile to item 1 of lastOpenFiles of JSONFilesRecord
# STEP 3 - Encodes the relative path to a URL-friendly format
set encodedRelativePath to urlEncode(lastOpenFile)
# STEP 4 - Mounts the URI scheme link from variables vaultName and encodedRelativePath
set obsidianURL to "obsidian://open?vault=" & vaultName & "&file=" & encodedRelativePath
set fileName to name of (info for (vaultPOSIXPath & lastOpenFile))
return fileName```
It’s great to see all this integration happening. We’ve been looking at this at CogSci Apps and looking to incorporate support based on this.
I noticed something about Obsidian’s URL handling (nothing to do with the integration scripts). If I
copy a URL of a file using Obsidian itself.
rename the file in Obsidian itself ,i.e using the Obsidian UI, (not even via Finder),
attempt to use the URL from step 1
result:
Obsidian cannot resolve the URLs.
Looking at the obsidian URL, it does not contain an ID.
Am I missing something?
hook://file/ URLs are robust under file renames, so we will likely, in addition to these scripts, provide alternative scripts that traffic in hook://file/ URLs.
Also, I’ve asked our devs at CogSci Apps to ensure Reveal File in Finder works via Hook in the context of Obsidian.
You’ll notice in those docs that we intend to update the integration (e.g., providing Reveal File in Finder , supporting Hook to New > Obsidian document , and giving users the option to use hook://file/ URLs, to the extent the Obsidian API allows.) We look forward to further development of the Obsidian API to automate linking from Obsidian to anything.
I want to thank @LucCogZest for his tremendous customer service. How many times have you seen a software company leader paying attention to this extent – joining us here on the Obsidian Forum? I look forward to the future of Hook.
It looks like obsidian.json no longer has the lastOpen field. I haven’t looked over the guess the Applescript version was not using that? Now there’s an "open": true on the vaults under “vaults” though:
Indeed! I wasn’t looking for the lastOpen vault, using an arbitrary variable with the path to my only vault.
My AppleScript skills weren’t good enough to fetch the lastOpen vault reliably (though I’ve managed to convert the JSON to a AppleScript record, I’m failing to check fetch the path to the record with the open key).
I guess the open:true is a safe step if there’s only one vault open at the time.
We will soon stop using the json file for ObsidianCache and migrate to IndexedDB for performance reasons.
I think this will break your integration.
If you want to keep the current integration, I suggest you write a plugin that dumps the information you need in a file and read that.