Pick of the Week - Nov 10 [Show all picks]
Path Finder 5 - A feature-laden Finder replacement
Submit Hint Search The Forums LinksStatsPollsFAQHeadlinesRSS
12,000 hints and counting!

Speak the sender of a mail item Apps
Here's a quick script to speak the name of the person sending you e-mail. I've seen scripts like this for entourage, but never for Apple's Mail.app. To use it, paste it into Script Editor, save, and create a mail rule that acts on every message and add it to the top of your list of mail rules. Set the action to "Run AppleScript" and choose your new script as the target.
on perform_mail_action(info)
  tell application "Mail"
    set theMessages to |SelectedMessages| of info
    repeat with thisMessage in theMessages
    set AppleScript's text item delimiters to {""}
    set thisSender to sender of thisMessage as string
    set quotepos to offset of "\"" in thisSender
      if (quotepos is not 0) then
        set thisSender to (text items (quotepos + 1) through -1) ¬
          of thisSender as string
        set quotepos to offset of "\"" in thisSender
        if (quotepos is not 0) then
          set thisSender to (text items 1 through (quotepos - 1)) ¬
            of thisSender as string
        end if
      else
        set atpos to offset of "@" in thisSender
        if (atpos is not 0) then
          set thisSender to (text items 1 through (atpos - 1)) ¬
            of thisSender as string
        end if
        set brkpos to offset of "<" in thisSender
        if (brkpos is not 0) then
          set thisSender to (text items (brkpos + 1) through -1) ¬
            of thisSender as string
        end if
      end if
      tell application "Finder" to say "Mail from " & thisSender
    end repeat
  end tell
end perform_mail_action
[robg adds: This worked as described ... see also this hint which explains how to speak the entire contents of messages.]
    •    
  • Currently 0.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (0 votes cast)
 
[13,713 views]  

Speak the sender of a mail item | 32 comments | Create New Account
Click here to return to the 'Speak the sender of a mail item' hint
The following comments are owned by whomever posted them. This site is not responsible for what they say.
Speak the sender of a mail item
Authored by: Ansel_Witty on Thu, Mar 6 2003 at 10:39AM PST
Seems like it works pretty well, but if the person doesn't put quotes around their name it jsut readys the username of their e-mail address... How can you add that it should read the name even without quotes if there are no quotes? or have it read the whole e-mail address if there is no name at all?

---
"I don't believe in mathematics!" - Albert Einstein

