Getting Applescript to change text formatting in an email message already open

I use a script in FileMaker Pro 17 that composes an email-message, but Filemaker can’t handle formatted text, so I’m trying to write an Applescript that changes some formatting in the email message right after FM has created it. So it is already open and at the front, addresses, subject and content already where they need to be.
To be specific: I need some recurring sentences changed to bold and a specific recurring words changed to red whenever it appears.

(I’ve tried it the other way around: writing an Applescript that gets the values out of the fields in the Filemaker file, but that’s a headache because of security issues: it’s somehow very hard to give Scripteditor permission to ask FM for anything.)

I’m new to AS, but I have tried the following:

set makeBold1 to “Important Data”
set makeBold2 to “Pay attention”
set makeBold3 to “Please reply”
set makeRed to “tbc”

tell application “Mail”
activate
set theWindow to item 1 of (windows whose visible is true)
set windowTitle to name of theWindow

tell windowTitle
	repeat with aParagraph in (paragraphs of windowTitle)
		set aParagraph to contents of aParagraph
		if aParagraph begins with makeBold1 or aParagraph begins with makeBold2 or aParagraph begins with makeBold3 then
			set the font of the paragraph to "Calibri Bold"
		end if
	end repeat
	
	repeat with aWord in (words of windowTitle)
		set aWord to contents of aWord
		if aWord begins with makeRed then
			set the color of the word to "Red"
		end if
	end repeat
end tell

end tell

But all it seems to do is bring the window to the front and blink the cursor in the address-field.

Please help!

Your script is focused on trying to work with a window but that is inappropriate for your purpose here. Also, as an aside, there is something else to watch out for: windowTitle is just a string so you can’t really tell it much. You need to pair it with the related object, in this case the window, eg tell window windowTitle — but as mentioned, you aren’t really working with a window here. Try working with outgoing message.

Outgoing messages have the property content, which is the rich text that should include your paragraphs.

Assuming that the front window is the newly created outgoing message, you might start with something like this:

set om1 to outgoing message 1
set paraList to paragraphs of content of om1

