Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Use Speech to announce new Mail messages Apps
I am very careful about who I give my main e-mail address out to, and as a result I literally get no junk mail. When I do get an e-mail, it's usually important and I should read it right away. So I wrote an AppleScript that does the following (and set it up as a rule in Mail so that occurs every time I get a new message ):
  1. Pauses iTunes (so I can hear what it has to say)
  2. Using Apple's Speech technology, it says "You have mail from: " and then it says out loud each person I received e-mail from
  3. Next it opens each e-mail message and then activates mail, so I can read the whole message


Script is as follows:
using terms from application "Mail"  
  -- This is what allows this AppleScript to run as a Rule  
  on run  
    --Performs the following action on each new mail received  
    tell application "Mail" to set sel to selection  
    tell me to perform mail action with messages (sel)  
  end run  
end using terms from  
  
using terms from application "Mail"  
  on perform mail action with messages selectedMsgs  
    -- See Mail's AppleScript dictionary for the full documentation on the  
    -- 'perform mail action with messages' handler.  
    tell application "iTunes"  
      --Pause iTunes to you can hear it what says next  
      pause  
    end tell  
    say "You have mail from"  
    set logString to "" & return  
    tell application "Mail"  
      set selCount to (count of selectedMsgs)  
      --A little bit of error handling  
      if selCount is equal to 0 then  
        set logString to logString & "There are no selected messages."  
      else if selCount is equal to 1 then  
        set logString to logString & "There is " & selCount 
        & " selected message."  
      else if selCount > 1 then  
        set logString to logString & "There are " & selCount 
        & " selected messages."  
      end if  
      repeat with counter from 1 to selCount  
        set msg to item counter of selectedMsgs  
        set theSubject to subject of msg  
        set theSender to sender of msg  
        set theSender to extract name from theSender  
        set logString to (logString & tab & "Message " & counter as string) 
        & " from: " & theSender & ", subject: " & theSubject & ".  "  
        if length of logString > 0 then  
          --note that you could have it speak the subject as well  
          say ":" & theSender  
        end if  
        --open the message in mail in a new window  
        open msg  
          
      end repeat  
    end tell  
    --open up mail to read the new messages  
    tell application "Mail"  
      activate  
    end tell  
      
  end perform mail action with messages  
end using terms from  
After saving the script somewhere, make sure you make a new Rule in Mail and set the conditions to match every message (or you could just have it run on select messages) and the action to run your newly saved script. I'm sure some AppleScript guru out there could improve and streamline my script, but it works for me!
    •    
  • Currently 3.00 / 5
  You rated: 4 / 5 (3 votes cast)
 
[14,528 views]  

Use Speech to announce new Mail messages | 29 comments | Create New Account
Click here to return to the 'Use Speech to announce new Mail messages' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Use Speech to announce new Mail messages
Authored by: bhippel on Apr 23, '04 12:13:55PM

This is terrific, works like a champ! Very cool!



