Applescript to get email link not working

I had implemented MacSparky’s Applescript to link email message successfully for many years.

I have recently upgraded to an Apple Silicon MBP 14".

When I run the script (through a Textexpander shortcut) now, I get the dialog:

sh: /usr/bin/python: No such file or directory

I have checked the script - it hasn’t become corrupted.

I have no idea what the dialog means or how to fix it so any thoughts or help would be much appreciated!

What version of MacOS are you running?

/usb/bin/python is the python interpreter, version 2.7, which has shipped with OS X and the MacOS for years. That version is now deprecated (the python.org website indicates that python version 2 is at end of life). Apple announced some time ago that python 2.7 was going to be removed from MacOS, but I am not certain with which version.

Anything dependent on python 2.7 will break, and will require an upgrade of the software to python 3 and installation of python 3 on MacOS. I do not believe that MacOS will include python 3 by default. It can be installed using homebrew, direct download from python.org, through the XCode online tools, etc. At least in the past, there was a stub installed so if you issued the “python3” command in the Terminal you would get a message telling you how to install it. I don’t know if this is still the case as I have it installed through XCode and so cannot check.

To me this is a pain. It was time for Apple to remove 2.7 which is at end of life, but I wish Apple just automatically included 3.

As a aside, if it is not clear why you need python to run an AppleScript, look at MacSparky’s script that you lined to. The line that starts with “set msgID to do shell script” is running a python command that takes the message ID of the selected email message and makes sure that any characters in it that are not “URL safe” are fixed. [That’s why, for example, you may have noticed that a URL with a space in it appears with the space as ‘%20’ in the web link, because URLs cannot have embedded spaces and so the space is represented as %20.]

It would, unfortunately, be a pain to implement this functionality completely in AppleScript, as AS is just not designed to handle extensive text manipulations very well.

As an aside, this script should break for everyone when they upgrade to the latest version of MacOS and /usr/bin/python goes away. I will have to check my own KM macros that do this, as I probably used python 2 myself when I wrote them. I have a large number of KM macros and freestanding scripts in python that I have written over time, and it’s been a process to get everything converted.

did you check if the directory exists?
I think it;s to do with the fact that the python directory probable now is python3

You can change the python directory reference in the script to match
To do that in the script change "do shell script “/usr/bin/python” to read "do shell script “/usr/bin/python3”

or alternatively use this applescript without the python bit:

tell application "Mail"
	set _sel to get selection
	set _links to {}
	repeat with _msg in _sel
		set _messageURL to "message://%3c" & _msg's message id & "%3e"
		set end of _links to _messageURL
	end repeat
	set AppleScript's text item delimiters to return
	set the clipboard to (_links as string)
end tell
1 Like

@JKoopmans: Well said, and inexplicable much more to the point than my opus.

Assuming that there are no “URL unfriendly” characters in the message id, this will do the job. I don’t know if that is the case, but it turns out my own KM macros for this purpose make the same assumption, and so far, so good.

As far as I know, python3 will not be included by default with MacOS, and will require a manual install. Can anyone verify that?

The syntax will also need changing, in that the urllib library is different in python3 compared with python2. I think the syntax will need to be:
/usr/bin/python3 -c ‘import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))
but I would have to check that.

1 Like

I got my script from a blogpost by Colter Reed from 2015, and it has been working rock solid since then

Wow!

Thank you both, Neal and Jkoopmans.

I had no idea that anything to do with python was involved.

As it’s a new Apple silicon MBP 14”, the computer is running Monterey.

I have done a few things in homebrew before but I think I will try jkoopmans script first.

1 Like

At the risk of boring everyone out of their minds, here’s what’s going on.

At some point release in the Monterey series (macOS 12.3, I believe), Apple followed through on its longstanding deprecation warning and removed Python 2, the command for which was at /usr/bin/python. Any scripts that rely on that command will fail.

Apple added a new command at /usr/bin/python3. You might think that this is a Python 3 command, but—initially, at least—it isn’t. It’s a stub program that asks you if you want to install the Command Line Tools for XCode (which includes Python 3). If you go ahead and install the tools, then /usr/bin/python3 will run Python 3.

