Templated Mail Replies in macOS Mail.app

This is an old post!

This post is over 2 years old. Solutions referenced in this article may no longer be valid. Please consider this when utilizing any information referenced here.

So one of the downsides to corporate life can be dealing with the deluge of email. While Slack is the new hotness for communicating inside companies, when dealing with outside people or organizations email is still the lingua franca of communication. But the downside to that is that you sometimes have to deal with repetitive emails.

One in particular I have noticed over the last few years being more and more common is people reaching out to me wanting to get content on DealNews, or in some other way work with our marketing or business development teams. It is starting to get so common that I get it several times a month, and the reply is always the same: I don’t have editorial control over what content appears on the website, please reach out to these web addresses.

But typing this out every time is annoying. There should be a way to automate this. After all, anything worth doing twice is worth automating.

Surprisingly, there does not seem to be a way to have “templated responses” in Mail.app. This seems a curious omission given how otherwise surprisingly full featured the built-in mail client is. But we do have other options: namely we have Applescript.

After doing some reading and trial and error, this is what I came up with:

set theFile to ("Macintosh HD:Users:peckrob:Development:Dotfiles:data:mail:dealnews-marketing.txt")
set theFileContents to paragraphs of (read file theFile)

tell application "Mail"
    set theSignatureName to "dealnews"
    set theMessages to selected messages of first message viewer
    set theMessage to first item of theMessages
    set theOutgoingMessage to reply theMessage with opening window and reply to all
    tell theOutgoingMessage
        tell application "System Events" to tell process "Mail"
            set frontmost to true

            tell window 1
                tell scroll area 1
                    tell UI element 1
                        tell group 3
                            tell static text 1
                                repeat with theItem in theFileContents
                                    keystroke theItem & return
                                end repeat
                            end tell
                        end tell
                    end tell
                end tell
            end tell
        end tell

    end tell
end tell

So this is pretty hacky, so we’ll step through it.

  1. First, we set the file path and read the file. Remember, Applescript is old and still uses the : HFS path separators. In this case we read a file path into an array of paragraphs.

  2. We open the selected email for a reply. This puts the text quoted in the body and inserts the cursor at the top of the message.

  3. We descend the control tree hierarchy of the mail reply until we reach the text box, then loop the paragraphs from the file into the message.

I decided the best way to handle running it is Alfred. I can just type “marketing” and it pops up with the script. From there, hit Return and it runs the script and generates the reply email. You could optionally have it even send the email for you, but actions like that I want to take the human step of pushing “Send.”

Hat tip to this thread that helped me figure most of this out.

Comments (0)

Interested in why you can't leave comments on my blog? Read the article about why comments are uniquely terrible and need to die. If you are still interested in commenting on this article, feel free to reach out to me directly and/or share it on social media.

Contact Me
Share It
Every day, when I get to work, there are a number of tasks I do. Among the first thing I do is connect to a number of servers via SSH. These servers - our development testing, staging, and code rolling servers - are part of the development infrastructure at dealnews. So every morning, I launch iTerm, make three sessions and log into the various servers. Over time, I’ve written some helper scripts to make this faster. My “go” script contains the SSH commands (using keys) to log into these machines so that all I have to do is type “go rpeck” to log into my development machine. Still, this morning, the lunacy of every morning having to open iTerm and execute three commands, every day without fail, struck me. Why not script this so that, when my laptop is plugged into the network at work, it automatically launches iTerm and logs me into the relevant services? Fortunately, iTerm exposes a pretty complete set of AppleScript commands, so with a little work, I was able to come up with this: tell application "System Events" set appWasRunning to exists (processes where name is "iTerm") tell application "iTerm" activate if not appWasRunning then terminate the first session of the first terminal end if set myterm to (make new terminal) tell myterm set dev_session to (make new session at the end of sessions) tell dev_session exec command "/Volumes/iDisk/bin/go rpeck" end tell set staging_session to (make new session at the end of sessions) tell staging_session exec command "/Volumes/iDisk/bin/go staging2" end tell set nfs_session to (make new session at the end of sessions) tell nfs_session exec command "/Volumes/iDisk/bin/go nfs" end tell select dev_session end tell end tell end tell What this little script does is, when launched, checks to see if an instance of iTerm is already running. If it is, it just creates a new window, otherwise creates the first window, then connects to the relevant services using my “go” script (which is synchronized across all my Macs by MobileMe). Then, with it saved, I wrap it in a shell script: #!/bin/bash /usr/bin/osascript /Users/peckrob/Scripts/launch-iterm.scpt And launch it with MarcoPolo using my “Work” rule that is executed when my computer arrives at Work. Works great!
Read More
At dealnews, we have an internal Jabber server that we use for our internal communications. As part of that, we have a number of internal chat rooms for the various areas of the company. I’m a big believer in automation - that is, scripting various repetitive actions that I have to do every so often. One of these little things is joining our developer chat channel each morning when I get to the office. Unfortunately, there’s no built in way in Adium to do this, nor does Adium expose native AppleScript commands to join group chat. It does for other functions, but group chat functionality is conspiciously absent, even though there’s a long standing feature request to implement this. So, we have to hack it. In this case, I used AppleScript to imitate keyboard input set CR to ASCII character of 13 tell application "System Events" tell application "Adium" to activate keystroke "j" using {command down, shift down} keystroke "development" keystroke CR end tell So we have a script, but how to automate the launching of it? I mentioned MarcoPolo before. It has quickly become one of my favorite pieces of Mac software. In this case, I use MarcoPolo to launch the AppleScript (with a 10 second delay to allow time for Adium to start and connect to the Jabber service). You can launch AppleScripts using the osastart utility like so: /usr/bin/osastart /Users/codelemur/Scripts/DevChat_AutoJoin.scpt It sucks that it’s like this, and I wish they would expose a more native way to do this, but it does work.
Read More
Download I recently added a Mac mini to my setup at home, that I’m using to drive my in-home “video on demand” system. With many of the TV’s in the house on AppleTVs, any TV in the house can watch any movie in the library at any time. I put the mini (headless) in the closet, along with the Drobo and a printer. But, the new Mac mini lacks an optical drive. So, how to continue ripping the DVDs I already own? The solution, it turns out, is to continue doing the actual work on my iMac when it comes to ripping, filtering the files through iDentify and MetaX. But I don’t want to have to go to screen sharing on the Mini and add a file to iTunes. I want that to happen automatically. That’s where Automator - one of the most underrated pieces of software that comes with every Mac - comes in. With Automator, you can attach an action to a folder, so that that action will be performed whenever anything is added to that folder. So here’s what I did to get files from a folder into iTunes: Create a folder somewhere on your system. I put mine in my user directory. Open Automator. From the dialog box, select “Folder Action.” At the top, where it says “Folder Action receives files and folders added to,” select “Other” and select your new folder. Search for an action called “Set Var of Value”. Drag that action over to the right. From “Variable” select “New Variable.” Call it “Source” Search for an action called “Import Files into iTunes”. Drag that action over to the right underneath the variable action. Be sure to select “Library” from the empty dropdown. Search for an action called “Get Var of Value”. Drag that action over to the right underneath the iTunes action. Be sure the selected variable is “Source”. Search for an action called “Move Finder Items to Trash”. Drag that action over to the right. Search for an action called “Run AppleScript.” Drag that action over to the right. In the AppleScript action, paste this: on run {input, parameters} tell application "Finder" to empty trash return input end run Save the action. You’re done.
Read More