[ Reply to This | # ]
Timing is everything!
Authored by: porkchop_d_clown on Thu, Mar 6 2003 at 10:44AM PST
The no-quotes problem is actually one of the reasons I wrote the updated script. If you want to read the whole name, instead of just up to the @ sign, change the line

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

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

---
--
knock knock

[ Reply to This | # ]

Slightly better version...
Authored by: porkchop_d_clown on Thu, Mar 6 2003 at 10:40AM PST
I should remember that I don't write enough applescript to really write a good routine in one pass. This version is shorter and handles various name formats better.

on perform_mail_action(info)
	tell application "Mail"
		set theMessages to |SelectedMessages| of info
		repeat with thisMessage in theMessages
			set AppleScript's text item delimiters to {""}
			set thisSender to sender of thisMessage as string
			set brkpos to offset of "<" in thisSender
			if (brkpos is greater than 1) then
				set thisSender to (text items 1 through (brkpos - 1)) of thisSender as string
				if thisSender contains "\"" then
					set AppleScript's text item delimiters to {"\""}
					set thisSender to text item 2 of thisSender as string
				end if
			else
				if (brkpos is equal to 1) then
					set thisSender to (text items 2 through -1) of thisSender as string
				end if
				set AppleScript's text item delimiters to {"@"}
				set thisSender to text item 1 of thisSender as string
			end if
			tell application "Finder" to say "Mail from " & thisSender
		end repeat
	end tell
end perform_mail_action

---
--
knock knock

[ Reply to This | # ]

Slightly better version...
Authored by: splattertrousers on Thu, Mar 6 2003 at 2:28PM PST
I modified your script to also speak the subject. My script removes "Re:", "Fwd:", etc. from the beginning of the script. I also tried to get it to remove things in brackets or parentheses. The code works when I test it from ScriptEditor, but not when Mail runs it. The only difference is that when I test it from ScriptEditor, I remove all the Mail-specific code, and the outer function. Does anyone have any ideas?

Anyway, here's the script (sorry for the lousy formatting, but when I post as HTML, the > and < signs screw up the output):

on perform_mail_action(info)
tell application "Mail"
set theMessages to |SelectedMessages| of info
repeat with thisMessage in theMessages

set AppleScript's text item delimiters to {""}
set thisSender to sender of thisMessage as string
set brkpos to offset of "<" in thisSender
if (brkpos is greater than 1) then
set thisSender to (text items 1 through (brkpos - 1)) of thisSender as string
if thisSender contains "\"" then
set AppleScript's text item delimiters to {"\""}
set thisSender to text item 2 of thisSender as string
end if
else
if (brkpos is equal to 1) then
set thisSender to (text items 2 through -1) of thisSender as string
end if
set AppleScript's text item delimiters to {"@"}
set thisSender to text item 1 of thisSender as string
end if

set thisSubject to subject of thisMessage as string

-- remove "Re:", "Fwd:", etc.
set AppleScript's text item delimiters to {""}
set colonpos to offset of ":" in thisSubject
if (colonpos < 5) then
set thisSubject to (text items (colonpos + 1) through -1) ¬
of thisSubject as string
end if

-- remove text between [ and ]; and between ( and )
-- I can't get these next two lines to work when calling this from Mail
-- but they work when running from ScriptEditor (though I take this
-- part out of the perform_mail_action subroutine)
--set thisSubject to removeTextBetween(thisSubject, "[", "]")
--set thisSubject to removeTextBetween(thisSubject, "(", ")")

tell application "Finder" to say "Mail from, " & thisSender ¬
& ", regarding, " & thisSubject

end repeat
end tell
end perform_mail_action

-- removes any text between "a" and "b" in "s"; returns the result
-- doesn't handle the case where a...b is nested inside another a...b
-- (because there's no "last offset of" and I didn't feel like writing one
-- (hey, it's the first AppleScript I have written since System 7 days...)
on removeTextBetween(s, a, b)
repeat while ((s contains a) and (s contains b))

set aIndex to offset of a in s
set bIndex to offset of b in s

if ((aIndex > 0) and (bIndex > aIndex)) then

if (aIndex > 1) then
set beforeA to (text items 1 through (aIndex - 1)) ¬
of s as string
else
set beforeA to ""
end if

if (bIndex < (length of s)) then
set afterB to (text items (bIndex + 1) through -1) ¬
of s as string
else
set afterB to ""
end if

set s to beforeA & " " & afterB

end if

end repeat

return s
end removeTextBetween

[ Reply to This | # ]
Slightly better version...
Authored by: porkchop_d_clown on Thu, Mar 6 2003 at 4:31PM PST
Use the meta-tags [code] and [/code] when doing HTML formatting and it will correctly handle the script.

---
--
knock knock

[ Reply to This | # ]
Slightly better version...
Authored by: vanstra on Sat, Mar 8 2003 at 2:39PM PST
I've tried this, but it doesn't seems to work. Must I activate the speech in MacOSX ? What rule do I have to add in Mail ?

[ Reply to This | # ]
Speak the sender of a mail item
Authored by: davidcrickett on Thu, Mar 6 2003 at 10:46AM PST
Very nice! :-)

---
davidcrickett

[ Reply to This | # ]
thanks.
Authored by: porkchop_d_clown on Thu, Mar 6 2003 at 10:51AM PST
I found it a big help because I have a couple of machines in the office, and my ibook is usually behind me. When mail comes in, I can decide whether or not I should stop what I'm doing and turn around...


---
--
knock knock

[ Reply to This | # ]
Speak the sender of a mail item
Authored by: falkaholic on Thu, Mar 6 2003 at 1:39PM PST
I swear I looked in rules for a Run AppleScipt command. Now it is there? how new is it?

[ Reply to This | # ]
Speak the sender of a mail item
Authored by: Cerberus on Sat, Mar 8 2003 at 7:17AM PST
Well it isn't in 10.1 so I would say it is NEW.

[ Reply to This | # ]
I needed a small change
Authored by: daveedvdv on Thu, Mar 6 2003 at 2:22PM PST
I'm not accustomed to AppleScript (yet), but I had to change the line
    tell application "Finder" to say ...
to simply
    say ...
Since noone else mentioned it, I suspect I might have something misconfigured somewhere. Oh well, it works now.

[ Reply to This | # ]
I needed a small change
Authored by: porkchop_d_clown on Thu, Mar 6 2003 at 4:35PM PST
Interesting. The only reason I have it that way, is because I saw another script that did it that way. I wonder what the difference is.

---
--
knock knock

[ Reply to This | # ]
tell..
Authored by: Accura on Thu, Mar 6 2003 at 9:08PM PST
The difference will be that with the "tell.." line that finder will speak the text, but with out the system will speak. The dock is a good app to use to do things, if im going to get a dialog to display i tell the dock to do it as it is allways in front of everything

---
"The time has come," the walrus said. "To talk of many things..."

[ Reply to This | # ]
Me Too
Authored by: yoel on Thu, Mar 6 2003 at 9:31PM PST
tell application "Finder" to say "foo"

gives the following error message:

Finder got an error: "foo" doesn't understand the say message.

However,

say "foo"

works as expected. This is on 10.2.4.

[ Reply to This | # ]

But it works fine for me. Hmmm....
Authored by: dcollett on Fri, Mar 7 2003 at 3:08AM PST
I used the original: tell application "Finder" to say "Mail from " & thisSender and it works fine for me (10.2.4). Why would AppleScript perform differently for different users?

[ Reply to This | # ]
But it works fine for me. Hmmm....
Authored by: porkchop_d_clown on Fri, Mar 7 2003 at 10:39AM PST
I don't know, but I realized last night you don't need the "tell application 'Finder'" clause at all. say is in the "standard extensions" library, it's not part of the finder.

---
--
knock knock

[ Reply to This | # ]
Speak the sender of a mail item
Authored by: keana on Thu, Mar 6 2003 at 3:14PM PST
This is cool. I am finding it very useful! I only wish I could write apple scripts. It's on my list of things to learn. Thanks for the very useful and very cool script!

[ Reply to This | # ]
adjusting volume?
Authored by: TTop on Thu, Mar 6 2003 at 4:24PM PST
This is a great script! My only complaint is that the spoken words seem much louder than they should be -- specifically in relation to iTunes, which I already have turned up to about 85% of max. Is there a way to modify the script so that the volume is toned down a bit? I poked around in System Preferences under both Sound and Speech and couldn't seem to find any way to adjust only the Speech items.

[ Reply to This | # ]
adjusting volume?
Authored by: porkchop_d_clown on Thu, Mar 6 2003 at 4:46PM PST
Unfortunately, I don't think you can. Say doesn't take a volume argument.

---
--
knock knock

[ Reply to This | # ]
adjusting volume?
Authored by: hayne on Thu, Mar 6 2003 at 7:25PM PST
You could do:
set volume 3.0
to turn down the volume before speaking the email
and then
set volume 5.8
to turn it back up
The AppleScript "set volume" command can set the volume between 0.0 and 7.0

[ Reply to This | # ]
adjusting volume? -- Yes you can!
Authored by: ghoppe on Sun, Mar 9 2003 at 2:08AM PST

You can adjust the volume by changing this line:

tell application "Finder" to say "Mail from " & thisSender

to

tell application "Finder" to say "[[volm 0.7]] Mail from" & thisSender

Toy with the value 0.7 (0=silence, 1.0=max) until you find a volume you find reasonable. Instead, you could use + or - before the number to raise or lower the volume.

Apple has a list of embedded speech commands on their site.

For example, if you want your mac to speak rapidly you could:

tell application "Finder" to say "[[rate 300]] Mail from" & thisSender



[ Reply to This | # ]
Speak the sender of a mail item
Authored by: matt_j_gray on Thu, Mar 6 2003 at 5:34PM PST
I'd written something similar a while back - the only problem I have with my script and this new one is that Mail doesn't seem to be threaded when it is running its rules. This means when I check my mail in the morning and there are lots of mails that arrive in one hit, Mail reads out all the senders, and I can't do anything else in Mail at the same time.

In other programs (such as Eudora), I think you can keep reading, navigating, etc, in other messages when it is reading out new things. But this script locks Mail up until it is finished.

Any ideas how to make it threaded? Or is that asking way too much of AppleScript? I'm guessing it needs some alteration to the Mail app.

[ Reply to This | # ]
Check the unread count?
Authored by: porkchop_d_clown on Fri, Mar 7 2003 at 2:00PM PST
It seems like the whole applescript interface in mail needs a rework; I've been having lots of issues with things like moving mail inside a script and so on.

My best suggestion at this point would be to add an outer if statement that would cause the rule to do nothing if the number of unread messages was too high.


---
--
knock knock

[ Reply to This | # ]
Changing the voice
Authored by: figz on Thu, Mar 6 2003 at 7:22PM PST
I changed mine to:

tell application "Finder" to say "New message from " & thisSender using "Bruce"

...but you can say "Fred" or "Zarvox" or any of the many other voices in the Speech preference pane that floats your boat!

[ Reply to This | # ]
Here's my take
Authored by: jcstudio on Fri, Mar 7 2003 at 9:35AM PST
Okay, I this may be going over the top. But it's so fun!
on perform_mail_action(info) tell application "Mail" set theMessages to |SelectedMessages| of info repeat with thisMessage in theMessages set AppleScript's text item delimiters to {""} set thisSender to sender of thisMessage as string set thisSubject to subject of thisMessage as string set brkpos to offset of "

[ Reply to This | # ]
Here's my take (again)
Authored by: jcstudio on Fri, Mar 7 2003 at 9:40AM PST
Whoops! I guess I don't understand how to use the <code> tag. Here it is in plain text:

on perform_mail_action(info)
tell application "Mail"
set theMessages to |SelectedMessages| of info
repeat with thisMessage in theMessages
set AppleScript's text item delimiters to {""}
set thisSender to sender of thisMessage as string
set thisSubject to subject of thisMessage as string
set brkpos to offset of "<" in thisSender
if (brkpos is greater than 1) then
set thisSender to (text items 1 through (brkpos - 1)) of thisSender as string
if thisSender contains "\"" then
set AppleScript's text item delimiters to {"\""}
set thisSender to text item 2 of thisSender as string
end if
else
if (brkpos is equal to 1) then
set thisSender to (text items 2 through -1) of thisSender as string
end if
set AppleScript's text item delimiters to {"@"}
set thisSender to text item 1 of thisSender as string
end if
say "You have new Mail from " using "Victoria"
say thisSender using "Bruce"
say "regarding" using "Victoria"
say thisSubject using "Bruce"
end repeat
end tell
end perform_mail_action

[ Reply to This | # ]
Here's my take (again)
Authored by: porkchop_d_clown on Fri, Mar 7 2003 at 10:41AM PST
use [code] and [/code] not <code> and </code> - [code] is an instruction to the discussion software here to preserve line breaks and indenting.

---
--
knock knock

[ Reply to This | # ]
Speak the sender of a mail item
Authored by: matt_j_gray on Sun, Mar 9 2003 at 10:22PM PST
Yep, that is indeed what I do anyway. Oh well, hopefully the next release of Mail will be a bit more threaded.

[ Reply to This | # ]
Enhanced, threaded version
Authored by: Hugin777 on Thu, Mar 25 2004 at 8:51AM PST
Advantages:
  1. Get the big picture - if you get three mails from the same sender, John, it will simply say "New mail: three from John". If you get a lot of mail it will just say e.g. "New mail: from 6 different senders !"
  2. Threaded - does not block Mail.app while announcing
Examples:
  • New mail: from Michael.
  • New mail: From 3 different senders ! 2 from Erik. 3 junk. 1 from John.
  • New mail: From 5 different senders !

The script has to be saved as a Stay-open script, as it needs to monitor Mail.app in the background. It will Quit itself when the announcement is done.

IMPORTANT: You need to save the script as a program, and check "Stay open" !


property announceJunk : false -- should junk mail be announced too ?
property senderCntThreshold : 2 -- more than this, and the count is announced
property senderCntMax : 4 -- more than this, and only the count is announced
property voiceVolume : "0.7"

property senderList : {}
property firstRun : true -- don't do anything at first run of idle

using terms from application "Mail"
	on perform mail action with messages theMessages
		repeat with thisMessage in theMessages
			set thisSender to extract name from sender of thisMessage
			set junk to junk mail status of thisMessage
			tell application "Mailmelding"
				-- We have to run ourselves :-/
				--  If we didn't use "tell" the run method would never be called...
				newMail(thisSender, junk)
			end tell
		end repeat
	end perform mail action with messages
end using terms from

on newMail(thisSender, junk)
	if junk then
		if not announceJunk then
			return
		end if
		set thisSender to " junk "
	end if
	set found to false
	repeat with x in my senderList
		if sender of x is equal to thisSender then
			set cnt of x to (cnt of x) + 1
			set found to true
			exit repeat
		end if
	end repeat
	if not found then
		copy {sender:thisSender, cnt:1} to end of my senderList
	end if
end newMail

on idle
	if firstRun then
		set firstRun to false
		return 2
	end if
	tell application "Mail"
		set mailIdle to background activity count = 0
	end tell
	if mailIdle then
		set senderCount to count of senderList
		if senderCount = 0 then
			set firstRun to true
			quit
			return 0
		end if
		
		set sayStr to "[[volm " & voiceVolume & "]]" & "New mail:" & space
		
		if senderCount > senderCntThreshold then
			set sayStr to sayStr & "From " & senderCount & " different senders !" & space
		end if
		if senderCount is less than or equal to senderCntMax then
			--  Report the findings
			repeat with x in senderList
				set thisSender to sender of x
				set cnt to cnt of x
				set sayStr to sayStr & spokenPrefix(senderCount, cnt) & space
				if thisSender is " junk " then
					set sayStr to sayStr & "junk." & space
				else
					set sayStr to sayStr & "from " & pickFirstPart(thisSender) & "." & space
				end if
			end repeat
		end if
		say sayStr
		set senderList to {}
		set firstRun to true
		quit
	end if -- mailIdle
	return 2 -- Call again every 2 seconds...
end idle

on spokenPrefix(senderCount, cnt)
	if senderCount = 1 and cnt = 1 then
		return ""
	else
		return (cnt as text)
	end if
end spokenPrefix

on pickFirstPart(emailOrName)
	set oldDelim to AppleScript's text item delimiters
	if emailOrName contains "@" then
		set AppleScript's text item delimiters to {"@"}
	else
		set AppleScript's text item delimiters to {" "}
	end if
	return first text item of emailOrName
	set AppleScript's text item delimiters to oldDelim
end pickFirstPart


[ Reply to This | # ]
Correction !!!!
Authored by: Hugin777 on Thu, Mar 25 2004 at 9:07AM PST
Whoops, you have to change the string "Mailmelding" to the name you choose for the script !

If you save the script as "Mail-announcer", then change this line:

tell application "Mailmelding"

to this:

tell application "Mail-announcer"


[ Reply to This | # ]
Enhanced, threaded version
Authored by: mikeall on Mon, Mar 29 2004 at 2:18AM PST
I tried to cut and paste this one and make it into an apple script but it won't compile in Jaguar using Script Editor 1.9.
The error says:
Expected "given", "into", "with", "without" or other parameter name but found identifier.

The script looks like it would be great so any help will be appreciated.

---
Mike
http://allbutt.homeip.net/

[ Reply to This | # ]
Enhanced, threaded version
Authored by: Hugin777 on Sun, Apr 18 2004 at 10:25AM PDT
Sorry, I'm no AppleScript expert. It works in Panther as far as I know...

[ Reply to This | # ]