MWean
MWean

Reputation: 422

Get message in compose window from Mail.app

I am trying to make a script that will get the contents of an email message that I'm composing in Mail, do something with the data, and then send the message. I know how to make and send a new message from scratch with AppleScript, but I can't find a way to get a message that I'm already writing. I don't care what language is used, and I would be open to trying a different email client. Thanks for your help!

Upvotes: 5

Views: 1461

Answers (5)

Thomas Kekeisen
Thomas Kekeisen

Reputation: 4406

So I came across this in 2020 and with this Apple Script it is (now?) possible (whenever its still a bit hacky since I have to use the clipboard for this):

activate application "Mail"

tell application "System Events"
    tell process "Mail"
        set initialClipboardContent to (the clipboard as text)
        set composeWindow to (first window whose title does not contain "Inbox")
        set value of attribute "AXFocused" of UI element 1 of scroll area 1 of composeWindow to true

        delay 0.05

        # CMD + A   
        key code 0 using command down
        delay 0.1

        # CMD + C
        key code 8 using command down
        delay 0.1

        set message to (the clipboard as text) as string

        log message

        set the clipboard to initialClipboardContent
    end tell
end tell

Here a proof of concept:

proof of concept

Upvotes: 1

Werner Ruotsalainen
Werner Ruotsalainen

Reputation: 91

It's actually pretty easy to do what you need.

  1. If you want to run some kind of an inline processing (assigned to, say, a hotkey (in Mail, e.g. Cmd+D is not occupied), or "just" listed in the Services menu, accessible after selecting something), you can simply use Automator. A demo Automator script reading the current selection, making some changes (here, converting some ASCII char+number combinations to some accented characters) and, finally, returning the modified text is as follows:

    on run {input, parameters}
    
    set myText to replaceText("a1", "á", (input as text))
    
    set myText to replaceText("e1", "é", myText)
    
    set myText to replaceText("i1", "í", myText)
    
    return myText
    
    end run
    
    
    
    on replaceText(find, replace, someText)
    
    set prevTIDs to text item delimiters of AppleScript
    
    set text item delimiters of AppleScript to find
    
    set someText to text items of someText
    
    set text item delimiters of AppleScript to replace
    
    set someText to "" & someText
    
    set text item delimiters of AppleScript to prevTIDs
    
    return someText
    
    end replaceText
    

    Make sure you enable the "Replaces selected text", should you want to overwrite the original content with the returned one.

  2. if you want to write an external script not invoked from the local Services menu (or via a hotkey), you'll also need to add clipboard handling. A solution similar to the above with additional clipboard copy/paste:

    on replaceText(find, replace, someText)
    
    set prevTIDs to text item delimiters of AppleScript
    
    set text item delimiters of AppleScript to find
    
    set someText to text items of someText
    
    set text item delimiters of AppleScript to replace
    
    set someText to "" & someText
    
    set text item delimiters of AppleScript to prevTIDs
    
    return someText
    
    end replaceText
    
    
    
    tell application "Mail"
    
    activate
    
    tell application "System Events"
    
    tell process "Mail"
    
    click menu item "Select All" of menu "Edit" of menu bar 1
    
    click menu item "Copy" of menu "Edit" of menu bar 1
    
    end tell
    
    end tell
    
    end tell
    
    
    
    tell application "Mail"
    
    set textclip to (the clipboard)
    
    end tell
    
    
    
    set myText to replaceText("a1", "á", textclip)
    
    set myText to replaceText("e1", "é", myText)
    
    set myText to replaceText("i1", "í", myText)
    
    
    
    set the clipboard to myText
    
    
    
    tell application "Mail"
    
    activate
    
    tell application "System Events"
    
    tell process "Mail"
    
    click menu item "Paste" of menu "Edit" of menu bar 1
    
    end tell
    
    end tell
    
    end tell
    

Note that the latter script selects (and, then, overwrites) the entire window contents. It should be easy to work on the current selection only.

Upvotes: 1

Antal Spector-Zabusky
Antal Spector-Zabusky

Reputation: 36622

This is striaghtforward if we make two reasonably weak assumptions: that the message you're working on is frontmost, and that the subject of all draft messages is unique. Then, before running the script, save the message you're working on; this will place it in the drafts mailbox. Then, since the subject of the message is the name of the window, we can easily access it; and since we can easily access the drafts mailbox, we can combine the two. This gives us:

tell application "Mail"
    set msgs to messages of drafts mailbox ¬
        whose subject is (name of window 1 as string)
    if (count of msgs) = 1 then
        -- Do whatever
    else
        -- Error, disambiguate, whatever
    end if
end tell

It's probably possible to make the script save the frontmost window, and it wouldn't surprise me if a freshly-saved message is always the first item of the drafts mailbox, but these are left as an exercise for the reader :-)

Upvotes: 0

Clark
Clark

Reputation: 818

Mail has huge limitations with regards to Applescript and dealing with its content area is a major one. The best bet is to use GUI scripting to tab to the content area, type cmd-C, and then work off the data in the clipboard.

Sadly from what I can see Applescript has not been improved at all in Lion.

Upvotes: 1

geekosaur
geekosaur

Reputation: 61369

It's possible, but painful. Painful enough that I'm still trying to work out exactly how to do something similar but in Safari. I've gotten to the point where I can find the textarea, but the documentation I've found for getting the content isn't working. (Unfortunately, that's pretty much par for the course for AppleScript; every program does stuff just a little bit differently from the next program.)

EDIT: ok, have some horrible evil which hopefully can be adapted to work with Mail: http://www.ece.cmu.edu/~allbery/edit_textarea.script

Upvotes: 0

Related Questions