Getting a Hyperlink of the Last Sent Message from Mail.app using Applescript

 Posted on 
 and last updated January 15, 2018
 ·  6 minutes reading time

I've been a fan of Getting Things Done as a technique for managing projects, but it was only recently that I settled on OmniFocus as the "trusted system" collecting all of my next actions. One of the things I like about OmniFocus -- as a rich, Mac-only application -- is its ability to hold links to messages from Mail.app as notes for each action. This occurs, for instance, when you use the "Clippings" function of OmniFocus to create a new action based on the message that you are currently viewing in Mail.app. (There are other ways to do it, such as the method described by Adam Sneller.)

One of the things I find myself doing is creating actions in a "Waiting" context based on e-mail messages I've just sent. Initially, I'd just create the action via the OmniFocus Quick Entry window. But I found myself needing to refer back to the message I sent when the person I'm waiting on doesn't come through. So I started clicking and dragging the message from the Sent mailbox to the action. But to do that I'd have to click into the Sent mailbox and have the Mail.app and the OmniFocus windows set up just right. Or I'd have to follow a select-sent-mailbox, select-message, OmniFocus-quick-entry-with-clipping, select-Inbox, select-next-message workflow. And that took time and effort. So I've created an AppleScript ditty that does the work of creating a hyperlink on the clipboard of the last sent message. The results can then be pasted into any RTF-aware application, including OmniFocus.

The script is based heavily on Speedy creation of rich text links to Mail messages by Brett Terpstra. In particular, he had the missing link about creating RTF hyperlinks on the clipboard using a bash shell script. The meat of the AppleScript is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
tell application "Mail"

    -- Ask the user which account to use
    set _accts to get accounts
    set _enabledAccounts to {}
    repeat with eachAccount in _accts
        -- Only offer the enabled accounts for the user to choose
        if enabled of eachAccount then
            set the end of _enabledAccounts to name of eachAccount as string
        end if
    end repeat
    set _selectedAccount to (choose from list _enabledAccounts with title "Select Account" with prompt "Select the account from which to copy a link of the last sent message..." default items (item 1 of _enabledAccounts))

    -- Quit script if the user selected "cancel"
    if _selectedAccount is false then
        return
    end if
    set _selectedAccountName to _selectedAccount as string

    -- Get the "last" message of the Sent mailbox of the selected account
    set _msg to first message of mailbox "Sent" of account _selectedAccountName

    -- Get various properties of the message
    set _date to _msg's date sent

    try
        set _recipient to name of first recipient of _msg
        set _test to _recipient
    on error
        -- if the Recipient's name property was blank, use the e-mail address instead
        set _recipient to address of first recipient of _msg
    end try

    set _sub to _msg's subject
    if _sub starts with "Re:" then
        -- Remove the "Re:" prefix from messages
        set _sub to text 5 through (length of _sub) of _sub
    end if

    set _msgid to _msg's message id

    -- Create the URL to the message
    set _msglnk to "message://%3C" & my urlencode(_msgid) & "%3E"

    -- Create the anchor text for the link
    set _anchorText to "Message sent " & _date & " to " & _recipient & " regarding '" & _sub & "'"

    -- Execute the external script to generate the RTF hyperlink on the clipboard
    do shell script "/bin/bash -c \"" & _script & " \\"" & _anchorText & "\\" \\"" & _msglnk & "\\"\""
end tell

It first prompts the user for which account to use based on the list of active accounts. Then it gets the last message in the Sent mailbox of that account, gets various metadata properties, and sends the results to the bash shell script. The shell script comes from Brett; it creates the RTF snippet and pipes it into 'pbcopy' to put it on the clipboard:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash
# Places a rich text link on the clipboard
# usage: rtflink.sh "Title of link" "URL to link to"
#
# This will paste *nothing* into applications that don't recognize rich text

echo "{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
{\field{\*\fldinst{HYPERLINK \"$2\"}}{\fldrslt 
\f0\fs24 \cf0 $1}}}" | pbcopy -Prefer rtf

The end result is a hyperlink with an anchor that looks something like:

    Message sent Thursday, May 15, 2008 8:36:33 AM to Jane Partner regarding 'Can you pick up milk?'

...waiting on the clipboard to be pasted into an action note. With that bound to a keyboard trigger via QuickSilver, copying a link to a message is now a simple matter of keystrokes.

If you are interested, you can download the "Copy last sent message as RTF link" AppleScript bundle and try it yourself. Let me know what you think.

Update 20080516T1219 : I had to modify the part of the code that gets the recipient name or (for recipients without name parts) the e-mail address. The downloaded version has been updated.

Update 20110405T1946 : The script has been improved! See this thread on the Omni Group forums for the update. Thanks to whpalmer4 for the modifications.

The text was modified to remove a link to http://docs.blacktree.com/quicksilver/triggers on January 28th, 2011.