email file from finder II

the previous post — email file from finder — showed how to use applescript to quickly attach a selected finder item to an email — adding a recipient, subject and basic content along the way. this post will show how to adapt that script to allow for multiple attachments and multiple recipients.

here’s the original script :

set mgPeople to {}
set mgFirsts to {}
set mgAddresses to {}

tell application "Address Book"
  repeat with mgPerson in people
    tell mgPerson
      repeat with mgEmail in emails
        copy name to the end of mgPeople
        copy first name to the end of mgFirsts
        copy value of mgEmail to the end of mgAddresses
      end repeat
    end tell
  end repeat
end tell

-- thanks to Mark J. Reed 
-- http://lists.apple.com/archives/applescript-users/2007/Mar/msg00086.html
set text item delimiters of AppleScript to (ASCII character 10)
set mgSortedPeople to paragraphs of (do shell script "echo " & quoted form of (mgPeople as string) & "| sort  -d -f")
set text item delimiters of AppleScript to ""
-------------

choose from list mgSortedPeople with prompt "who you emailing then?"
if result is not false then
  set mgChosenOne to item 1 of result
else
  error number -128
end if

repeat with x from 1 to count of mgPeople
  if item x of mgPeople = mgChosenOne then
    set mgFirstName to item x of mgFirsts
    set mgChosenEmail to item x of mgAddresses
  end if
end repeat

tell application "Finder"
  set mgSelection to the selection
  set text item delimiters of AppleScript to ":"
  if class of (item 1 of mgSelection) is folder then
    set mgSubject to text item -2 of ((item 1 of mgSelection) as string)
    set mgContent to "Hi " & mgFirstName & return & return & "Here's that folder we were talking about." & return & return
  else
    set mgSubject to text item -1 of ((item 1 of mgSelection) as string)
    set mgContent to "Hi " & mgFirstName & return & return & "Here's the file you're waiting for." & return & return
  end if
  set text item delimiters of AppleScript to "."
  set mgSubject to text item 1 of mgSubject
  set text item delimiters of AppleScript to ""
end tell

tell application "Mail"
  activate
  set mgMessage to make new outgoing message with properties {subject:mgSubject, content:mgContent, visible:true}
  tell mgMessage
    make new to recipient with properties {name:mgChosenOne, address:mgChosenEmail}
    make new attachment with properties {file name:(mgSelection as alias)} at after last paragraph of content
    save
  end tell
end tell

that script first creates three lists — names, first names and email addresses. the list of first names was used to create the salutation in the email (“Hi whoever”). but this script allows for multiple recipients so the salutation will change (in this script we’ll use “Hi all”). so, the start of the script will be stripped back to this :

set mgPeople to {}
set mgAddresses to {}

tell application "Address Book"
  repeat with mgPerson in people
    tell mgPerson
      repeat with mgEmail in emails
        copy name to the end of mgPeople
        copy value of mgEmail to the end of mgAddresses
      end repeat
    end tell
  end repeat
end tell

-- thanks to Mark J. Reed 
-- http://lists.apple.com/archives/applescript-users/2007/Mar/msg00086.html
set text item delimiters of AppleScript to (ASCII character 10)
set mgSortedPeople to paragraphs of (do shell script "echo " & quoted form of (mgPeople as string) & "| sort  -d -f")
set text item delimiters of AppleScript to ""
-------------

the next thing we need to do is allow the user to select multiple email recipients. that’s as simple as changing the end of that choose from list command. we also need to change the way we capture that data — it’s no longer a list with only one item :

choose from list mgSortedPeople with prompt "who you emailing then?" with multiple selections allowed
if result is not false then
  set mgChosenOnes to result
else
  error number -128
end if

as per standard mac functionality, you can select multiple items in the dialog by holding down the command key :
screen grab of choose from list dialog with multiple recipients selected

we’re going to dump the next repeat loop from the original script — we’ll integrate that functionality once we start talking to Mail. here’s the new code we need for addressing the finder. this time we’re going to capture the name of the folder containing the finder selection to use as our subject line :

tell application "Finder"
  set mgSelection to the selection
  set text item delimiters of AppleScript to ":"
  if class of (item 1 of mgSelection) is folder then
    set mgSubject to text item -3 of ((item 1 of mgSelection) as string)
  else
    set mgSubject to text item -2 of ((item 1 of mgSelection) as string)
  end if
  set text item delimiters of AppleScript to ""
end tell

the original script allowed for one attachment and one recipient, so the last portion of the script — the bit that created the actual email — was quite simple. with this version we need two repeat loops — one to process the multiple recipients and one to process the multiple attachments :

