Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

AppleScript works for everything except Exchange server emails

Here is the script:


using terms from application "Mail"

set theRuleName to name of theRule

on perform mail action with messagestheMessagesfor ruletheRule

tell application "Mail"

repeat with eachMessage in theMessages

set theSender to extract name from (sender of eachMessage)

say "Mail from " & theSender using "Alex"

end repeat

end tell

end perform mail action with messages

end using terms from



It is called from a Mail rule. Here is the rule:


User uploaded file


It works for every incoming message except for those that originate from an Exchange account.

Here is the interesting part: If I manually "apply rules" by selecting the message and using Option ⌘ L then it speaks the name perfectly. It is only when the mail arrives (by checking for new mail, for instance) that the script does not appear to do anything.


More interesting: The email does get its background color set to Blue. So as far as I can tell, the Rule is being executed, but the script isn't.


Here is the Rule for everything else:


User uploaded file


(speakname5 is identical to speakname6 just without the voice "Alex" - here it is anyway)


using terms from application "Mail"

set theRuleName to name of theRule

on perform mail action with messagestheMessagesfor ruletheRule

tell application "Mail"

repeat with eachMessage in theMessages

set theSender to extract name from (sender of eachMessage)

say "Mail from " & theSender

end repeat

end tell

end perform mail action with messages

end using terms from

If I try to simply use the same Rule for everything it still does not work for the Exchange email account. That is the reason for two separate scripts - it was a troubleshooting attempt.


Why does it only work when manually "applying Rules"?


Is there anything else I can include in the speakname6 script to indicate that it is actually being called?


Here are all my Rules, so that their order is known:


User uploaded file

MacBooks  iMacs  iPods  AirPorts-OTHER, OS X Mountain Lion,  27 years Apple!

Posted on Nov 20, 2012 5:43 PM

Reply
Question marked as Best reply

Posted on Nov 21, 2012 11:20 AM

John

for debugging you could stick a beep in the script. What happens if you try speaking the subject rather than the sender?

27 replies

Nov 23, 2012 9:04 AM in response to Austin Kinsella1

Excellent idea!


Here is my revised script:



using terms from application "Mail"

set theRuleName to name of theRule

on perform mail action with messagestheMessagesfor ruletheRule

tell application "Mail"

repeat with eachMessage in theMessages

say "script entry"

set theSender to (extract name fromsender of eachMessage)

set theSubject to (extract name fromsubject of eachMessage)

say "Mail from " & theSender & "Regarding " & theSubject using "Alex"

say "script exit"

end repeat

end tell

end perform mail action with messages

end using terms from



This caught Mail red-handed with another failure to speak the sender's name from the Exchange account: when the Exchange email arrived, I heard "script entry" and nothing more.


Therefore it would appear that the script executes, but something is different about extracting the sender from an Exchange account vs. others.


Since I never heard "script exit" I conclude something in the above causes the entire script to abort... yet manually "applying rules" works just fine after the email is received. Is there a Console entry or other log that may be enlightening?


Other emails announce the name of the sender as well as the subject as you suggested.


Comparing the raw source of an Exchange email to ones that work obviously reveals many differences, but it still has a line that begins with "From:" just like everything else. It's obviously in a different place.


So what is different about extract name from for an Exchange email than others? Is there another way to parse the source of an Exchange email?

Nov 23, 2012 11:14 AM in response to John Galt

I'm not sure that

set theSubject to (extract name fromsubject of eachMessage)

will work. In a similar script I have

set theSubject to (subject of eachMessage) as text

So try that, and comment out set theSender ... and change the say to say theSubject

just to verify that that works.


Also, you don't need

set theRuleName to name of theRule

and you could take for rule theRule off the next line - you're not using either of them.


It might be interesting, as a separate test, to set theSender to senter of eachMessage (so not using extract) and then maybe say (count of theSender) to see if there is anything to be said!

Nov 23, 2012 11:37 AM in response to Austin Kinsella1

I'll try that.



Austin Kinsella1 wrote:


I'm not sure that

set theSubject to (extract name fromsubject of eachMessage)

will work.


It works for everything else, in the same manner that extract name fromsender of eachMessage works for extracting the sender's name, but I will try


set theSender to (sender of eachMessage) as text


for both sender and subject. Your suggestion is certainly simpler.


Also, you don't need

set theRuleName to name of theRule

and you could take for rule theRule off the next line - you're not using either of them.


I suspected that. I will comment them out. I deleted them and they were superfluous as you said.


It might be interesting, as a separate test, to set theSender to senter of eachMessage (so not using extract) and then maybe say (count of theSender) to see if there is anything to be said!


I'll let you know!


What should I expect from (count of theSender) ?


🙂

Nov 23, 2012 11:47 AM in response to John Galt

set theSender to (sender of eachMessage) as text


This is not ideal since it speaks (for example) "Apple Support Communities Updates discussions updates at apple dot com"


