Scripting Apple Mail


Scripting Apple Mail


Hey Folks,

This keeps coming up over and over, so I'm giving it a topic of its own.

01) How to create a new outgoing message with one or more attachments.

-------------------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2013/05/15 06:11
# dMod: 2017/02/04 19:15
# Appl: Apple Mail
# Task: Make a new outgoing message with attachments example.
# Libs: None
# Osax: None
# Tags: @Applescript, @Mail, @Create, @Make, @New, @Outgoing, @Message, @Attachments
-------------------------------------------------------------------------

# The attachment list MUST be made up of a LIST of file aliases!!!!
set attachmentList to {alias "Mercury:Users:chris:test_directory:Mail_Attachment_Test:Test_Archive_01.zip", alias "Mercury:Users:chris:test_directory:Mail_Attachment_Test:Test_Archive_02.zip", alias "Mercury:Users:chris:test_directory:Mail_Attachment_Test:Test_Archive_03.zip"}

set toName to "Robert A. Heinlein"
set toAddress to "bob@pieinthesky.com"
set msgSender to "Your Name <YourEmailAddress@YourDomain.com>"
set msgSubject to "Example Message with Attachments"
set msgBody to "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."

tell application "Mail"
   set newMsg to make new outgoing message with properties {subject:msgSubject, content:msgBody & return & return}
   
   tell newMsg
      set visible to true
      make new to recipient at end of to recipients with properties {name:toName, address:toAddress}
      set sender to msgSender
      
      repeat with theAttachment in attachmentList
         make new attachment with properties {file name:theAttachment} at after the last paragraph
      end repeat
      
   end tell
end tell

--------------------------------------------------------------------------

NOTE – If you don't understand what an alias is or how to make one stay tuned – I will post a tool for making them soon.

-Chris

4 Likes

Suppose I have a KM variable “HFSPathList” with the value:

alias "Disk:file1"
alias "Disk:file2"
alias "Disk:file2"

Instead of the exact names at the beginning of the script

set attachmentList to {alias "Mercury:Users:chris:test_directory:Mail_Attachment_Test:Test_Archive_01.zip", alias "Mercury:Users:chris:test_directory:Mail_Attachment_Test:Test_Archive_02.zip", alias "Mercury:Users:chris:test_directory:Mail_Attachment_Test:Test_Archive_03.zip"}

I do:

tell application "Keyboard Maestro Engine"
    set attachmentList to value of variable "HFSPathList"
end tell

But the code:

repeat with theAttachment in attachmentList
    make new attachment with properties {file name:theAttachment} at after the last paragraph 
end repeat

Stops working correctly…

Where is the mistake?

Hey Ilya,

The problem is that Keyboard Maestro’s variables can only contain plain-text, so your alias <hfs_path> construct in Keyboard Maestro is useless.

An alias is a specific type of file object in AppleScript created at compile-time (or via other methods).

You can’t just put put a string together and call it an alias.

Here’s the sort of thing you have to do to transition between a Keyboard Maestro variable containing HFS_Path_Strings and AppleScript aliases.

Here’s our list of paths in the Keyboard Maestro variable “HFSPathList”:

Mercury:Users:myUserName:test_directory:Ilya_Test_Folder:Attachment 01.zip
Mercury:Users:myUserName:test_directory:Ilya_Test_Folder:Attachment 02.zip
Mercury:Users:myUserName:test_directory:Ilya_Test_Folder:Attachment 03.zip

Here’s how we convert them to aliases for AppleScript to use:

tell application "Keyboard Maestro Engine"
   set attachmentList to getvariable "HFSPathList"
end tell

set attachmentList to paragraphs of attachmentList

repeat with theItem in attachmentList
   set contents of theItem to (contents of theItem) as alias
end repeat

-Chris

Thanks Chris, it’s working! At such moments you understand how little you know of AppleScript… :slight_smile:

Three questions:

  1. How do you make the text to look like the code?
  2. What is the best book to learn AppleScript?
  3. The code string:
    set message signature of newMsg to signature theSignatureName

doesn’t work… (AppleEvent error -10000)
I defined this var at the beginning:
set theSignatureName to “Sig”

Hey Ilya,

Bracketing the text with three back-ticks – ``` (Lower-case of the tilde ~ key.)

```
tell application "Mail"
   tell (some message viewer whose index is 1)
      set msg to item 1 of (get selected messages)
   end tell
end tell
```

Will cause the text to render as code.

tell application "Mail"
   tell (some message viewer whose index is 1)
      set msg to item 1 of (get selected messages)
   end tell
end tell

You can also add the type of code to the first back-tick line.

Try:

```applescript
your code
```
```text
your code
```
```bash
your code
```

And see the difference.

I believe the default for just three back-ticks is AppleScript, although Peter would have to confirm.

My post here would be worth reading, and some of the other conversation:

Best Practices for GUI Scripting

There's a long thread on the Keyboard Maestro forum:

Learning & Using AppleScript & JavaScript for Automation (JXA)

There's the Scripting page on the Keyboard Maestro wiki.

I have about 5 books on AppleScript myself.

I usually recommend these two:

"Learn AppleScript: The Comprehensive Guide to Scripting and Automation on Mac OS X"
"AppleScript: The Definitive Guide"

I've heard good things about “AppleScript 1,2,3”, although I haven't had my hands on it.

Apple broke AppleScripting signatures in Sierra and hasn't fixed it.

-Chris

3 Likes

Thank you Chris!

Thanks for AppleScript books recommendations
I used this workaround for Mail signatures:

tell application "System Events"
	tell application "Mail" to activate
	tell process "Mail"
		delay 0.9
		click pop up button 2 of window 1
		delay 0.01
		keystroke "R"
		delay 0.01
		keystroke return
		delay 0.01
	end tell
end tell

I have the impression it gets triggered by keywords, for example “tell” will set it to AppleScript. Not sure though.

@Ilya, I can confirm that this is a good book. Due to its age though (2006) it “only” covers vanilla AppleScript.
For AppleScriptObjC there is Shane Stanley’s excellent “Everyday AppleScriptObjC”.

Also have a look at Apple’s online documentation, for example the AppleScript Language Guide.

1 Like

Hey Ilya,

That works.

You can also assign keyboard shortcuts to signatures in the System Keyboard Prefs and then fire them either via Keyboard Maestro or AppleScript.

-Chris

Didn't find how to do this...

System Prefs > Keyboard > Shortcuts > App Shortcuts > Mail > Exact Title of Signature

Did that - doesn’t work (

It does, but it's picky about what keyboard shortcuts work.

Try Cmd-Opt-L and Ctrl-Shift-L

Restart Mail.

I've had those keyboard shortcut working for a long time on my system.

They should show up in the signature pop-up window, but just because they show up doesn't mean the given keyboard shortcut will work properly. (Bad Apple!)

-Chris

)) Ctrl-Shift-… worked finally. Thank you Chris. Now macro works smoother, than with this GUI timings

1 Like

Has been working good until now… Mail stops and asks me for outgoing mail service…

How do you attach a file to an email which is already open as a window and not yet sent by passing through the location of the file held as a KM variable?

Hey Ali,

You can't do this via AppleScript.

The only way is to emulate the process of doing it by hand.

-Chris

1 Like

Thank you.

Hi Chris, Is it possible to do this now? :slight_smile: attach a file to Window 1 of Mail? I have the location of the file held within a KM variable.