Apple script fail on copying attachment from Outlook

applescriptms office

I'm trying to copy all the attachments that I received from a certain sender (scanner) to a folder. I'm using Outlook and I've tried to write a script to do the job. It fails on saving the file with error code:

error "Microsoft Outlook got an error: Parameter error." number -50

Unfortunately I've not been able to figure out a) what that error means, and b) how to make the script work. Any help is welcome.

This is my script:

set saveToFolder to (choose folder with prompt "Choose the destination folder") as string
set ctr to 0

tell application "Microsoft Outlook"
    set srcFolder to mail folder "inbox" of exchange account "FOO"
    set selectedMessages to messages of srcFolder
    repeat with msg in selectedMessages
        set ctr to ctr + 1
        set msgsender to the sender of msg
        set senderaddress to the address of msgsender
        if "scanner@some.some" = senderaddress then
            set attFiles to attachments of msg
            repeat with f in attFiles
                set attName to (get the name of f)
                log attName
                set saveAsName to saveToFolder & attName
                log saveAsName
                save f in POSIX file saveAsName
            end repeat
        end if
    end repeat
end tell
display dialog "" & ctr & " messages were processed" buttons {"OK"} default button 1
return ctr

Best Answer

The parameter error is arising because one of the parameters you're sending to the save command is erroneous. The f parameter is the attachment to be saved—this is fine.

The problem is the second parameter, which you've stated is a POSIX file path (one composed of forward slashes, e.g. /Users/hitzg/Desktop/some_file.txt).

However, the variable saveAsName is derived from saveToFolder, which gets its file path from the choose folder command. This command returns an HFS path (one composed of colons, e.g. Macintosh HD:Users:hitzg:Desktop:some_file.txt).

So the fix is simply to decide which type of file path format you're going to go with, and stick to it. You can EITHER use posix paths, and change this line of the script (shortened for readability) from this:

set saveToFolder to (choose folder) as string

to this:

set saveToFolder to POSIX path of (choose folder)

OR use HFS paths, and change this line of the script:

save f in POSIX file saveAsName

to this:

save f in file saveAsName

That fixes your parameter error, but I haven't tested the rest of your script to see how it performs. Reading through it, there aren't any glaring errors, so I don't anticipate any other major issues.


ADDENDUM

I'd like to offer a few edits to your original script that I believe streamlines the code whilst making it more efficient and performant. Your existing script is excellent, however with strategic use of the AppleScript whose filter, we can eliminate the first of the repeat loops, whilst improving the performance of the second.

set saveToFolder to (choose folder) as text


tell application "Microsoft Outlook"
    set srcFolder to mail folder "Inbox" of exchange account "FOO"
    
    set selectedMessages to a reference to (messages of srcFolder whose ¬
        class of attachments contains attachment and ¬
        "From: First Last <scanner@some.some>" is in headers)
        
    set attFiles to a reference to attachments of selectedMessages
    set [n, m] to [count selectedMessages, count attFiles]
    
    repeat with f in the attFiles
        set savePath to saveToFolder & name of f
        save f in file savePath
    end repeat
end tell


display alert "" & m & " attachments were saved" message ¬
    "These belonged to " & n & " messages" as ¬
    informational buttons {"OK"} default button 1

The key element of this version of the script is the implementation of the whose filter here:

    set selectedMessages to a reference to (messages of srcFolder whose ¬
        class of attachments contains attachment and ¬
        "From: First Last <scanner@some.some>" is in headers)

Instead of searching through all the messages in your inbox for messages sent from a particular sender, then grabbing the attachments, the filter's first criterion instantly picks out only the messages in your inbox that have attachments; messages without attachments are superfluous to our needs, so we don't even need to consider them. The second criterion specifies that emails should come from a specific person, although the address of sender unfortunately can't be incorporated into the filter, so instead I've utilised the message headers to make sure it contains the appropriate "From: ..." string.

To format this string, simply obtain the headers property for one message from the specific sender, and skim through it until you come across a few lines that look like this:

From: First Last <scanner@some.some>
Subject: Hello World!
Thread-Topic: Hello Again
Thread-Index: AdQD5jaiEJ7GiUlKRYeD5LaN3BaSpA==
Date: Thu, 14 Jun 2018 13:22:53 +0000
Message-ID: <B64BBE7A4C13095094C6A44D85FA3FDB5085651F@ABCD-mail.somemailbox.foo.com>

It'll be roughly in the middle of the header text. Then just make sure your filter text matches the "From:" line (copy-n-paste), as this will almost certainly be the same throughout all emails from that sender, unless they changed their first and last names at any point (which may, of course, be absent).

A slightly looser filter if you are concerned that the first and last names could have changed over time, would simply be to filter the headers to see if they contain just the email address "scanner@some.some". Since you'll only be searching your inbox, it's reasonable to assume that any occurrence of that email address in an inbox message header means that email either originated from that address or was Cc'd to that address as well as you:

    set selectedMessages to a reference to (messages of srcFolder whose ¬
        class of attachments contains attachment and ¬
        "<scanner@some.some>" is in the headers)

The rest of the script is more-or-less the same, with the fix for the parameter error implemented.

Having tested the script on my system, it worked as expected and performed very efficiently. The bottlenecking in speed for me was having to download each attachment in order to save it, so there was a data transfer consideration when running in against my Exchange mail folder.

When running it against a local mail folder with attachments already downloaded, the saving of attachments was virtually instantaneous.