The Omni Group
These forums are now read-only. Please visit our new forums to participate in discussion. A new account will be required to post in the new forums. For more info on the switch, see this post. Thank you!

Go Back   The Omni Group Forums > OmniFocus > OmniFocus Extras
FAQ Members List Calendar Today's Posts

 
OmniFocus URI Handler (create tasks via URL) [See Omni note on pg 5!] Thread Tools Search this Thread Display Modes
You might want to file a bug report to Omni (Help → Send Feedback) about the QE not opening. They changed some of the internals on opening the QE window with 1.7, so this could be a regression.
__________________
Cheers,

Curt
 
I'm checking with Ken to be sure, but I think what happened here is that Mail on the iPhone OS made a change which broke our "send settings in an email" feature. I think fixing that on the phone required a change which caused the bookmarklet to stop working on the Mac.

Of course, I could be remembering this incorrectly. More info soon.
 
Turns out I was incorrect about what happened here - I forgot that the bookmarklet sends information along to an applet instead of OmniFocus itself.

We made a change in 1.7 that probably affects the applet that the bookmarklet sends data to:
Updated our AppleScript terminology to use "open quick entry" rather than "activate quick entry". Hopefully this will eliminate the problems people have occasionally encountered in trying to activate the app itself. (Compiled scripts which used our old activate verb may need to be recompiled, however!)
So, once folks recompile the applet to use "open quick entry" instead of "activate quick entry", the bookmarklet should start working again.
 
Thanks for the information, Brian! I changed “activate” to “open” within the QE entry in the URI script and the bookmarklet functions correctly now. Here is the the modified script if anyone else is interested.

Code:
(* 
# OMNIFOCUS URI HANDLER

This applet enables you to create new tasks using an "x-omnifocus" URL. This is particularly designed to make it easy to add tasks from a web browser via a bookmarklet, without having to code a separate script for each browser. This also works in browsers that don't support AppleScript. (I'm looking at you, Firefox!!!)

It also supports more advanced URLs containing context and project assignments that you're likely to create from web page bookmarklets. This functionality can be utilized to make it easier to add OmniFocus tasks from other applications, shell scripts, etc., without having to hook into complicated AppleScript.

## HOW TO CREATE PROPER URLS

All URLs must use the "x-omnifocus:" URI. You can have "whack whacks" after the URI, or just a colon, your choice. You must then follow the URI with the following methods:

*x-omnifocus:newtask*

This creates a new task. You can pass variables, following the example below. The only required element is "name".

x-omnifocus://newtask?name=**task name**&project=**project name**&context=**context name**&note=**task note text**&quickentry=**1/0**

**Project Name** and **Context Name** will "fuzzy match" an existing project or context, so you don't need a full or exact name.

a **Quickentry** value of "1" will cause the task to go into the Quick Entry window, which will be activated, rather than straight into the inbox. 

*x-omnifocus:parsetasks*

This parses tasks either as a single task or as multiple tasks, per the usual parsing syntax. You can pass two variables, the text to parse and whether to parse it as a single task, as below. The only required element is the text to parse.

x-omnifocus://parsetasks?text=**Text to Parse**&single=**1/0**

A *single* value of "1" will make the tasks parse as single tasks. Otherwise, tasks will be parsed line-by-line, potentially as multiple tasks. 

All strings should be URL encoded to eliminate any ambiguity in URLs and whatnot.

*** BOOKMARKLETS TO GET YOU STARTED ***

Here's some sample bookmarklets you can put into your browser's toolbar to make this all go:

*Add the current page as a task with the page's URL and any selected text as the note:*

javascript:window.location='x-omnifocus://newtask?name='+encodeURIComponent(document.title)+'&note='+encodeURIComponent(window.location+'\n\n')+encodeURIComponent(getSelection())+'&quickentry=0';

*Same as above, but route to the Quick Entry window instead of directly into the inbox:*

javascript:window.location='x-omnifocus://newtask?name='+encodeURIComponent(document.title)+'&note='+encodeURIComponent(window.location+'\n\n')+encodeURIComponent(getSelection())+'&quickentry=1';

*Parse tasks in the selection:*

javascript:window.location='x-omnifocus://parsetasks?text='+encodeURIComponent(getSelection())+'&single=0';

## NOTES

