Using AppleScript to save attachments in Outlook for Mac OS

Breaking the sandbox

Situation

You want to automatically save your attachments for some e-mails in Outlook for Mac OS. Outlook Rules does not allow you to save attachments somewhere. AppleScript to the rescue.

Outlook AppleScript: Save attachment

In the more recent versions of Outlook for Mac OS though, a sandbox is in place. So if you try to save an email attachment to a folder of choice, you will get an user-friendly and nice error.

Result:
error "Microsoft Outlook got an error: An error has occurred." number -2700

See! It took me quite a bit of googling to figure out this was related to the new sandbox introduced in Microsoft Outlook. So, you cannot directly save messages to your Documents folder (or anywhere outside of the sandbox) from within AppleScript.

The workaround is to first store attachments inside the document folder inside the Outlook Sandbox and then move them around.

In this article we first look at separate functional snippets of our needed functionality. At the end we bring it all together into a single script.

Creating a temporary folder

First you will learn to use AppleScript to create a temporary folder within the Outlook sandbox to store our attachments, if it does not already exist. Within AppleScript you will tell Finder to create the directory if it does not yet exist.

For that we first need to create the folder for use in AppleScript (in the internal notation like SSD:Users:XXX:Library:Containers:com.microsoft.Outlook:Data:Documents:Attachments). And then we instruct Finder to check and create the folder for us.

tell application "Microsoft Outlook"
    set sandboxDocumentFolder to (path to documents folder as string)
    set sandboxAttachmentsFolder to sandboxDocumentFolder & "Attachments"

    tell application "Finder"
        if not (exists sandboxAttachmentsFolder) then
            make new folder at sandboxDocumentFolder with properties {name: "Attachments"}
        end if
    end tell
end tell

Constructing the filename

When saving attachments, you often run into attachments that have identical names. In case of invoices it’s useful to organize them when saving, for instance by prepending the date to the filename.

In order to use the date in the highly sortable YYYY-MM-DD format we first extract the date from the selected e-mail and split it into a year, month and day variable. We then format the timestamp using the date and a small padding function.

tell application "Microsoft Outlook"
    set msg to first item of (get current messages)
    set {year:y, month:m, day:d} to (get msg's time sent)
    set timeStamp to ("" & y & "-" & my pad(m as integer) & "-" & my pad(d))
end tell

on pad(n)
    return text -2 thru -1 of ("00" & n)
end pad

Saving e-mail attachments

Now we are ready to save our e-mail attachments to a folder of our choice using AppleScript. We tell Outlook to iterate over the e-mail’s attachments, save each of them with our name into the temporary Attachments folder and then move them to the proper directory.

tell application "Microsoft Outlook"
    set msg to first item of (get current messages)
    set sandboxDocumentFolder to (path to documents folder as string)
    set sandboxAttachmentsFolder to sandboxDocumentFolder & "Attachments"
    set storeFolder to "SSD:Users:XXX:Documents:Store"
    set allAttachments to attachments of msg

    repeat with thisAttachment in allAttachments
        set saveName to name of thisAttachment
        set destName to sandboxAttachmentsFolder & ":" & saveName
        save thisAttachment in destName

        # Move to correct folder
        tell application "Finder"
            if not (exists storeFolder) then
                display dialog "Destination directory '" & storeFolder & "' not found" with icon 1
            return
            end if

            move destName to storeFolder with replacing
        end tell
    end repeat
end tell

Bringing it all together

Now that you learned how to do all the separate parts of saving attachments with a new name to your folder, let’s bring it all together into a single script.

tell application "Microsoft Outlook"
    repeat with msg in (get current messages)
        set sandboxDocumentFolder to (path to documents folder as string)
        set sandboxAttachmentsFolder to sandboxDocumentFolder & "Attachments"
        set storeFolder to "SSD:Users:paul:Documents:Store"
        set allAttachments to attachments of msg
        set {year:y, month:m, day:d} to (get msg's time sent)
        set timeStamp to ("" & y & "-" & my pad(m as integer) & "-" & my pad(d))

        tell application "Finder"
            if not (exists sandboxAttachmentsFolder) then
                make new folder at sandboxDocumentFolder with properties {name:"Attachments"}
            end if
        end tell

        repeat with thisAttachment in allAttachments
            set saveName to timeStamp & " - " & name of thisAttachment
            set destName to sandboxAttachmentsFolder & ":" & saveName
            save thisAttachment in destName

            # Move to correct folder
            tell application "Finder"
                if not (exists storeFolder) then
                    display dialog "Destination directory '" & storeFolder & "' not found" with icon 1
                    return
                end if

                move destName to storeFolder with replacing
            end tell
        end repeat
    end repeat
end tell

on pad(n)
    return text -2 thru -1 of ("00" & n)
end pad
outlook applescript email
comments powered by Disqus