AppleScript to send Devonthink item to GoodTask?

I have only a basic understanding of AppleScript so I'm wondering if a genius here might be able to provide some guidance. I use Devonthink to store most of my documents, and occasionally there's something I'd like to follow up on. Someone created an AppleScript to send new items to Reminders, which of course works well with GT, but it would be great to have one dedicated to GT.

Here's the Reminders script:

-- Script to add a selected record to Reminders as a to do
-- Written by Eric Böhnisch-Volkmann, Version 1.1, Sep 12, 2012
-- © 2010–2014 DEVONtechnologies, LLC
-- Modified October 28, 2016 by Jim Neumann / BLUEFROG / DEVONtechnologies, LLC
--> Added Custom Date option


-- Set properties
property pDaysIntoFuture : -1 -- Created to do will have a due date n days in the future
property pPrefix : "Reminder" -- Prefix for the created to do item
property pDelays : {{displayname:"No due date", value:0}, {displayname:"Custom…", value:-1}, {displayname:"Tomorrow", value:1 * days}, {displayname:"In two days", value:2 * days}, {displayname:"In three days", value:3 * days}, {displayname:"In one week", value:1 * weeks}, {displayname:"In two weeks", value:2 * weeks}, {displayname:"In one month", value:4 * weeks}, {displayname:"In two months", value:8 * weeks}, {displayname:"In three months", value:90 * days}, {displayname:"In six months", value:180 * days}, {displayname:"In one year", value:365 * days}}
property pDefaultDelay : "In one week"

set theDueDate to ""

-- Import helper library
tell application "Finder" to set pathToAdditions to ((path to application id "DNtp" as string) & "Contents:Resources:Template Script Additions.scpt") as alias
set helperLibrary to load script pathToAdditions

try
	-- Get the selection
	tell application id "DNtp" to set thisSelection to the selection

-- Error handling
if thisSelection is {} then error localized string "Please select a document or group, the try again."
if (length of thisSelection) > 1 then error localized string "Please select only one document or group, then try again."

-- Get and format the data we need
set pLocalizedPrefix to localized string pPrefix
tell application id "DNtp"
	set thisItem to first item of thisSelection
	set theSummary to (pLocalizedPrefix & ": " & name of thisItem) as string
	set theURL to (reference URL of thisItem) as string
end tell

-- Let the user choose the reminder list
tell application "Reminders"
	set theListNames to {}
	repeat with theList in the lists
		set theListNames to theListNames & {name of theList}
	end repeat
end tell
if (count of theListNames) = 0 then error (localized string "Please set up at least one list in Reminders.")
set theChoice to choose from list theListNames with title (localized string "Choose list") default items {item 1 of theListNames}
if theChoice is false then return false -- If the user pressed Cancel, exit
if theChoice is missing value or class of item 1 of theChoice is not text then return false
set theChosenListName to item 1 of theChoice

-- Let the user choose when to receive the reminder
-- Convert array into localized arrays
set pLocalizedDelays to {}
set pLocalizedDelayNames to {}
repeat with theDelay in pDelays
	set pLocalizedDelays to pLocalizedDelays & {{displayname:localized string (displayname of theDelay), value:(value of theDelay)}}
	set pLocalizedDelayNames to pLocalizedDelayNames & {localized string (displayname of theDelay)}
end repeat
set theChoice to choose from list pLocalizedDelayNames with title (localized string "Set reminder") with prompt (localized string "Please choose when you want to get reminded of the item") & " \"" & theSummary & "\"" & (localized string "%choice prompt end%") & ":" default items {localized string pDefaultDelay}
if theChoice is false then return false -- If the user pressed Cancel, exit
set theDelayValue to pDaysIntoFuture -- Assume default
try
	-- Find the number of days associated with the user's choice
	repeat with theDelay in pLocalizedDelays
		if ((displayname of theDelay) as string) is equal to (theChoice as string) then set theDelayValue to (value of theDelay)
	end repeat
end try

-- Calculate due date
if theDelayValue > 0 then
	set theDueDate to (date (date string of (current date))) + theDelayValue
else if theDelayValue < 0 then
	try
		set theDueDate to (date (text returned of (display dialog (localized string "Enter the due date") & ":" & return & (localized string "Example: 1/1/2017 10:45pm") default answer "")))
	on error
		return
	end try
end if

-- Add new to do to Reminders
tell application "Reminders"
	tell list theChosenListName
		--Create new to do
		if theDueDate ≠ "" then
			set theEvent to make reminder with properties {name:theSummary, remind me date:theDueDate, body:theURL}
		else
			set theEvent to make reminder with properties {name:theSummary, body:theURL}
		end if
		show theEvent -- Show new to do item in Reminders so that the user can edit it right away
		activate
	end tell
end tell

on error errMsg

display alert (localized string "Error when adding item to Reminders") message errMsg

end try
1 Like

This week, I was working on making an AppleScript to send selected Mail messages to GoodTask (though you can already drag messages to GoodTask, I wanted something more keyboard centric). I came up with two options, either of which might also be helpful starters (I don't use Devonthink, so I don't think I could help very much with specifics).

As far as I can tell, GoodTask doesn't support AppleScript directly, but you can still use AppleScript with GoodTask's URL scheme or by sending keystrokes to it. Both options can be easily run by using Automator to create a Quick Action, adding a Run AppleScript action, and entering the script. I set up a keyboard shortcut to run it when in the Mail app. There are probably other ways to run the scripts as well.

The first option I tried was to use AppleScript to build the URL to direct GoodTask to add a new task with the specified title and to add a tag and link to the Mail message in that task's note field. The script also includes to functions necessary for URL encoding some text (I found the functions at https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/EncodeandDecodeText.html). See the comments to find the main part of the script.