The HTML entity decoding routine falls down on certain characters, particularly Unicode characters.

If you use the quick entry window with the "newtask" method, the project and context values will be ignored, as these are not scriptable in the quick entry window.

## VERSION HISTORY

• 1.0 - 06/20/2008: Initial release. Supports parsetasks, newtask
• 1.x - 09/03/2009: Modified iNik's script to support new AppleScript terminology used after OF 1.7 update. "activate" changed to "open" for QuickEntry. This version corrects an issue with the QuickEntry window failing to open when the bookmarklet is used in Firefox 3.5.2. Refer to http://forums.omnigroup.com/showthread.php?t=8251 for details.  - kaijin

*)

property theURI : "x-omnifocus"
global tid -- save text item delimiters

-- Test it here
on run
	open location "x-omnifocus://newtask?name=JavaScript%20escape%28%29%20Function&note=The%20escape%28%29%20function%20encodes%20a%20string%2C%20so%20it%20can%20be%20read%20on%20all%20computers.&quickentry=0&context=P"
	
	--open location "x-omnifocus:parsetasks?text=foo
	--bar
	--rawr&single=0"
	
	-- open location "ofinbox://?title=JavaScript%20escape%28%29%20Function&selection=kittykat"
	
end run

(* Open the URI: link *)
on open location sURL
	
	try
		if sURL does not start with (theURI & ":") then error "Malformed URL: " & sURL number 400
		set tid to AppleScript's text item delimiters
		
		set theSplitURL to splitURL(sURL)
		
		set theMethod to (decode_text(item 1 of theSplitURL))
		
		if item 2 of theSplitURL is not missing value then
			set theArgs to my parseArgs(item 2 of theSplitURL)
		end if
		
		if theMethod is "newtask" then
			my newTask(theArgs)
		else if theMethod is "parsetasks" then
			my parseTasks(theArgs)
		else
			error "Method \"" & theMethod & "\" not allowed." number 405
		end if
		
	on error errMsg number errNum
		display alert errMsg & " (" & errNum & ")"
		error number -128
	end try
end open location

on newTask(theArgs)
	-- x-omnifocus://newtask?name=[task name, required]&project=[project name]&context=[context name]&note=[task note text]&quickentry=[1: Use quickentry]
	
	log "newTask"
	log theArgs
	set useQuickEntry to false -- default to no quick entry
	set hasName to false -- Check to see if it has a name, otherwise it'll break
	set theParameters to {}
	set theNote to missing value
	set theContext to missing value
	set theProject to missing value
	set theName to missing value
	
	repeat with x in theArgs
		set xKey to key of x
		set xVal to value of x
		
		
		-- Name
		if xKey is "name" then
			set theName to xVal
			
			-- Note
		else if xKey is "note" then
			set theNote to xVal
			
			-- QuickEntry			
		else if xKey is "quickentry" and xVal is "1" then
			set useQuickEntry to true
			
			-- Project
			-- Match the project to the closest match in the document, error if something doesn't match
		else if xKey is "project" then
			try
				tell application "OmniFocus" to tell default document to get name of first item of (complete xVal as project maximum matches 1)
				set theProject to (result as text)
			on error errMsg number errNum
				if errNum is -1728 then
					error "Project \"" & xVal & "\" not found." number 404
				else
					error errMsg number errNum
				end if
			end try
			
			-- Context
			-- Match the context to the closest match in the document, error if something doesn't match
		else if xKey is "context" then
			try
				tell application "OmniFocus" to tell default document to get name of first item of (complete xVal as context maximum matches 1)
				set theContext to (result as text)
			on error errMsg number errNum
				if errNum is -1728 then
					error "Context \"" & xVal & "\" not found." number 404
				else
					error errMsg number errNum
				end if
			end try
		end if
		
	end repeat -- We have all the arguments now
	
	log "Arguments repeat finished"
	
	if theName is missing value then -- no name, no new task
		error "No name specified. New tasks must have a name." number 406
	else if useQuickEntry is true then
		my makeQuickEntryTask(theName, theNote) -- Context and Project are not scriptable in QE mode
	else
		my makeInboxTask(theName, theProject, theContext, theNote)
	end if
	
end newTask