tell application "Mail"
  activate
  set mgContent to "Hi all" & return & return & "Please find attached ..." & return & return
  set mgMessage to make new outgoing message with properties {subject:mgSubject, content:mgContent, visible:true}
  tell mgMessage
    repeat with mgChosenOne in mgChosenOnes
      repeat with x from 1 to count of mgPeople
        if item x of mgPeople = (mgChosenOne as string) then
          set mgChosenEmail to item x of mgAddresses
          make new to recipient with properties {name:mgChosenOne, address:mgChosenEmail}
        end if
      end repeat
    end repeat
    repeat with mgitem in mgSelection
      make new attachment with properties {file name:(mgitem as alias)} at after last paragraph of content
    end repeat
    save
  end tell
end tell

screen grab of email created by the script

your homework for this week is to come up with a way to make the salutation personal if only one recipient is selected (eg. “Hi John”) but generic if multiple recipients are selected (eg. “Hi all”).

next time we’ll look again at how to turn this script into a service for easy accessibility from within the finder.

macgrunt icon

email file from finder

InDesign scripting : lesson 22 showed an applescript that exports a pdf from InDesign and attaches it to an email — adding a subject and recipient along the way. here’s a variation that lets you email an existing file directly from the finder. the previous script used a predefined list of email addresses — this one accesses your address book.

the first part of the script compiles three lists — names, first names and email addresses. we start by creating three empty lists before moving on to copying the relevant data into those lists. then we use the choose from list command to create a UI for the user to make a selection from. mgPeople is the list of names for people in your address book who have an email address :

set mgPeople to {}
set mgFirsts to {}
set mgAddresses to {}

tell application "Address Book"
  repeat with mgPerson in people
    tell mgPerson
      repeat with mgEmail in emails
        copy name to the end of mgPeople
        copy first name to the end of mgFirsts
        copy value of mgEmail to the end of mgAddresses
      end repeat
    end tell
  end repeat
end tell

choose from list mgPeople

you’ll notice the list is in a crazy order. that’s because the list is in ID order — the order in which the contacts were entered into your address book :
screen grab of initial choose from list dialog

so, to make things a leetle easier, we need to reorder the list alphabetically. thanks to mark j. reed over at the apple mailing lists for the shell script :

set mgPeople to {}
set mgFirsts to {}
set mgAddresses to {}

tell application "Address Book"
  repeat with mgPerson in people
    tell mgPerson
      repeat with mgEmail in emails
        copy name to the end of mgPeople
        copy first name to the end of mgFirsts
        copy value of mgEmail to the end of mgAddresses
      end repeat
    end tell
  end repeat
end tell

-- thanks to Mark J. Reed 
-- http://lists.apple.com/archives/applescript-users/2007/Mar/msg00086.html
set text item delimiters of AppleScript to (ASCII character 10)
set mgSortedPeople to paragraphs of (do shell script "echo " & quoted form of (mgPeople as string) & "| sort  -d -f")
set text item delimiters of AppleScript to ""
-------------

choose from list mgSortedPeople with prompt "who you emailing then?"
if result is not false then
  set mgChosenOne to item 1 of result
else
  error number -128
end if

that last part captures the result of the dialog into a variable (mgChosenOne) or, if the user hits cancel instead, stops the script (error number -128). this is needed because of a quirk of the choose from list command — the cancel button doesn’t actually cancel the process it just returns a ‘false’ result. the observant will notice we’ve added our own prompt to this version of the dialog. you can also add a title to that top bar as well if you like :
screen grab of alphabetisied choose from list dialog

the next bit simply matches up the chosen recipient with their first name and email address and captures those into variables too :

repeat with x from 1 to count of mgPeople
  if item x of mgPeople = mgChosenOne then
    set mgFirstName to item x of mgFirsts
    set mgChosenEmail to item x of mgAddresses
  end if
end repeat

then we need to get a reference to the selected object in the finder. and we set a subject and content for the email message. you can see that we’re checking to see if the selected object is a file or folder first, then setting the subject and content accordingly. the subject will be the name of the file or folder and the content is our own chosen verbage :

tell application "Finder"
  set mgSelection to the selection
  set text item delimiters of AppleScript to ":"
  if class of (item 1 of mgSelection) is folder then
    set mgSubject to text item -2 of ((item 1 of mgSelection) as string)
    set mgContent to "Hi " & mgFirstName & return & return & "Here's that folder we were talking about." & return & return
  else
    set mgSubject to text item -1 of ((item 1 of mgSelection) as string)
    set mgContent to "Hi " & mgFirstName & return & return & "Here's the file you're waiting for." & return & return
  end if
  set text item delimiters of AppleScript to "."
  set mgSubject to text item 1 of mgSubject
  set text item delimiters of AppleScript to ""
end tell

the last part creates the email based on all the bits and pieces we’ve put together in the other parts of the script. this is how you would do it for Mail. see InDesign scripting : lesson 22 to see how to do it for Outlook. for other email software, consult your applescript dictionary for that program :

tell application "Mail"
  activate
  set mgMessage to make new outgoing message with properties {subject:mgSubject, content:mgContent, visible:true}
  tell mgMessage
    make new to recipient with properties {name:mgChosenOne, address:mgChosenEmail}
    make new attachment with properties {file name:(mgSelection as alias)} at after last paragraph of content
    save
  end tell