-- These first two functions are necessary for URL encoding to use with the GoodTask URL scheme
on encodeCharacter(theCharacter)
	set theASCIINumber to (the ASCII number theCharacter)
	set theHexList to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
	set theFirstItem to item ((theASCIINumber div 16) + 1) of theHexList
	set theSecondItem to item ((theASCIINumber mod 16) + 1) of theHexList
	return ("%" & theFirstItem & theSecondItem) as string
end encodeCharacter

on encodeText(theText, encodeCommonSpecialCharacters, encodeExtendedSpecialCharacters)
	set theStandardCharacters to "abcdefghijklmnopqrstuvwxyz0123456789"
	set theCommonSpecialCharacterList to "$+!'/?;&@=#%><{}\"~`^\\|*"
	set theExtendedSpecialCharacterList to ".-_:"
	set theAcceptableCharacters to theStandardCharacters
	if encodeCommonSpecialCharacters is false then set theAcceptableCharacters to theAcceptableCharacters & theCommonSpecialCharacterList
	if encodeExtendedSpecialCharacters is false then set theAcceptableCharacters to theAcceptableCharacters & theExtendedSpecialCharacterList
	set theEncodedText to ""
	repeat with theCurrentCharacter in theText
		if theCurrentCharacter is in theAcceptableCharacters then
			set theEncodedText to (theEncodedText & theCurrentCharacter)
		else
			set theEncodedText to (theEncodedText & encodeCharacter(theCurrentCharacter)) as string
		end if
	end repeat
	return theEncodedText
end encodeText

-- This is the main part of the script
-- get currently selected messages from the Mail app
-- You could change this first part to set variables from Devonthink
tell application "Mail"
	
	set selMessages to selection
	
	-- if there are selected messages, choose the first one
	if (count selMessages) > 0 then
		set firstMsg to item 1 of selMessages
		
		-- assign the message's subject to a variable to use for the title
		-- the title must be URLencoded to pass to the GoodTask url scheme later in the script
		set taskTitle to (my encodeText(subject of firstMsg, true, true))
		
		-- get the unique id of the message and create a URL that will open it in the Mail app
		-- normaly message://%3cXXXXX%3e, but must be url encoded to pass through the GoodTask url
		set msgURL to "message%3A%2F%2F%253c" & (message id of firstMsg) & "%253e"
		
		-- set the tag
		set taskTag to (my encodeText("#Email", true, true))
		
		-- construct the url with title and notes fields (both the tag and the link go in the notes field)
		set goodTaskURL to "goodtask3://add?title=" & taskTitle & "&notes=" & taskTag & "%0A%0A" & msgURL
		
		-- opening the URL should open GoodTask and add the new task automatically
		open location goodTaskURL
	end if
end tell

For the first option, You could probably use a large part of the AppleScript you posted to get the values from Devonthink.

You could add other things such as due dates or set the list in the script to pass to the GoodTask URL scheme.

The GoodTask help page for the URL scheme also indicates that you can make GoodTask prompt for input, but I couldn't get that to work on Mac. You could probably use the part of the AppleScript you posted to use Reminders for the prompts and then pass the user input to the URL scheme, but I'm not sure.

The second option I tried was a script that uses keystrokes to

  1. Open GoodTask's new task dialog using the global shortcut I created.
  2. Type the text of the extracted message subject in the title field.
  3. Tab to the note field
  4. Type the tag in the note field and add a blank line
  5. Type the URL of the link to the Mail message

This second option requires more permissions, but I think I like it better because it allows me to use GoodTask's own new task dialog to choose the list, set a due date or alert, and add other tags that I might want.

	  -- get currently selected messages from the Mail app
-- You could change this first part to set variables from Devonthink
tell application "Mail"
	
	set selMessages to selection
	
	-- if there are selected messages, choose the first one
	if (count selMessages) > 0 then
		set firstMsg to item 1 of selMessages
		
		-- assign the message's subject to a variable to use for the title
		set taskTitle to subject of firstMsg
		
		-- get the unique id of the message and create a URL that will open it in the Mail app
		set msgURL to "message://%3c" & (message id of firstMsg) & "%3e"
		
		-- set the tag
		set taskTag to "#Email"
		
		
		-- tell the System to type what we want to do
		tell application "System Events"
			
			-- open GoodTask's new task dialog by typing the keystroke assigned in GoodTask's options
			keystroke ";" using command down
			
			-- wait briefly for the new task dialog to appear (adjust as needed)
			delay 0.045
			
			-- the cursor should be in the title field, so type the value of the variable
			keystroke taskTitle
			
			-- tab to the notes field
			repeat with i from 1 to 4
				keystroke tab
				delay 0.015
			end repeat
			
			-- type the value of the tag variable
			keystroke taskTag
			
			-- after a brief delay, insert a blank line
			delay 0.05
			keystroke return
			keystroke return
			
			-- type the value of the msgURL variable
			keystroke msgURL
			
			-- when the script has finished, you can use GoodTask's dialog to choose the list, add more tags, add a due date, etc.
		end tell
	end if
end tell

Again, the second option probably requires you grant more Accessibility permissions to the AppleScript, Devonthink, or Automator (you should be prompted about them the first time).

The main parts you would need to change for either of the above scripts would be getting the information from Devonthink instead of the Mail app to set the variables to use later in the script.

1 Like

Thank you for your detailed response. I have a basic understanding of coding – certainly enough to have play and see if I can get something to work. Much appreciated.

1 Like

Glad to help. I hope you work something out.

1 Like