on parseTasks(theArgs)
	-- x-omnifocus://parsetasks?text=[Text to Parse, HTTP escaped, required]&single=[1: Parse as a single task]
	set theText to missing value
	set single to false
	
	repeat with x in theArgs
		set xKey to key of x
		set xVal to value of x
		if xKey is "text" then
			set theText to xVal
		else if xKey is "single" and xVal is "1" then
			set single to true
		end if
	end repeat
	
	if theText is missing value then -- error, we need transport text
		error "No text specified. New tasks must include text to parse." number 406
	else if single is true then
		tell application "OmniFocus" to tell default document to parse tasks with transport text theText with as single task
	else
		tell application "OmniFocus" to tell default document to parse tasks with transport text theText without as single task
	end if
	
end parseTasks

on makeQuickEntryTask(theName, theNote)
	tell application "OmniFocus" to tell default document
		tell quick entry
			set theTask to make new inbox task with properties {name:theName}
			if theNote is not missing value then set note of theTask to theNote
			select {theTask}
			open
		end tell
	end tell
end makeQuickEntryTask

on makeInboxTask(theName, theProject, theContext, theNote)
	tell application "OmniFocus" to tell default document
		set theTask to make new inbox task with properties {name:theName}
		if theNote is not missing value then set note of theTask to theNote
	end tell
end makeInboxTask

(* Convert a URL into a record set *)
on splitURL(theURL)
	
	
	set uriN to (count of characters of theURI) + 1 -- account for the ":"
	-- Get rid of the url protocol string
	
	set pN to offset of (theURI & "://") in theURL -- is it a mailto:// style?
	
	if pN > 0 then -- a URI:// url
		set theURL to text (uriN + 3) through (count of characters of theURL) of theURL
	else -- or just a URI: url
		set theURL to text (uriN + 1) through (count of characters of theURL) of theURL
	end if
	
	-- See if there's any arguments being passed, pass 'em back if there are
	set aN to offset of "?" in theURL
	if aN = 1 then -- no base url, just arguments
		return {missing value, (text (aN + 1) through (count of characters of theURL) of theURL)}
	else if aN > 1 then
		return {(text 1 through (aN - 1) of theURL), (text (aN + 1) through (count of characters of theURL) of theURL)}
	else
		return {theURL, missing value}
	end if
	
end splitURL

on parseArgs(sArgs)
	set text item delimiters to "&"
	set theArgs to every text item of sArgs
	set text item delimiters to tid
	set rArgs to {}
	
	repeat with xArg in theArgs
		set yArg to (text of xArg)
		set eqOff to offset of "=" in yArg
		if eqOff > 0 then
			set argKey to text 1 through (eqOff - 1) of yArg
			set argValueEncoded to text (eqOff + 1) through (count of characters of yArg) of yArg
			set argValue to my decode_text(argValueEncoded)
			set rArgs to rArgs & {{key:argKey, value:argValue}}
		else
			error "Parameter \"" & yArg & "\" has no value." number 406
		end if
	end repeat
	
	return rArgs
end parseArgs

