Add attachments to Mail.app from the command line

If you spend a large part of your day in the console, like we do, you’d like to have all sorts of nifty tools to be able to direct your complete OS from there. Fortunately, we’re on OS X and AppleScript makes this pretty easy. Despite its somewhat unruly looking syntax, which (quite succesfully) tries to be as close to normal English as possible, I still like to toy around with it once in a while.

The ‘toy’ I’ve written today however is pretty useful. It lets you attach files to an email from the console. Instead of having to reach for the mouse and navigate to the folder you’re already in, you can just do mailfile checkthis.tar.gz. If you already started on an email the file will be attached to the draft, else it will open up a new compose window and you’re good to go!

#!/usr/bin/osascript
 
on run argv
  if argv is {} then
    return "Pass at least one filename as an argument!"
  end if
 
  set pwd to system attribute "PWD"
 
  tell application "Mail"
    try
      set composeMessage to first outgoing messages where visible is equal to true
    on error
      set composeMessage to make new outgoing message at beginning with properties {visible:true}
    end try
 
    tell composeMessage
      repeat with fileName in argv
        if not fileName starts with "/" then
          set fileName to pwd & "/" & fileName
        end if
        tell content
          make new attachment with properties {file name: fileName} at after the last paragraph
        end tell
      end repeat
    end tell
 
    activate
 
  end tell
end run

Place this code for in /usr/local/bin/mailfile (or some other ‘bin’ dir that’s in your path), and make it executable. You can also download it from github.

I think the code is pretty readable. You might notice that attachments are just added to the content of the email, there is no concept of attachments outside of the content. You might also notice how I totally inappropriately abuse the exception catching mechanism for something I could have tested before. In my defense I’d like to say this is just a simple script and it uses less code this way ;)

Something that took me a while to figure out was how to get the current working directory, which I needed because else it could only handle full paths. Turns out the script needs a bit of help from the environment variables or ’system attributes’ as they are called in AppleScript.

My first try was to find the directory the script itself is in, which is not the way to go when you want to put it somewhere central. But because there is a lot of bad/old information on how to do that online, I’d still like to share the following code snippet

  tell application "System Events"
    set pwd to POSIX path of container of (path to me)
  end tell

Note that I’m using “System Events” here and not the Finder.


About this entry