Link to New with Agenda and x-callback-url

  1. Home
  2. Docs
  3. Help & Support
  4. Integration
  5. Link to New with Agenda and x-callback-url

If you just want to be use Hook to Link to New Agenda notes, skip to the end of this article and follow the instructions there.

For a more detailed explanation, read on.

Link to New with x-callback-url

For some applications (e.g. Ulysses, Bear, Agenda) the best or only way to create new items programmatically is with x-callback-url.

Agenda’s create-note x-callback-url

Agenda’s x-callback-url support is documented here.

set newNoteURL to "agenda://x-callback-url/create-note?title=" & encodedTitle & "&project-title=" & projectTitle

newNoteURL is an x-callback-url which makes a new note in Agenda.

The parameters are passed as URL query values and must be percent encoded. This can be done with a simple one line python shell script.

title

The standard behaviour of Link to New is to name the new item after the source item it is being created from and linked with. Hook will subsititute the title for $title before executing the script.

set encodedTitle to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of "$title"

project-title

Agenda does not have a default project for new unassigned notes, so user must edit the script to specify the project they want to create new notes in.

set projectTitle to "Hook notes"
set projectTitle to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of projectTitle

x-success

The x-success parameter is a URL. If Agenda successfully creates the note described in the create-note x-callback-url, it appends a query specifying the new note’s ID, and calls it.

set newNoteURL to newNoteURL & "&x-success=" & callbackURL

Hook’s link-to-new x-callback-url

set callbackURL to "hook://x-callback-url/link-to-new?src=" & doubleEncodedSrc & "%26partialURL=agenda://note/%26identifierKey=note%26title=" & doubleEncodedTitle

callbackURL is called with the information Hook needs to link the new note with the source item. Because callbackURL is itself a query value, it must be percent encoded (notably the &s are encoded to %26) and any query values in it must be double encoded, so that they are still encoded when callbackURL is decoded and called.

$encoded_src is the URL of the source item which Link to New was called on. It is used by Hook to link the new Agenda Note to the original item. Since it is a query value of a URL which is the value of a URL query, it is double encoded

hook://x-callback-url/link-to-new
    ?src=<doubleEncodedSrcURL>
    &title=<doubleEncodedTitle>
    &identifierKey=note
    &note=<identifier>
    &partialURL=agenda://note/

src

The URL of the source item. Since x-callback-URLs work asynchronously, by the time Agenda creates the note and calls back to Hook, Hook may not be open on the source item, so the link-to-new URL must include a reference to it.

This value must be double encoded.

set doubleEncodedSrc to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of "$link"
set doubleEncodedSrc to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of doubleEncodedSrc

title

The title parameter specifies the title of the linked item. The title must also be double encoded.

set doubleEncodedTitle to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of encodedTitle

identifier, identifierKey, note

The identifier of the new item given by x-success should be keyed to identifier.

But the create-note x-success callback keys the identifier of the new note under note, not identifier.

The link-to-new callback can use identifierKey to designate a different query key to find the identifier

&identifierKey=note&note=<note-identifier>

partialURL

Since the create-note x-success callback only includes the identifier of the new note, not the whole URL, we give the first half of the URL here. The identifier is appended to it into the whole URL which is linked together with src.

We haven’t encoded Agenda’s partialURL because it is a static string and we know with certainty that partialURL=agenda:// doesn’t contain any characters which will break the URL if they’re not encoded.

return placeholder URL

The last line of the script has to be get "hook://link-to-new-callback", because Hook expects it to return the address of the new document. Since the linking is done with x-callback, we don’t need to return a valid URL and return “hook://link-to-new-callback”, a placeholder.

Integrating Hook to Link to New Agenda notes

  1. Copy the following script to the Link to New script field for Agenda in Hook Preferences>Scripts.
  2. Replace “Hook notes” in the first line (set projectTitle to "Hook notes") with the project of your choice. Agenda doesn’t have a default project for new notes, it has to be specified.
set projectTitle to "Hook notes"
set projectTitle to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of projectTitle

set encodedTitle to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of "$title"

set newNoteURL to "agenda://x-callback-url/create-note?title=" & encodedTitle & "&project-title=" & projectTitle

set doubleEncodedTitle to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of encodedTitle

set doubleEncodedSrc to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of "$link"
set doubleEncodedSrc to do shell script "python -c \"import urllib, sys; print (urllib.quote(sys.argv[1]))\" " & quoted form of doubleEncodedSrc

set callbackURL to "hook://x-callback-url/link-to-new?src=" & doubleEncodedSrc & "%26partialURL=agenda://note/%26identifierKey=note%26title=" & doubleEncodedTitle
set newNoteURL to newNoteURL & "&x-success=" & callbackURL
do shell script "open '" & newNoteURL & "'"
get "hook://link-to-new-callback"
Was this article helpful to you? Yes No

How can we help?