Problem: Automating "Save PDF to DEVONthink 3"

Hi there, I frequently send mails whose only content is an URL to myself. With DEVONthink Pro I used Automator actions to search them and create PDFs. As I have to rebuild this workflow I also want to automate it further as those mails often contain URLs which have to be created via Safari’s print dialog.

When reading in Safari I already use a handler that automates “Save PDF to DEVONthink 3” to a specific DEVONthink group and it works fine.

In the script I’m working on I use another handler that checks if Safari has finished loading the page. However if I use the same “Save PDF to DEVONthink 3” handler I already use in Safari (via script library, so it’s really the same) in the new script it will create PDFs in DEVONthink 3 but they have no URLs.

If I use the print dialog manually the records have URLs. If I use the handler while reading in Safari they also have URLs. But they don’t have URLs when created with the new script.

I already tried to set delays and set them higher (many more delays and much higher as in the handlers below), but that didn’t help - and that doesn’t seem to be the problem as PDFs are created but without URLs.

Any ideas?

Here's a part of the script to test if you also get records without URLs
property theURL : ""
property theGroupName : ""

tell application "Safari"
	make new document with properties {URL:theURL}
	activate
end tell

delay 1

set pageFinishedLoading to my waitForSafariPageToLoad()

if pageFinishedLoading = true then
	set printPDF to my printPDFToDEVONthink(theGroupName)
	if printPDF = true then tell application "Safari" to close window 1
end if

on waitForSafariPageToLoad()
	activate application "Safari"
	tell application "System Events"
		tell process "Safari"
			set theReloadButton to ""
			
			with timeout of 30 seconds
				repeat until theReloadButton is not ""
					repeat with i from 1 to 10
						try
							set theReloadButton to (first UI element of group i of toolbar 1 of window 1 whose name is "Diese Seite neu laden")
							exit repeat
						end try
					end repeat
				end repeat
			end timeout
			
			if theReloadButton ≠ "" then
				return true
			else
				return false
			end if
			
		end tell
	end tell
end waitForSafariPageToLoad


on printPDFToDEVONthink(theGroupName)
	tell application "System Events"
		try
			with timeout of 15 seconds
				
				tell process "Safari"
					keystroke "p" using command down
					repeat until button 1 of sheet 1 of window 1 exists
						delay 0.5
					end repeat
					#keystroke "p" using command down -- (shortcut for "Save PDF to DEVONthink 3")
					click menu button 1 of sheet 1 of window 1
					click menu item "Save PDF to DEVONthink 3" of menu 1 of menu button 1 of sheet 1 of window 1
				end tell
				
				tell process "DEVONthink 3"
					repeat until pop up button 1 of window 1 exists
						delay 0.5
					end repeat
					set focused of text field 2 of window 1 to true
					set value of text field 2 of window 1 to theGroupName
					click button 3 of window 1
				end tell
				
				return true
				
			end timeout
		on error
			return false
		end try
	end tell
end printPDFToDEVONthink

In case of a PDF document directly printed to DEVONthink (or using services or drag & drop too), DEVONthink tries to retrieve the URL from the source application and sets it. But if a script is used to print to DEVONthink, you have to set the URL of the new record on your own.

Ok, but why does the handler work in a script I use with Keyboard Maestro? It’s the same script library and the same source application (Safari) but I get different results.

Could you post the code of the script?

Just as an aside, UI scripting like this is fiddlly and easily subject to breaking. It’s a better idea to not try and reproduce physical movements, like button presses, except in very unusual circumstances. I would caution you to not become too reliant on it.

It’s probably possible to replace the script with just one line:

tell application id "DNtp" to create PDF document from theURL with pagination

Setting the URL afterwards did the trick, thanks @cgrunenberg

-- Automating "Save PDF to DEVONthink 3" to specific group. It will save to the first matching group that DEVONthink finds.

property theURLs : {}
property theGroupName : ""
property theDatabaseName : ""
property theReloadButtonName : "Diese Seite neu laden" -- you get the name of your reload button if you hover long enough over it

repeat with thisURL in theURLs
	tell application "Safari"
		make new document with properties {URL:thisURL}
		activate
	end tell
	
	delay 1
	
	set pageFinishedLoading to my waitForSafariPageToLoad()
	
	if pageFinishedLoading = true then
		set printPDF to my printPDFToDEVONthink(theGroupName)
		
		if printPDF = true then
			tell application "Safari"
				set thisPagesURL to URL of current tab of window 1 -- get the the right URL even when redirected
				close window 1
			end tell
			
			delay 1
			
			tell application id "DNtp"
				try
					set currDate to current date
					set theComparisonDate to currDate - 300
					set lastAddedRecord to item -1 of (search "additionDate >" & theComparisonDate in (root of database named theDatabaseName))
					set URL of lastAddedRecord to thisPagesURL
					
				on error error_message number error_number
					if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
				end try
			end tell
			
		end if
	end if
end repeat

on waitForSafariPageToLoad()
	activate application "Safari"
	tell application "System Events"
		tell process "Safari"
			set theReloadButton to ""
			
			with timeout of 30 seconds
				repeat until theReloadButton is not ""
					repeat with i from 1 to 10
						try
							set theReloadButton to (first UI element of group i of toolbar 1 of window 1 whose name is theReloadButtonName)
							exit repeat
						end try
					end repeat
				end repeat
			end timeout
			
			if theReloadButton ≠ "" then
				return true
			else
				return false
			end if
			
		end tell
	end tell
end waitForSafariPageToLoad


on printPDFToDEVONthink(theGroupName)
	tell application "System Events"
		try
			with timeout of 15 seconds
				
				tell process "Safari"
					keystroke "p" using command down
					repeat until button 1 of sheet 1 of window 1 exists
						delay 0.5
					end repeat
					#keystroke "p" using command down -- (my shortcut for "Save PDF to DEVONthink 3")
					click menu button 1 of sheet 1 of window 1
					click menu item "Save PDF to DEVONthink 3" of menu 1 of menu button 1 of sheet 1 of window 1
				end tell
				
				tell process "DEVONthink 3"
					repeat until pop up button 1 of window 1 exists
						delay 0.5
					end repeat
					set focused of text field 2 of window 1 to true
					set value of text field 2 of window 1 to theGroupName
					click button 3 of window 1
				end tell
				
				return true
				
			end timeout
		on error
			return false
		end try
	end tell
end printPDFToDEVONthink