[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: joestalin on Apr 23, '04 01:11:15PM

This has been reported before, in some form or another: here (scroll down for a Mail.app script) and here. I'm using a variation on the latter script.

If you use Groups intelligently in your Address Book, it is easy to set this action to trigger only when receiving mail from friends; or you could just trigger it on people listed in your address-book, period.



[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: gdsimms on Apr 23, '04 02:24:24PM

Of course, because of the immediate audible interruption, this takes away one of the advantages email has over the telephone.



[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: hairyhelpfuldave on Apr 23, '04 03:34:08PM

Wow, this is really cool. I modified the script a little so it doesn't open the messages or activate mail (which seemed a bit intrusive). I also changed it so there is only one 'say' command rather than 2 (it waits until its worked out who its from before starting to talk). Very useful.



[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: ka on Apr 23, '04 04:20:25PM

Great! Only one simple question: How can I make itunes playing again after that?



[ Reply to This | # ]
Modified script that makes iTunes play after everything is done
Authored by: nosaj56 on Apr 23, '04 04:34:47PM

using terms from application "Mail"
-- This is what allows this AppleScript to run as a Rule
on run
--Performs the following action on each new mail received
tell application "Mail" to set sel to selection
tell me to perform mail action with messages (sel)
end run
end using terms from

using terms from application "Mail"
on perform mail action with messages selectedMsgs
-- See Mail's AppleScript dictionary for the full documentation on the
-- 'perform mail action with messages' handler.
tell application "iTunes"
--Pause iTunes to you can hear it what says next
pause
end tell
say "You have mail from"
set logString to "" & return
tell application "Mail"
set selCount to (count of selectedMsgs)
--A little bit of error handling
if selCount is equal to 0 then
set logString to logString & "There are no selected messages."
else if selCount is equal to 1 then
set logString to logString & "There is " & selCount
& " selected message."
else if selCount > 1 then
set logString to logString & "There are " & selCount
& " selected messages."
end if
repeat with counter from 1 to selCount
set msg to item counter of selectedMsgs
set theSubject to subject of msg
set theSender to sender of msg
set theSender to extract name from theSender
set logString to (logString & tab & "Message " & counter as string)
& " from: " & theSender & ", subject: " & theSubject & ". "
if length of logString > 0 then
--note that you could have it speak the subject as well
say ":" & theSender
end if
--open the message in mail in a new window
open msg

end repeat
end tell
--open up mail to read the new messages
tell application "Mail"
activate
end tell

tell application "iTunes"
--Tell iTunes to play again
play
end tell

end perform mail action with messages
end using terms from



[ Reply to This | # ]
Modified script that makes iTunes play after everything is done
Authored by: Chris Biagini on Apr 25, '04 04:23:57PM

What if iTunes wasn't playing? Won't this modified version start playing music every time you get a new message?



[ Reply to This | # ]
You're right. Modify like this...
Authored by: Xeo on Apr 25, '04 10:29:38PM
You can just find out if iTunes is playing before you mess with it. Pause if it's playing, then play again when you're all done.
tell application "iTunes"
	set isPlaying to player state is playing
end tell

if isPlaying then
	tell application "iTunes" to pause
end if

-- later, after announcing the e-mail

if isPlaying then
	tell application "iTunes" to play
end if


[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: nosaj56 on Apr 23, '04 04:40:42PM

this script is so cool



[ Reply to This | # ]
could be embarassing
Authored by: SOX on Apr 23, '04 05:28:01PM

Let's hope the Mike Hunt, and Hugh G. Rection dont send you and e-mail.



[ Reply to This | # ]
Here is the script I use.
Authored by: raven42rac on Apr 23, '04 05:32:50PM

I set it as a rule, after I filter out Spam, so that it does not announce my spam. This does not switch to mail or display the message, it just tells you from who your new mail came.
<code>
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
</code>



[ Reply to This | # ]
Now with syntax!
Authored by: raven42rac on Apr 23, '04 05:36:21PM

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


[ Reply to This | # ]
Modified with fader and check to see if itunes is playing
Authored by: storrence on Apr 23, '04 07:15:49PM

using terms from application "Mail"
-- This is what allows this AppleScript to run as a Rule
on run
--Performs the following action on each new mail received
tell application "Mail" to set sel to selection
tell me to perform mail action with messages (sel)
end run
end using terms from

using terms from application "Mail"
on perform mail action with messages selectedMsgs
-- See Mail's AppleScript dictionary for the full documentation on the
-- 'perform mail action with messages' handler.

tell application "iTunes"
if player state is playing then
set sndbeg to sound volume
repeat
set snd to sound volume
if snd is less than or equal to 20 then
exit repeat
end if
set sound volume to (snd - 5)
delay 0
end repeat
end if
end tell

say "You have mail from"
set logString to "" & return
tell application "Mail"
set selCount to (count of selectedMsgs)
--A little bit of error handling
if selCount is equal to 0 then
set logString to logString & "There are no selected messages."
else if selCount is equal to 1 then
set logString to logString & "There is " & selCount
& " selected message."
else if selCount > 1 then
set logString to logString & "There are " & selCount
& " selected messages."
end if
repeat with counter from 1 to selCount
set msg to item counter of selectedMsgs
set theSubject to subject of msg
set theSender to sender of msg
set theSender to extract name from theSender
set logString to (logString & tab & "Message " & counter as string)
& " from: " & theSender & ", subject: " & theSubject & ". "
if length of logString > 0 then
--note that you could have it speak the subject as well
say ":" & theSender
end if
end repeat
end tell

tell application "iTunes"
if player state is playing then
repeat
set snd to sound volume
if snd is greater than or equal to sndbeg then
exit repeat
end if
set sound volume to (snd + 10)
delay 0.1
end repeat
end if
end tell

end perform mail action with messages
end using terms from

---
Steve



[ Reply to This | # ]
Modified with fader and check to see if itunes is playing
Authored by: abacsalmasi on Apr 23, '04 07:38:13PM

Keep getting syntax error

"Expected end of line, etc. but found identifier"

and it highlights the word - mail - in the text I've included.


" tell me to perform mail action with messages (sel) "

Any ideas?

---
My eyes, my eyes, these goggles do nothing!



[ Reply to This | # ]
Modified with fader and check to see if itunes is playing
Authored by: PancakeMan on Apr 28, '04 11:59:49AM

I get the same error. Is this a Panther-only script? (I'm on Jaguar).



[ Reply to This | # ]
Modified with fader and check to see if itunes is playing
Authored by: tbolt502 on Apr 23, '04 08:41:49PM

OK, so many of us probably live with Itunes on constantly. However, in the rare case that iTunes is not running, all of the scripts here would start iTunes.

Probably not sensible.

Using modified code from plenty of other postings here at MacOSXHints.com to check if an application is running means we can avoid starting iTuines if it is not running. Surround each of the two blocks which control the iTunes Volume with the following:

tell application "System Events"
	if (get name of processes contains "iTunes") then
-- THE iTunes VOLUME CONTROL ROUTINES GO HERE!

	end if
end tell
Just a wee note.

[ Reply to This | # ]
Modified with fader and check to see if itunes is playing
Authored by: Chris Biagini on Apr 25, '04 04:27:49PM

Beautiful! Fine work, gentlemen!



[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: asan102 on Apr 23, '04 07:40:59PM

Maybe I'm missing something, but this wouldn't work if Mail's not already running, would it? If it's implemented as a mail rule, Mail.app only checks for new messages when it's actually open, so wouldn't it always be open when this script is run? Why do you need to tell Mail.app to launch?



[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: Glide on Apr 24, '04 12:54:43PM

I have mail.app in my startup items and set as hidden so it simply runs in the dock at all times. That way it can poll automatically without me having to fire it up every time to check my mail as well the window won't be in my way or inflating my dock with a minimized window. The original post of the script will simply activate the window (if it's not already open it will open a new one). Unless ram is VERY scarce I see no reason why anyone wouldn't want to keep it running in this fashion. Give 'er a try and see if you like it. But yes if it isn't running at all then it will open mail. Which is rather necessary to get your mail anyway unless you use something else to poll for pop3?



[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: Glide on Apr 24, '04 01:03:01PM

oops I missed something. If you run the script manually then it will open mail.app. So then you would probably have to run it from a cron job but then it'll basically have the same effect as if you run mail.app all the time and using the applscript in a rule instead. After the first run though mail.app will remain running anyway. So I'd just go with the startup item/hidden way of doing it in the first place.



[ Reply to This | # ]
A very improved version
Authored by: momerath on Apr 25, '04 01:11:34AM
This version incorporates several improvements made by the above posters as well as an additional one: if there is new mail from several people, it will format it as a list and read it (e.g. for two emails, "You have mail from Bob and Joe," and for three, "You have email from Bob, Jane, and Joe.") The other improvements are: the iTunes fader works it checks to see if iTunes is open before touching it (thus avoiding opening it if it's not open or playing a song if one isn't playing) it doesn't activate the message (I got rid of the log stuff because it is unnecessary)
using terms from application "Mail"
	on run
		tell application "Mail" to set sel to selection
		tell me to perform mail action with messages (sel)
	end run
end using terms from

using terms from application "Mail"
	on perform mail action with messages selectedMsgs
		set reactivate to false
		tell application "System Events"
			set the process_flag to (exists process "iTunes")
		end tell
		if the process_flag then
			tell application "iTunes"
				if player state is playing then
					repeat
						set snd to sound volume of application "iTunes"
						if snd is less than or equal to 30 then
							exit repeat
						end if
						set sound volume of application "iTunes" to (snd - 10)
						delay 0.1
					end repeat
					set reactivate to true
				end if
			end tell
		end if
		
		set logString to "" & return
		set speakString to "You have mail from "
		tell application "Mail"
			set selCount to (count of selectedMsgs)
			repeat with counter from 1 to selCount
				set msg to item counter of selectedMsgs
				set theSender to sender of msg
				set theSender to extract name from theSender
				if length of theSender > 0 then
					if selCount > 1 and counter is selCount then
						set speakString to speakString & " and "
					end if
					set speakString to speakString & theSender
					if (selCount - counter) > 0 and selCount > 2 then
						set speakString to speakString & ", "
					end if
				end if
			end repeat
			set speakString to speakString & "."
			say speakString
		end tell
		
		if reactivate is true then
			tell application "iTunes"
				repeat
					set snd to sound volume of application "iTunes"
					if snd is greater than or equal to 100 then
						exit repeat
					end if
					set sound volume of application "iTunes" to (snd + 10)
					delay 0.1
				end repeat
			end tell
		end if
	end perform mail action with messages
end using terms from


[ Reply to This | # ]
A very improved version
Authored by: rarora-resume@ma on May 02, '04 12:12:54PM

this is a great script, i have a problem with it though. The volume for itunes gets maxed out everytime the script is run. How do I change so that it simplly goes back to the original volume state? If that's too much code, how about setting the volume to the middle?



[ Reply to This | # ]
A very improved version
Authored by: rarora-resume@ma on May 02, '04 12:34:41PM

okay so i got it set the volume to 50%, i got a little confused by the fader effect.

I'm still working on capturing the original volume(before the fade out). I would imagine it's pretty easy, I'm new to Apple script and macs too(just switched two weeks ago).



[ Reply to This | # ]
A very improved version
Authored by: rarora-resume@ma on May 02, '04 12:53:00PM

Okay, I figured it out :) I also changed the fader to fade in and out more gradually (+5, -5). It's seems like a smoother operation now.



[ Reply to This | # ]
Adapted, not wrote...
Authored by: mhv on Apr 25, '04 05:31:10PM
Ahem, I don't want to spoil the fun, but although you have done yourself the work of making the script do what you say it intends to do, you should still have mentionned, for the sake of honesty, and Apple's licensing (see below) that you took a sample Applescript that comes with Panther, and adapted it here and there to add the functions. You didn't even bother changing the variables' name. See:

/Library/Scripts/Mail Scripts/Script Menu/Speak Sender and Subject___ctl-s.scpt


(*
Speak Sender and Subject

Copyright © 2003 Apple Computer, Inc.

You may incorporate this Apple sample code into your program(s) without
restriction.  This Apple sample code has been provided "AS IS" and the
responsibility for its operation is yours.  You are not permitted to
redistribute this Apple sample code as "Apple sample code" after having
made changes.  If you're going to redistribute the code, we require
that you make it clear that the code was descended from Apple sample
code, but that you've made changes.
*)

(*
This script demonstrates how to write a script that can be executed
directly from the Scripts menu in Mail. It acts on the selected messages,
which are passed in to the 'perform mail action with messages' handler.

This script also demonstrates the syntax for adding a keyboard shortcut to
a Scripts menu item. You can do this by suffixing the name of the script with
three underscore characters, then the keyboard shortcut. For example:

MyScript___ctl-shift-Y
MyScript___opt-cmd-Z
*)

using terms from application "Mail"
	on perform mail action with messages selectedMsgs
		-- See Mail's AppleScript dictionary for the full documentation on the
		-- 'perform mail action with messages' handler.
		set logString to "" & return
		tell application "Mail"
			set selCount to (count of selectedMsgs)
			if selCount is equal to 0 then
				set logString to logString & "There are no selected messages."
			else if selCount is equal to 1 then
				set logString to logString & "There is " & selCount & " selected message."
			else if selCount > 1 then
				set logString to logString & "There are " & selCount & " selected messages."
			end if
			repeat with counter from 1 to selCount
				set msg to item counter of selectedMsgs
				set theSubject to subject of msg
				set theSender to sender of msg
				set theSender to extract name from theSender
				set logString to (logString & tab & "Message " & counter as string) & " from: " & theSender & ", subject: " & theSubject & ".  "
			end repeat
		end tell
		if length of logString > 0 then
			say logString
		end if
	end perform mail action with messages
end using terms from

-- If run as an ordinary script, instead of directly from the Scripts
-- menu, it will call the default handler instead.
using terms from application "Mail"
	on run
		tell application "Mail" to set sel to selection
		tell me to perform mail action with messages (sel)
	end run
end using terms from


[ Reply to This | # ]
Adapted, not wrote...
Authored by: groundspeed on Apr 25, '04 07:01:18PM

Tried this script but it didn't work as posted,

1) I had to put underscores for "perform_mail_action_with_messages(sel)"

2) script editor doesn't understand "extract name" with or without underscores. It isn't in Mail's dictionary. Do I need a newer versiion of mail? I have 1.2.5 (v553).

3) I set a rule in Mail set to every message and to run the script. I tried pointing to other scripts but it won't run any when new mail comes in. Other rules work fine.

What am I doing wrong?

---
When I die, I want to go peacefully in my sleep, like my Grandfather, not screaming in terror like his passengers.



[ Reply to This | # ]
Whoops! Apologies in order...
Authored by: hotcocoa on Apr 26, '04 08:04:20PM

Hey, this is the original poster of the hint. First and foremost let me apologize and clarify. I did take the code from an Apple demo script. The reason I didn't mention this is because I have been using the script for so long that I honestly forgot. I definitely did not try to intentionally take credit for something I didn't do; so I'm sorry.

Second, thanks for all the great improvements! I don't spend any time really with AppleScript and it's been fun to see what everyone has come up in terms of improvements. Cool!



[ Reply to This | # ]
Is there a way to do this with Entourage?
Authored by: MacPlaya on May 10, '04 07:30:53PM

Is there a way to do this with Entourage?



[ Reply to This | # ]
Use Speech to announce new Mail messages
Authored by: GlowingApple on Mar 31, '05 09:32:53PM
So just in case anyone is still looking at this thread, here is my latest revision of the script (I'm running it on Panther):

(*
Speak New Mail Script
Origional code (Copyright © 2003 Apple Computer, Inc.) taken from Apple sample code at 
/Library/Scripts/Mail Scripts/Script Menu/Speak Sender and Subject___ctl-s.scpt

Origional modification by hotcocoa and several other modifications taken from 
http://www.macosxhints.com/article.php?story=20040422104515106&query=speak+mail.

Final modification by Jayson Kempinger 2005
*)

(*
This script runs when Mail.app gets new mail.  Each mail message is parsed for name and subject, iTunes is paused by
manner of fading out (if it is running), the message notification is spoken, and iTunes is resumed to it's prior state.

Use this script in a Mail.app rule.
Precede it with a rule "If any, Message is junk mail, then Stop evaluating rules" to prevent this script from speaking
junk mail as well.
*)

on perform_mail_action(info)
	--if iTunes is playing, fade out
	set reactivate to false
	tell application "System Events"
		if the exists process "iTunes" then
			tell application "iTunes"
				if player state is playing then
					set orig_vol to sound volume of application "iTunes"
					repeat
						set snd to sound volume of application "iTunes"
						if snd is less than or equal to 30 then
							exit repeat
						end if
						set sound volume of application "iTunes" to (snd - 5)
						delay 0.1
					end repeat
					set reactivate to true
				end if
			end tell
		end if
	end tell
	
	tell application "Mail"
		--get set of messages as objects
		set selectedMessages to |SelectedMessages| of info
		--count them
		set numMessages to the count of selectedMessages
		--if there are more than five messages, then don't say each one, just say the number of new mail messages
		if numMessages is less than or equal to 5 then
			repeat with eachMessage in selectedMessages
				
				-- seperate name from email address
				set theFromAddress to sender of eachMessage
				set theBreak to " <"
				set nameEnd to the offset of theBreak in theFromAddress
				if nameEnd is not 0 then
					set fromPerson to (characters 1 through (nameEnd - 1) of theFromAddress) as string
				end if
				
				-- determine if this is a reply or forward
				set theSubject to subject of eachMessage
				if theSubject contains "re:" or theSubject contains "Re:" then
					set introText to "Reply from "
				else if theSubject contains "Fwd:" or theSubject contains "Fw:" or theSubject contains "fwd:" or theSubject contains "fw:" then
					set introText to "Forwarded mail from "
				else
					set introText to "New mail from "
				end if
				
				--combine parts and say it
				say introText & fromPerson & ".  Subject is " & theSubject & "." --using "Voice Name"
			end repeat
		else
			say numMessages & " new mail messages."
		end if
	end tell
	
	if reactivate is true then
		tell application "iTunes"
			repeat
				set snd to sound volume of application "iTunes"
				if snd is greater than or equal to orig_vol then
					exit repeat
				end if
				set sound volume of application "iTunes" to (snd + 5)
				delay 0.1
			end repeat
		end tell
	end if
end perform_mail_action

---
Jayson --When Microsoft asks you, "Where do you want to go today?" tell them "Apple."

[ Reply to This | # ]