By the way, if you move the three backticks (```) to their own lines above and below your the first and last tell statements, then all of your code will be formatted. Without this, copying and pasting your script will require fixing all the quotes characters.

Thank you for your suggestions. The problem (which I was trying to solve by working with a window) is that ScriptEditor is giving me error messages when I’m trying to access the content of the message directly and I can’t figure out why. E.g. when I try your suggestion in SE it doesn’t get past

set om1 to outgoing message 1

and says: “Mail got an error. outgoing message 1 can not be requested. Invalid index.”
(My OS is set to Dutch, so I’ve translated this error message.) Any idea why this should be?
(I have checked ScriptEditor as one of the apps allowed to control the computer in Security>Privacy>Accessability.)
How could I solve this?

Interesting, but not in a good way. I see what you mean about the window but unfortunately, the text isn’t a property of the window. I am getting the impression that you cannot directly edit the content of the outgoing message. It’s possible that the content can only be set when creating the message — this despite the dictionary indicating that you can use set. FWIW, I’m not a fan of scripting Mail (or any apple app, really).

So, as an alternative, I hacked together a script that uses TextEdit to format the text and then uses copy and paste to replace the text in the outgoing message window. The length of the delays works for me but you should test them and see what works best in your case. I added a randomized colour change just to make it easier to observe how the script was working while testing. It’s a mess but it seems to work.

set calBold to "Calibri-Bold"
set red to {65535, 0, 0} -- RGB colour
tell application "Mail"
	set aid to id of account "Me" -- account to work with - substitute your own here
	set draftBox to mailbox "Drafts" of account id aid -- drafts of above
	set dm to message 1 of draftBox -- most recent draft
	set mc to content of dm -- content of most recent draft message
end tell
tell application "TextEdit"
	activate
	set d1 to document 1
	set text of d1 to mc -- use text of mail message for textedit document
	set size of text of d1 to 14
	set keyList to {"Important Data", "Pay attention", "Please reply"}
	repeat with p from 1 to count of paragraphs of d1
		repeat with k from 1 to length of keyList
			if paragraph p of d1 begins with item k of keyList then
				set color of paragraph p of d1 to my makeup() -- optional randomizes colour
				set font of paragraph p of d1 to calBold
			end if
		end repeat
	end repeat
	if text of d1 contains "tbc" then
		set w to words of text of d1
		repeat with x from 1 to length of w
			if item x of w is "tbc" then
				set color of word x of text of d1 to red
				set font of word x of text of d1 to calBold -- optional
			end if
		end repeat
	end if
	delay 1
	tell application "System Events" to tell process "TextEdit"
		key code 0 using command down -- command-a or Select All
		delay 0.3
		key code 8 using command down -- command-c or Copy
	end tell
end tell
tell application "Mail"
	activate
	delay 0.3
	tell application "System Events" to tell process "Mail"
		key code 0 using command down -- command-a or Select All
		delay 0.3
		key code 9 using command down -- command-v or Paste
	end tell
end tell

on makeup() -- random 16-bit colours
	set {r, g, b} to {rando(), rando(), rando()}
end makeup
on rando()
	(random number from 0 to 255) * 256 + (random number from 0 to 255)
end rando
1 Like

Here is a sample script to create an outgoing message. You are correct that you have to set the content at time of creation.

tell application "Mail"
	set curmsg to make new outgoing message with properties {subject:"Thanks for sending me so much spam mails!", content:"This is a test!"}
	tell curmsg
		make new to recipient at end of to recipients with properties {name:"Harry Johnson", address:"hjohnson@me.com"}
	end tell
end tell

Ah, this is such a relief! I have spent hours trying to access the content of a newly created email message, assuming I couldn’t do it due to my crappy scripting, but it turns out it can’t be done. Thank you Mockman and robertfern.
I got it all working now.
Two problems I ran into:
First, it takes Mail some time (whole minutes in some cases) to put a new message into the Drafts folder, but thanks to your example script I knew how to force Mail to save it using Command-S.
Second: the formatted text got pasted into the address field of the email message, but again that was solved by four consequetive keystrokes of TAB.
The same trick could also be used to quit TextEdit after it had done its job.
Plus I finally learned how these repeat loops work. Indeed, it is a brute force approach and a lot happens on screen in a few seconds, but it gets the job done and I learned a lot. Thanks!
For the record, I include the final version.

‘’’
– VARIABLES – Phrases that must be formatted
set makeBold to {“Important data”, “Pay attention”, “Please reply”}
set makeRed to “tbc”

– VARIABLES – Formats to be used
set boldType to “Calibri-Bold”
set redColor to {65535, 0, 0} – RGB colour Red

– Save new email message to Drafts
tell application “Mail” to activate
delay 0.3
tell application “System Events” to tell process “Mail”
key code 1 using command down – command-s or Save
delay 0.3
end tell

– Get text from email message in front window
tell application “Mail”
set accountId to id of account “iCloud”
set draftBox to mailbox “Drafts” of account id accountId – drafts of account
set theMessage to message 1 of draftBox – most recent draft
set messageContent to content of theMessage – content of most recent draft message
end tell

– Paste text into new TextEdit document
tell application “TextEdit”
activate
make new document at the front
set the text of the front document to messageContent

set doc1 to document 1
set text of doc1 to messageContent -- use text of mail message for textedit document
set font of text of doc1 to "Calibri"
set size of text of doc1 to 15


-- Set indicated phrases to Bold
repeat with p from 1 to count of paragraphs of doc1
	repeat with k from 1 to length of makeBold
		if paragraph p of doc1 begins with item k of makeBold then
			set font of paragraph p of doc1 to boldType
		end if
	end repeat
end repeat


-- Set indicated word to Red
if text of doc1 contains makeRed then
	set w to words of text of doc1
	repeat with x from 1 to length of w
		if item x of w is makeRed then
			set color of word x of text of doc1 to redColor
			set font of word x of text of doc1 to boldType -- optional
		end if
	end repeat
end if
delay 1


--Copy formatted text from TextEdit document
tell application "System Events" to tell process "TextEdit"
	key code 0 using command down -- command-a or Select All
	delay 0.3
	key code 8 using command down -- command-c or Copy
end tell

end tell

– Paste formatted text into email message
tell application “Mail”
activate
delay 0.3
tell application “System Events” to tell process “Mail”
key code 48 – 4 x TAB to get to the text field
key code 48
key code 48
key code 48
key code 0 using command down – command-a or Select All
–delay 0.3
key code 9 using command down – command-v or Paste
end tell
end tell

– Quit TextEdit
tell application “TextEdit” to activate
delay 0.3
tell application “System Events” to tell process “TextEdit”
key code 12 using command down – command-q or Quit
delay 1
key code 51 using command down – command-delete or Don’t Save
delay 0.3
end tell

– Back to email-message for last edit
tell application “Mail” to activate
‘’’

Looks awkward but it seems to make sense. I’m glad you figured out a solution.

By the way…

It’s actually the ` character… the key above the tab (i.e. the tilde key). For clarification, key code 50. Currently you have what appears to be a combination of left and right single quotes, not the backtick.

Also, you can quit textedit without resorting to key codes.

quit without saving

Finally, when you make a new textedit document, you can include its text, like so:

make new document with properties {text:messageContent}

Awkward indeed. But the real awkward thing of course is that FileMaker Pro still can’t compose an email message with formatted text. It has been on the users’ wishlist for years and its forum is packed with people swapping ideas to get around it. But all of these assume knowledge of html and curl or java, which I don’t have.
I tried a similar workaround before and had FM export to PDF and let AppleScript get the text from there, but it turns out that Apple’s Preview is barely scriptable so that was a dead end.
Interestingly, no one on these forums has come up with using TextEdit as a go-between.

BTW, I used key codes to quit TextEdit, because if I use
quit without saving
TextEdit will still reopen the document the next time it is launched. So it doesn’t really discard it, but seems to assume it might still be needed some day. Obviously this leaves room for error and confusion if the script is run twice.
I have changed the line to your properties suggestion. Works fine, thanks!
Thanks also for clearing up the back tick! I was wondering why some lines appeared as script in my posts and some weren’t.

A while ago I spent a considerable amount of time to make a html email with AppleScript. See (Almost) Making a html email in AppleScript for Mail .

1 Like

Well, your NSSSharing-code is the first example I have seen that seems feasible to me. I know just enough html (I hope) to be able to paste my own text into your code. I’m going to see if it is possible to run this script from inside FileMaker and have it pull values from fields to compose the email. I will post the results, but it might take me a while. Thanks for sharing your script!
I suppose the someone@somewhere.com address is the account I would l like to send the email from, right?

1 Like

Yes, someone@somewhere.com should be the sending account.

It’s me again. Could I bother you to take a look at this?

What happened with the code posted by @Fredrik71?

Of course, you could always fall back on key codes again.

You can simulate command-option-f with this:

key code 3 using {command down, option down}

You’re right, I should have replied to Fredrik71 first (I just did). His code didn’t do anything. I’m not sure if it is required but his line every message of mailbox "INBOX" whose subject begins with theCode doesn’t seem to contain a verb, a command so to speak. Frustratingly, it it this very bit I couldn’t find in the Script Editor’s library. So I just tried list, find, show, display etc. But nothing works. I tried key codes but it didn’t give the same result: command-F opens an different find field and puts the code in there and the found set looks different too. But you suggested command-option-F, which works a lot better! That puts the code where it needs to be.

Just a quick courtesy reply: to avoid wandering into the off-topic I’ve replied to your suggestion in the other thread.