instead of simply "Apple Support Communities Updates" which is what I prefer, by using


set theSender to (extract name fromsender of eachMessage)


.

extract name from appears to extract just the name - without the email address part.



Odd observation: upon compiling the script AS changed text to rich text:


set theSender to (sender of eachMessage) as rich text

.


Message was edited by: John Galt

Nov 23, 2012 2:19 PM in response to Austin Kinsella1

say (count of theSender)


... always returns a non-zero result. I am not sure of its significance. The number ranged from eighteen to twenty-four to thirty-three. It may be the total number of emails from that sender in my Inbox.


Austin Kinsella1 wrote:


By omitting the extract name from part you are, hopefully, verifying that there is something to extract!


That is a good point too, but I think it's a red herring in this case.


There seem to be two varieties of "From" in an email raw source: those that include a name as well as an email address, and those that include only an email address. For example, today's email from Apple regarding their one day shopping event contains


From: Apple <News@InsideApple.Apple.com>


... and the only part that is extracted and spoken with my script is "Apple".


If the sender's name is not included as in the form above, the entry might resemble this:


From: Dilbert@MegaCorp.com


... and the name will be spoken as "Dilbert at MegaCorp dot com".


So I think the use of


extract name fromsender of eachMessage


is still OK.

Remember that the script executes fine if I manually "apply rules" to the message after it is received. Something else is going on with the way Exchange is doing things.


Anyway, you gave me some more ideas to try... thanks!


🙂

Nov 27, 2012 2:55 PM in response to Austin Kinsella1

Here is my revised, simply awful, script:


using terms from application "Mail"

on perform mail action with messagestheMessages

tell application "Mail"

repeat with eachMessage in theMessages

say "script entry"

set AppleScript's text item delimiters to {""}

set theSender to sender of eachMessage as string

set brkpos to offset of "<" in theSender

if (brkpos is greater than 1) then

say "break position is greater than one "

set theSender to (text items 1 through (brkpos - 1)) of theSender as string

if theSender contains "\"" then

say "the sender contains a quote "

set AppleScript's text item delimiters to {"\""}

set theSender to text item 2 of theSender as string

end if

else

say "break position is less than or equal to one "

if (brkpos is equal to 1) then

say "break position is equal to one "

set theSender to (text items 2 through -1) of theSender as string

end if

set AppleScript's text item delimiters to {"@"}

set theSender to text item 1 of theSender as string

end if

say "end break position test "

say "Mail from " & theSender

say "script exit"

end repeat

end tell

end perform mail action with messages

end using terms from



The result of all this is the same... a tortured way to extract the sender's name, which works but the results are exactly the same as the other one.

When an Exchange email arrives, the above script speaks "script entry" and that is the last I hear from it. All other emails speak the sender's name just fine. As before, manually "applying rules" after the email is received speaks the sender's name as I would expect.


So it is getting lost prior to "end break position test" but I have no idea why.

Nov 27, 2012 3:50 PM in response to John Galt

Time for some error handling?


after say "script entry" put in a line with just try

before end repeat put in 3 lines:

on error TheError

say TheError

end try


Also, as I understand it, a script will use the last set script delimiters, even if in a different script, so it is considered good practice at the start of a script to remember, and at the end of a script to restore, so you don't break some other script:

set OldDelim to Applescript's script item delimiters

...

set Applescript's script item delimiters to OldDelim

Nov 28, 2012 4:19 PM in response to Austin Kinsella1

Getting closer... the error handler caught something, but several emails arrived at once, and all I could decipher from the error handler was "can't make... application(?) ... (indecipherable) ... into type string."


I do not receive emails from the Exchange-centric puzzle palace often so I will have to wait until I receive another. Clearly there was something that could not be resolved into a string. The fact the script can resolve it after the email is received remains a mystery for now.



set OldDelim to Applescript's script item delimiters

...

set Applescript's script item delimiters to OldDelim


I did not do that yet.

Dec 3, 2012 10:33 PM in response to John Galt

John Galt wrote:


Getting closer... the error handler caught something, but several emails arrived at once, and all I could decipher from the error handler was "can't make... application(?) ... (indecipherable) ... into type string."


The error is "Can't make type sndr of item n of count application into type string".


where sndr is spoken as it is spelled: "S N D R"


and n = a number that began with 1 and was incremented by one up to 10. The error as it was spoken was


"Can't make type sndr of item n of count application count application count application... (this was repeated several times)... into type string."

Dec 6, 2012 7:29 PM in response to Frank Caggiano

Capital idea Frank!



User uploaded file


Austin - that makes sense. When the troublesome email arrives hopefully the above dialog will show something, because whatever arrives is apparently different than what the rule evaluates after the message resides in my Inbox. It would be nice to eliminate the parts between the brackets, which is the reason for converting it to a string. I suppose text should be no different. Clearly my script is objecting to making something "into type string". I have to find out what that something is.

AppleScript works for everything except Exchange server emails

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.