(* From Apple's sub-routines page *)
-- this sub-routine is used to decode a three-character hex string 
on decode_chars(these_chars)
	copy these_chars to {indentifying_char, multiplier_char, remainder_char}
	set the hex_list to "123456789ABCDEF"
	if the multiplier_char is in "ABCDEF" then
		set the multiplier_amt to the offset of the multiplier_char in the hex_list
	else
		set the multiplier_amt to the multiplier_char as integer
	end if
	if the remainder_char is in "ABCDEF" then
		set the remainder_amt to the offset of the remainder_char in the hex_list
	else
		set the remainder_amt to the remainder_char as integer
	end if
	set the ASCII_num to (multiplier_amt * 16) + remainder_amt
	return (ASCII character ASCII_num)
end decode_chars

-- this sub-routine is used to decode text strings 
on decode_text(this_text)
	set flag_A to false
	set flag_B to false
	set temp_char to ""
	set the character_list to {}
	repeat with this_char in this_text
		set this_char to the contents of this_char
		if this_char is "%" then
			set flag_A to true
		else if flag_A is true then
			set the temp_char to this_char
			set flag_A to false
			set flag_B to true
		else if flag_B is true then
			set the end of the character_list to my decode_chars(("%" & temp_char & this_char) as string)
			set the temp_char to ""
			set flag_A to false
			set flag_B to false
		else
			set the end of the character_list to this_char
		end if
	end repeat
	return the character_list as string
end decode_text

Last edited by kaijin; 2009-09-07 at 10:11 AM.. Reason: Added an entry to Version History details.
 
Still doesn't work for me. I didn't study it line by line, but looks like the above post might still be the original code?
 
The only change I made was in this entry:
Code:
on makeQuickEntryTask(theName, theNote)
	tell application "OmniFocus" to tell default document
		tell quick entry
			set theTask to make new inbox task with properties {name:theName}
			if theNote is not missing value then set note of theTask to theNote
			select {theTask}
			open
		end tell
	end tell
end makeQuickEntryTask
where I changed “activate” to “open”. This corrected the issue where the QuickEntry window failed to open after recent updates to OF and Firefox.

I also reverted the “x-change”, changing “omnifocus:” back to “x-omnifocus:” in the bookmarklet. Making the “x-change” in the bookmarklet; then the bookmarklet and the script—both the orginal and modified versions—did not correct the issue for me.

Interesting to note, while experimenting with the bookmarklet and script, I tested versions and combinations which failed to work. When I then replaced an experimental script with the modified one—the one I posted reflecting only the “open” change, which I knew to work—the QuickEntry bookmarklet failed to function properly until quitting and restarting Firefox. Until quitting and restarting FF, using the bookmarklet—despite pointing to the working modified script—would only produce whatever error message or faulty behavior the replaced experimental script had produced.

The steps that revived a broken QE bookmarklet for me:
  1. Revert the QuickEntry bookmarklet location to:
    Code:
    javascript:window.location='x-omnifocus://newtask?name='+encodeURIComponent(document.title)+'&note='+encodeURIComponent(window.location+'\n\n')+encodeURIComponent(getSelection())+'&quickentry=1';
  2. Replace the OF URI Handler script with the modified version I posted upthread.
  3. Confirm that FF Preferences > Applications > x-omnifocus is set to Use OmniFocus URI Handler (default).
  4. Quit and restart FF.
  5. Test the QuickEntry bookmarklet. (You may be prompted to confirm and open the new application).
 
Quote:
Originally Posted by kaijin View Post
Thanks for the information, Brian! I changed “activate” to “open” within the QE entry in the URI script and the bookmarklet functions correctly now. Here is the the modified script if anyone else is interested.
Very cool! Thanks for the fix!
 
I was not able to copy selected text from a Gmail message into the Omnifocus task note field until I replaced the function call

getSelection()

with the following code

document.getElementById('canvas_frame').contentWin dow.getSelection()

The resulting note isn't pretty. Some end-of-line characters get translated into other characters, but it's good enough for my purposes.

Here's the entire script:
Code:
javascript:window.location='x-omnifocus://newtask?name='+encodeURIComponent(document.title)+'&note='+encodeURIComponent(window.location+'%5Cn%5Cn')+encodeURIComponent(document.getElementById('canvas_frame').contentWindow.getSelection())+'&quickentry=0';
I am unable to get the quick entry script provided by kaijin to work. If I have the Quick Entry window open it will populate it with the new task, but it will not open the window and bring it to the foreground. No success with either FF or Safari.
 
The changes suggested here got it working for me in FF, but not in Safari or Fluid.app. Too bad, this was a cool thing and working quite well in 1.6.

If anyone has any suggestions Safari/Fluid, please let me know.
 
Nice job on the script!! 1 prob, for some reason it will not recognize the &project parameter. Everything works except that it ignores this parameter and chucks it in the inbox, both with quickentry 1 or 0.
 
 




Similar Threads
Thread Thread Starter Forum Replies Last Post
How to BCC tasks to Omnifocus [A: use Omni Sync Server's "Mail Drop" feature.] isadore.braun OmniFocus 1 for Mac 1 2013-03-20 01:56 PM
Please take note Omni Group! Deedubau OmniFocus for iPhone 3 2012-10-16 11:54 AM
Script to locate tasks with a certain date in a note daltongreen OmniFocus Extras 4 2011-01-20 10:07 AM
Please add some type of note indicator to tasks oschultz OmniFocus for iPhone 5 2009-05-12 05:08 PM
Tasks failure (The Apple Event Handler Failed) wycats OmniFocus Extras 1 2007-11-23 09:04 PM


All times are GMT -8. The time now is 08:56 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.