Tuesday, July 26, 2022

Mail Links and Percentages

Dr. Drang:

Yesterday, John Voorhees wrote a nice article at MacStories about creating links to specific email messages. His system is in the form of a Shortcut, but the real work is done by an AppleScript. The AppleScript is an extension of one John Gruber wrote 15 years ago.

[…]

The questions I needed to answer were:

  1. Are reserved characters used in message IDs?
  2. If so, do they need to be percent-encoded in a message URL?

[…]

None of the reserved characters caused a problem except the percent sign itself.

However, that does not mean that the strings are valid URLs, and in fact even putting the message ID in unencoded angle brackets will prevent it from working with NSURL. I think what’s happening here is that Mail is receiving the URL as a string and removing the percent escapes directly, without actually parsing it as a URL.

So, if you store unencoded links you are setting yourself up for trouble if Mail changes how it works, if you ever want to redirect the message: scheme to a different app, or if you want to detect message: URLs that are embedded in a document. Lots of e-mails unfortunately don’t follow the specification, and I’ve seen Message-ID headers that include the " and ) characters, as well as spaces, which could mess up the way Markdown interprets the links.

If you want to handle more than the percent symbol, here’s an AppleScript that will escape the other characters, too:

use AppleScript version "2.4"
use framework "Foundation"

on URLFromMessageID(_messageID)
    set _components to my NSURLComponents's alloc's init
    _components's setScheme:"message"
    _components's setHost:("<" & _messageID & ">")
    return _components's |URL|'s absoluteString() as Unicode text
end URLFromMessageID

Another issue to be aware of is that the Message-ID header sometimes includes text outside of the angle brackets. This should not be included in the URL. However, if you are using Mail’s message id AppleScript property, as Gruber’s script does, it will remove the extraneous text for you (just as it removes the angle brackets themselves).

Previously:

But 15 years after adding support for these URLs, Apple still hasn’t exposed a direct way to copy them from any given message other than drag-and-drop.

7 Comments RSS · Twitter

Well, at the risk of self-promoting: Hook (our app) already provides the ability to create links to messages on macOS across several major email apps (Airmail , Mailmate, Fastmail, Postbox Mac app) https://hookproductivity.com/what-mac-apps-are-compatible-with-hook-app#comm ,with other apps in pipeline. John Voorhees Shortcut could simply call Hook's AppleScript to get a link to the current email. Users can change the default app with which to open such email links at any point (instead of being locked into Apple Mail). Shortcuts support is coming to Hook very soon, as is the iOS and iPadOS version, so you can open these links on iPhone/iPad too. Hook handles messageID encoding issues, per RFC-5322, saving automators some trouble there. (And it's compatible in other ways with EagleFiler).

Readdle's Spark email app (which Voorhees 's post referred to) does not provide an AppleScript API to get a link to the currently selected or open email. So we currently rely on UI scripting. However, apparently Readdle will provide an API in the future to get the link (name and URL); but I don't know whether it will return Spark's app-specific URL format or something that is RFC-5322 compliant. Ideally Spark and other email app vendors who provide a "copy link" API , where the URLs includes the encoded RFC-5322 ID in their URLs.

Beatrix Willius

What is the code supposed to do? I only get "message:" as result on Ventura.

@Luc Thanks!

@Beatrix You have to call the handler, e.g. my URLFromMessageID("the message id").

Beatrix Willius

@Michael Tsai: Using

set MessID to my urlfrommessageid("20220710082029.40A30298AA3@d167.x-mailer.de")

I get "message:" as result.

@Beatrix I’m not sure why. That gives me message://%3C20220710082029.40A30298AA3%40d167.x-mailer.de%3E.

> the ability to create links to messages on macOS across several major email apps (Airmail , Mailmate, Fastmail, Postbox Mac app)

as luck would have it, I forgot to mention Apple Mail in that list. I.e., if on an email message in Apple Mail you invoke Hook's context-sensitive window and issue the `Copy Link` ( ⌘C) or `Copy Markdown Link` (⌘M) you'll get a link to the email (URL and email). Paste the former in a well-designed plain text app ( like BBEdit ) and you get just the URL. (or call Hook's AppleScript)

> you'll get a link to the email (URL and email).
getting late here. I meant: "you'll get a link to the email (URL and subject of the email)."

Leave a Comment