Getting content of current draft

I’m trying to get the text contents of the current draft–the one the user would be composing. The following works:


tell appliction "Mail"
      get content of message 1 of drafts mailbox
end tell

The only catch is that the output is up to 11 seconds old. Mail seems to update the GUI text to the ‘content of message 1 of drafts mailbox’ object:D every 11 seconds. Of course this won’t do for realtime text analysis. I would gladly pay $50 for a solution to this problem if it answers my need.

GUI script it. $50 please LOL. Or do I have to write it as well.

Thanks for suggestion Bevos, however this would not answer my need: copying the text through the GUI interrupts the user’s keyboarding. I need a normal, smooth, instantaneous record of the draft text. :frowning:

The only object for new message is a window, save it doesn’t save the content. So GUI the only way. since all you have to do is save, there just a keystroke of command s, a flash of the Save as draft button (reason for the 0.5 delay). And then you can get the draft contents.

tell application "Mail"
	activate
	tell application "System Events"
		tell process "Mail"
			keystroke "s" using {command down}
			delay 0.5
		end tell
	end tell
	set NewContent to content of message 1 of drafts mailbox
end tell

Fast enough for you to pay $50 :slight_smile:

Continuing…

Actually, the way it works: even copying the draft text using UI scripting does not provide what-you-see-is-what-you-get copy of Mail’s draft text. I found it was necessary to save the draft first. This seemed to update the text that was copied. Don’t ask me why. Although this is an interesting work-around, it proved impractical because saving interupts the user’s work experience briefly and also closes opened menus. It’s just not a very elegant technique for my need. No, there should be a straight forward way to get the text from the user’s working draft.

Bevan:

It looks like your post went just before mine. You were able to get pretty far along in your UI work around to have discovered the utility of saving the draft. I wish I had explained the pitfalls I discovered in the various work-arounds, however I was hoping to show a concise problem so as not to scare anyone away. Perhaps you can find out how to record the draft text as one should be able to. It puzzles me that Mail makes this difficult or impossible. If you can discover the method I need, I will gladly pay you the $50 as promised :slight_smile:

Throught you would trigger your Applescript but a key command. Therefore its works, no menu open then. The text field has a notication of change value. You can run an Applescript with every letter typed by use UI Actions. The thing is the new message window doesn’t have a content property so you would have to send it to the draft contents, and I wouldn’t think it would update back to the new message window.

If its not a secret what does your Applescript do? Post it if you can.

Maybe I’m up to $25 :slight_smile:

Have fun

Bevan:

Thanks for your continued interest the challenge (or the $50). You asked for more information about what I am trying to accomplish, so let me tell you: I wish to determine what spelling changes are made in one’s email draft. Ideally, I would capture the changes as AppleSpell makes them, however this would likely require access to Mails proprietary objective C code or whatever. So the next best thing I believe would be to determin when someone activates AppleSpell so we can capture the text before and after the spelling changes (I can determine when AppleSpell is activated using the System Activities info). This would allow us to compare the two sets of text and determine the spelling word before and after the correction were made. This would have been a pretty easily thing to do if Mails ‘get contents of document 1 of draft mailbox’ worked punctually as it should–but doesn’t. As a result we both tried to use the UI work-around. Unfortunately, this also required us to save the draft which interferes with the application’s user experience (menus close if they are open, the applicaton blinks, keyboard imput skips, and so on).

You raised some interesting ideas: if the draft text indicates when it recieves a change, then there must be a way to record this change beside just knowing it happened. Other ideas you mentioned were not clear, however you seem likely to be closing in on the goal. Please keep on thinking of a solution so I can pay you that $50 :slight_smile:

Times up! I solved the problem by way of PreFabs “UI Browser”:


activate application "Mail"
tell application "System Events"
	tell process "Mail"
			return value of (every static text of group 1 of UI element 1 of scroll area 3 of window "New Message") as text
	end tell
end tell

Unlike Bevan’s method where the ‘New Message’ is saved to the ‘Draft’ mailbox and then UI copied, this solution does not seem to interfer with user keyboard strokes and other mischief. I would never have discovered the method above had I not purchased PreFabs ‘UI Browser’ and played with it. Cost was $55–a coincidence, since this was to be the solution reward! Nevertheless, I must acknowledge Bevan for pointing me in the right direction with his ‘UI Actions’ link in a previous message. I’ll see what I can do for B. :cool:

I was working on it as you posted it and got the same line. The thing is I noticed is if you type quickly, you can beat it, it misses letters then catches up. UI Acitions if you run a stay open script it does remember values add to a property list (global). It as if it a normal script. So to remember things as you type I had to past it to a remember stay open Applescript with a handler to add to its property list. Then I had another script action a handler in remember stay open Applescript to process a report.

This is what UI triggers

on run
	beep
	activate application "Mail"
	tell application "System Events"
		tell process "Mail"
			set TheText to (name of every static text of group 1 of UI element 1 of scroll area 3 of window "New Message") as string
		end tell
	end tell
	tell application "Remember"
		Remember(TheText)
	end tell
end run

This is where it go for later processing, Stay Open Application

property TextList : {}

on Remember(TheText)
	set TextList to TextList & TheText
end Remember

on report()
	tell application "Mail"
		activate
		choose from list TextList
		set TextList to {}
	end tell
end report

Then a simple script to process a report, this case just display in choose a list

on run
	tell application "Remember"
		activate
		report()
	end tell
end run

Since it grabs each letter as you type and your processing is complex you best, do it on a key command later, but at less you got what was typed in and in what order. I would also get to text again on report just in case the last typed was missing.

Got your text now do your magic.

Bevan:

Thanks for your effort in working out a solution to the Mail text problem. This will surely be a help to others at MacScripter.

Although the UI method derived from PreFab’s UI Browser may cause keyboard input to lapse, I have not been able to detect it (though I don’t doubt your claim that it does). You may not be aware that I do not need great accuracy in getting the text at every moment. What I need is to detect within a second or two, when a spelling correction has been made in order to copy the text after the correction to variable ‘afterText.’ Copying the text before is just a matter of making sure I get a record of the New Message text every 5 seconds–or simply handing off the previous ‘afterText’ to a ‘beforeText’ variable. That said, your system of applications to preserve keyboard input from ‘Mail’ is ingenius and I will keep this in mind if I should have a problem with the keyboard input that I don’t yet see.

Enjoyed the challenge. Good luck.

Valid point. Didn’t get that far with my testing. Thanks for your post. On a long email that could be grabbing a lot of text at once. The script keeping up will get worst as the email get bigger. But who write really long emails any way?