But even if you go through this and change the /usr/bin/python to /usr/bin/python3 in David’s script, it still won’t run because Python’s libraries changed in the switch from 2 to 3. There are still ways to URL-encode the message ID, but the functions are different now.

So is it OK to use a script that doesn’t include URL-encoding? As far as I can tell, yes. The only reserved character that shows up in message IDs is the ampersand (@), and it’s appearance doesn’t seem to affect the ability of the message:// URL to work. Reserved characters “sometimes” have a special meaning and need to be encoded—this isn’t one of those times. So @JKoopmans’s experience without the encoding step makes sense.

2 Likes

Thanks, Dr Drang.

I won’t pretend to understand that fully but it is useful as it confirms the solution path is not simply to upgrade to python 3.

OK. So I have tried the script provided by Jkoopmans.

It works as advertised. Unlike Macsparky’s script, however, it seems one has to execute the paste command after running the script. Leastwise, that is what happens when I run the script in either Textexpander or Keyboard Maestro - after the script runs I get a blinking cursor at the insertion point and then have to type command-v to paste in the link.

So I added after "set the clipboard to (_links as string) the commands

“tell application “System Events”
keystroke “v” using {command down}
end tell”

Seems to work

For ease of reference, the whole modified script is:

(*
Returns a link to the first selected Apple Mail message
*)
tell application “Mail”
set _sel to get selection
set _links to {}
repeat with _msg in _sel
set _messageURL to “message://%3c” & _msg’s message id & “%3e”
set end of _links to _messageURL
end repeat
set AppleScript’s text item delimiters to return
set the clipboard to (_links as string)
tell application “System Events”
keystroke “v” using {command down}
end tell
end tell

1 Like

You can try @MacSparky’s script with a little surgery to get rid of the Python stuff:

tell application "Mail"
	set _msgs to selected messages of message viewer 0
	if (_msgs is not equal to missing value) then
		set _msg to first item of _msgs
		return "message://%3C" & (message id of _msg) & "%3E"
	end if
end tell

Differences between this and the @JKoopmans script:

  • This one doesn’t put anything on the clipboard.
  • This one returns a link to just the first selected message; the other returns links to all the selected messages.

Recall that the @MacSparky script was intended to be used inside a TextExpander snippet. That’s why it just returns the URL—TextExpander takes the output of a script and inserts it.

1 Like

Thanks.

Yes that does the trick.

I was wondering why, when I had selected an email thread the other script was pasting multiple links. I didn’t make the connection.

FWIW, I think I might have been the one to send @MacSparky the script referenced by the OP. When I upgraded to Monterey, I had to change the Python bits to use Python 3. The updated script is as follows:

[Redaced, use this script instead]

I totally missed this post by @drdrang. Use his updated script, Python used to be bundled with Mac OS X, so mine won’t work if you haven’t installed Apple’s Command Line Tools.

Thanks.

Yes Dr Drang’s updated script works well in Monterey either in TextExpander or Keyboard Maestro.

1 Like

I would’ve called it your script instead of @MacSparky’s if I’d known your handle here. David uses your Twitter handle in the post.

1 Like

To get some more scripts in here :wink:
I am using a different Apple Script now for a while that I also got from @MacSparky. I think I got my one from his KMFG, or one of his related blog posts.

tell application "Mail"
	set selMessages to selection
	if (count selMessages) > 0 then
		set thisMsg to item 1 of selMessages
		set thisMsgURL to "message://%3c" & (message id of thisMsg) & "%3e"
		tell me to set the clipboard to thisMsgURL
		display notification "Message from " & sender of thisMsg & ", subject: " & subject of thisMsg with title "Message Copied"
	else
		display notification "Nothing selected."
	end if
end tell

P.S.: Is there a way to post a script here, with its “color code” still visible?

To color a blow of code, you can use the Markdown code block syntax, wrapping the code block in three backticks (e.g. ```). Note, the wrapping backticks need to be on their own line.

1 Like

Thank you! :grinning:
(20 characters)

Sorry I was checked out on this one gang. Been super busy. Glad it’s sorted.

1 Like