end tell

put all those bits together, customise it to your particular way of working, and you’ve got yourself a handy little timesaver. there are a number of ways to activate a script like this, but the easiest is to turn it into a service so that you can activate the script with a right-click or keyboard shortcut. see get file path of finder items which shows how to do this through automator.

screen grab of email created by the script

the next post will show how to convert this script to allow for multiple attachments and multiple recipients.

til then, keep grunting.

macgrunt icon

InDesign scripting : lesson 22

performing tedious, repetitive tasks — no matter how small — is monkey-work. automating those tasks makes you just that little bit less like a monkey. if you take a moment to think about it, you may find you’re wasting an awful lot of life on mundanities …

… such as creating and emailing proofs for clients. this script will export a pdf, attach it to an email, then add the recipient, subject line and basic message — all with just three double-clicks.

the first part of the script exports the pdf. exporting pdfs was covered way back in scripting lessons 08 thru 12, so refer back to them if you need an explanation of what’s going on here :

tell application "Adobe InDesign CS4"
  activate
  save active document
  set mgPdfPresets to name of every PDF export preset
  set mgPdfPreset to choose from list mgPdfPresets with prompt "How you want these done then?" with title "CHOOSE PDF EXPORT PRESET"
  if mgPdfPreset is false then
    display dialog "WHATEVER!" buttons "get stuffed" giving up after 1
    error number -128
  end if  
  
  set properties of PDF export preferences to properties of PDF export preset (item 1 of mgPdfPreset)
  set page range of PDF export preferences to all pages
  set mgFolder to file path of active document
  
  tell application "Finder"
    if (exists folder "PDF" of folder mgFolder) is false then
      make new folder at mgFolder with properties {name:"PDF"}
    end if
  end tell
  set mgDocName to name of active document
  set OrigDelims to text item delimiters of AppleScript
  set text item delimiters of AppleScript to {"."}
  set mgShortName to text item 1 of mgDocName
  set text item delimiters of AppleScript to OrigDelims
  
  set mgFilePath to mgFolder & "PDF" & ":" & mgShortName & ".pdf" as string
  tell active document
    export format PDF type to mgFilePath without showing options
  end tell
end tell

tell application "Finder"
  set mgFile to mgFilePath as alias
end tell

this uses the choose from list command which will present the user with a dialog listing their available export presets. it’ll look something like this :
screen grab of pdf export selection dialog

just for shits and giggles we’ve added a surly message for any user who dares to cancel that dialog instead of proceeding.

the last part of that script above gets a reference to the pdf as an alias — ready to attach to the email.

the next part of the script sets up the details for the email. this workflow has a small number of possible email recipients (just the four sales reps who deal directly with clients) — you might want to come up with a different solution if your list is longer :

set mgChoice to choose from list {"macGrunt", "macGroan", "macGrumble", "John"} with prompt "Who you want this sent to?"
if mgChoice is false then
  error number -128
end if
set mgChoice to item 1 of mgChoice
if mgChoice is "macGrunt" then
  set mgAddress to "macgrunt@macgrunt.com"
else if mgChoice is "macGroan" then
  set mgAddress to "macgroan@macgrunt.com"
else if mgChoice is "macGrumble" then
  set mgAddress to "macgrumble@macgrunt.com"
else if mgChoice is "John" then
  set mgAddress to "john@macgrunt.com"
end if

set mgContent to "Hi " & mgChoice & return & return & "Here's your groovy proof" & return

first the user is asked to select from another list that might look something like this :
screen grab of email recipient dialog
then, based on that choice, the email address is set. finally verbage for the email content is set.

the last part of the script sets up the actual email and will need to change depending on which email software you are using. for example, this is how you could do it for Mail :

tell application "Mail"
  activate
  set mgMessage to make new outgoing message with properties {visible:true, subject:mgShortName, content:mgContent}
  tell mgMessage    
    make new to recipient with properties {name:mgChoice, address:mgAddress}
    tell content of mgMessage
      make new attachment with properties {file name:mgFile} at after last paragraph
    end tell
  end tell
  save mgMessage
  set visible of mgMessage to true
end tell

you’ll notice that, for this workflow, we’re using the shortened filename as our subject line.

this is how it would go if you needed to do the same thing with Outlook :

tell application "Microsoft Outlook"
  activate
  set mgMessage to make new outgoing message with properties {subject:mgShortName, content:mgContent}
  make new recipient at mgMessage with properties {email address:{name:mgChoice, address:mgAddress}}
  make new attachment at mgMessage with properties {file:mgFile}
  open mgMessage
end tell

you should be able to use these as a starting point — just open the relevant scripting dictionary in script editor to work out the syntax specific to your email software. if it all becomes too hard — google is your friend.

well, that’s it. a relatively small time-saving, but just think how many times you repeat that simple monkey-task every week.

macgrunt icon