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

10.4: Use iCal to set a response reminder for a Mail message Apps
One of the things I miss in Mail is the ability to set a reminder to respond to a mail message at a given time. So I re-wrote another script I'd found to do just this using iCal.

Open Script Editor, and then copy and paste the script into the editor. Save it as a script, anywhere you like (though I saved it in Mail's Script menu, for fast access).

To use it select a SINGLE mail, run the script and follow the dialogues. This script was done on the fly; I am sure it can be improved and trimmed.

[robg adds: This worked as expected. Note that the date format defaults to day-month-year. If you work with the US-style month-day-year format, you'll just need to change one line in the script. Here's how it looks after modifying it:
display dialog "Enter Date of the event for " & theFrom & ": i.e " & 
 theMonth & "/" & theday & "/" & theyear default answer 
 theMonth & "/" & theday & "/" & theyear
With this change, you'll both see and enter US-style dates.]
    •    
  • Currently 1.67 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (3 votes cast)
 
[12,523 views]  

10.4: Use iCal to set a response reminder for a Mail message | 24 comments | Create New Account
Click here to return to the '10.4: Use iCal to set a response reminder for a Mail message' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Use iCal to set a response reminder for a Mail message
Authored by: mark hunte on Jun 30, '05 11:54:39AM
I have since updated the script to cope with more than one email at a time here it is below.

Thanks Rob for also pointing out the date format

(* A script to use with Mail to set a response event in iCal, select a message and then run the
script and follow the dialogs  - written by Mark Hunte 2005 *)

global theEvent
tell application "Mail"
	set theMessages to selection
	repeat with eachMessage in theMessages
		set theFrom to (sender of eachMessage)
		set Extract_Addr to extract address from theFrom
		set the_delim1 to do shell script "echo " & quoted form of theFrom & " " & " |awk -F\\< '{print $1}'"
		set theFrom to the_delim1
		set theSubject to ("Subject: " & (subject of eachMessage))
		set theSubject1 to (subject of eachMessage)
		try
			
			set theText to Extract_Addr & return & return & theSubject
			
		end try
		set iCalendars to {}
		
		set theCals to {}
		my _Ical(theFrom, theSubject, theSubject1, theText, iCalendars, theCals)
	end repeat
	
end tell


on _Ical(theFrom, theSubject, theSubject1, theText, iCalendars, theCals)
	tell application "iCal"
		set theCals to calendars whose writable is true
		repeat with i from 1 to count of theCals
			copy title of item i of theCals to end of iCalendars
			
		end repeat
	end tell
	
	tell application "Finder"
		
		
		set timestamp to current date
		set theday to (day of (current date)) as string
		
		
		set monthList to {January, February, March, April, May, June, July, August, September, October, November, December}
		repeat with i from 1 to 12
			if timestamp's month = item i of monthList then
				set theMonth to text -2 thru -1 of ("0" & i)
				exit repeat -- no point continuing once we have what we want
			end if
		end repeat
		
		set theyear to (year of (current date)) as string
		
		display dialog "Enter Date of the event for " & theFrom & ": i.e " & theday & "/" & theMonth & "/" & theyear default answer theday & "/" & theMonth & "/" & theyear
		
		set theSdate to the text returned of the result
		
		display dialog "Enter time of the event : (24 hour time)" default answer "12:00"
		
		set theTime to the text returned of the result
		
		display dialog "Enter ending time of event (24 hour time)" default answer "13:00"
		
		set theEtime to the text returned of the result
		
		display dialog "Number of Hours before event to sound alarm(blank for no alarm): " default answer "1"
		
		set theAlarmTime to the text returned of the result
		
		display dialog "Type of Response" buttons {"Email", "Call", "Meeting"} default button 3
		set the button_pressed to the button returned of the result
		
		if the button_pressed is "Email" then
			set button_pressed to "to ~ " & button_pressed & "  "
		else if the button_pressed is "Call" then
			set button_pressed to "to ~ " & button_pressed & "  "
		else
			set button_pressed to "for ~ " & button_pressed & " with  "
		end if
		display dialog "Any Action taken so far: " default answer " "
		
		set theActionTaken to the text returned of the result
		
		
		set theChoice to choose from list iCalendars with prompt "Choose the Calendar to use" OK button name "Choose" without multiple selections allowed and empty selection allowed
		
		if theChoice is not false then
			set theCalChoice to item 1 of theChoice
		end if
		
		set theCalName to theCalChoice
		
		
		
		set i to 1
		
		repeat with anitem in iCalendars
			if item i of iCalendars is equal to theCalName then
				set theNum to i
				exit repeat
			end if
			set i to i + 1
		end repeat
	end tell
	
	set currentCal to item theNum of theCals
	
	set theDate to date theSdate
	
	set theDate to date theTime of theDate
	
	set endDate to date theSdate
	
	set endDate to date theEtime of endDate
	
	
	tell application "iCal"
		
		set theEvent to (make event at end of events of currentCal with properties {start date:theDate, end date:endDate, summary:"Mail reminder " & button_pressed & return & theFrom & ". " & return & "About, " & theSubject1, description:"Reminder set on " & timestamp & return & "Any Action taken so far: " & return & theActionTaken & return & theText})
		if theAlarmTime is not "" then
			set theAlarm to (theAlarmTime as integer) * -60
			make new sound alarm at end of sound alarms of theEvent with properties {trigger interval:theAlarm}
		end if
		
	end tell
	
end _Ical

-- comment out below if you do not want ical to show you the last event.
tell application "iCal"
	activate
	show theEvent
end tell

---
mh

[ Reply to This | # ]

Use iCal to set a response reminder for a Mail message
Authored by: Sport73 on Jun 30, '05 12:53:38PM

Just wanted to say:

THANK YOU! THANK YOU! THANK YOU!

I've been looking for a way to do this for some time; this script is clean, simple and functional.



---
Productivity, Beauty, Capably Simplicity, Elegantly Powerful = MAC



[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: roballen on Jun 30, '05 03:55:26PM

Thank you for this.

Something I have missed from outlook.

I've modified the script to automatically default to a purpose calendar, one less key click.

Would there be any way to have a dialogue box appear that asked all the questions at once?

Excellent script.



[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: chjabu on Jun 30, '05 10:33:06PM

the script runs fine from the script menu, but not from a rule set up in Mail Act-On. Any one else having the same problem or have any suggestions? Thx.



[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: magnamous on Jul 01, '05 04:26:22AM
Ok. After far too much time spent playing with this thing, I've come up with a modified version of the original script that has some changes I wanted.

  1. The ability to choose to have an all-day event.
  2. The ability to choose a number of minutes for the alarm (instead of hours).
  3. Error handling in case you accidentally don't put in anything for the date of the reminder.
  4. Other little piddly things that I can't remember because it's late and I'm tired.

What this script does not have is a way for iCal to bring up the specific message mentioned in the event when the reminder alarm goes off (if there is one). Further details are in the comments of the script. If anyone can figure out how to do it, that's amazing. I don't know enough to figure it out.

Here's the script:


(* 

Modified version of:

A script to use with Mail to set a response event in iCal, select a message and then run the
script and follow the dialogs  - written by Mark Hunte 2005

*)

-- the event (or events) we're going to be creating in iCal
global theNewEvent

-- get the parameters of each message for which we're making an iCal event
tell application "Mail"
	set theSelectedMessages to selection
	-- variables we'll need to get the list of editable calendars from iCal
	set userCalendars to {}
	set calendarTitles to {}
	
	-- get the list of editable calendars from iCal
	tell application "iCal"
		set userCalendars to calendars whose writable is true
		repeat with i from 1 to count of userCalendars
			copy title of item i of userCalendars to end of calendarTitles
		end repeat
	end tell
	
	repeat with eachMessage in theSelectedMessages
		set messageFrom to (extract name from sender of eachMessage)
		set messageAddress to (extract address from sender of eachMessage)
		set messageSubject to (subject of eachMessage)
		set messageUniqueID to (message id of eachMessage)
		
		try
			set eventDescription to messageAddress & return & messageSubject
		end try
		-- custom function for creating our event(s) - run it on each message
		my createTheEvent(messageFrom, messageSubject, messageUniqueID, eventDescription, userCalendars, calendarTitles)
		
	end repeat
	
	-- comment out this part if you don't want iCal to show you the event that was created
	tell application "iCal"
		activate
		show theNewEvent
	end tell
	
end tell

-- definition for our custom function to create events
on createTheEvent(messageFrom, messageSubject, messageUniqueID, eventDescription, userCalendars, calendarTitles)
	
	tell application "Finder"
		
		-- these are used to set a stamp for when the iCal event was created, among other things
		set timestamp to current date
		set currentDay to (day of (current date)) as string
		set currentYear to (year of (current date)) as string
		
		-- convert the month from a name to a number
		set monthList to {January, February, March, April, May, June, July, August, September, October, November, December}
		repeat with i from 1 to 12
			if timestamp's month = item i of monthList then
				set currentMonth to i as string
				exit repeat -- once we have the correct number, there's no need to continue the loop
			end if
		end repeat
		
		-- get the date on which the user wants to set the reminder
		set eventDate to ""
		repeat while eventDate = ""
			display dialog "Enter a date for the reminder about the email:" & return 
				& "(M/D/YY or M/D/YYYY format)" & return & 
				return & "Sender: " & messageFrom & return & "Subject: " & messageSubject 
				default answer currentMonth & "/" & currentDay & "/" & currentYear
			set eventDate to the text returned of the result
		end repeat
		
		-- get the time at which the user wants to set the reminder (or make it an all-day event)
		display dialog "Enter a start time for the reminder" & return & "using 24-hour format:" & return & return & "(Leave blank for an all-day event)" default answer "12:00"
		if the text returned of the result is not equal to "" then
			set eventStartTime to the text returned of the result
			set eventEndTime to ""
			repeat while eventEndTime = ""
				display dialog "Enter an end time for the reminder" & return & "using 24-hour format:" default answer "13:00"
				set eventEndTime to the text returned of the result
			end repeat
		else
			set eventStartTime to false
			set eventEndTime to false
		end if
		
		-- do you want to remind yourself to email, call, or meet with the person?
		display dialog "How do you wish to respond to the email?" buttons {"Meeting", "Call", "Email"} default button 3
		set eventRemindTo to the button returned of the result
		
		(*
		
		This section is currently disabled because I can't figure out how to get iCal to open the email when the alarm goes off. See the end of this script for details.
		
		-- this will call another script that will open the email using its message ID
		display dialog "Would you like iCal to open the email when the alarm goes off?" buttons {"No", "Yes"} default button 2
		set openEmailOnAlarm to the button returned of the result

		*)
		
		-- get the amount of time before the event to set the alarm (if any).
		set eventAlarmTime to ""
		-- not allowing the user to avoid entering anything. I think this is better than interpreting no input as no alarm.
		repeat while eventAlarmTime is ""
			display dialog "Would you like to set an alarm for the reminder?" & return & return & "Amount of time before the reminder:" & return & "(enter 0 (zero) for the same time as the reminder)" default answer "1" buttons {"No Alarm", "Minutes", "Hours"} default button 3
			if the button returned of the result is "Hours" and the text returned of the result is not "" then
				set eventAlarmTime to (the text returned of the result as integer) * -60
			else if button returned of the result is "Minutes" and the text returned of the result is not "" then
				set eventAlarmTime to (the text returned of the result as integer) * -1
			else if button returned of the result is "No Alarm" and the text returned of the result is not "" then
				set eventAlarmTime to false
			end if
		end repeat
		
		display dialog "Actions you've taken so far:" default answer ""
		set eventActionTaken to the text returned of the result
		
		choose from list calendarTitles with prompt 
			"Choose the calendar to use" OK button name "Choose" without multiple selections allowed and empty selection allowed
		set calendarNameChoice to item 1 of the result
		
		-- get the number of which calendar is to be used
		set eachCalendar to 1
		repeat with eachCalendar from 1 to count of calendarTitles
			if item eachCalendar of calendarTitles is equal to calendarNameChoice then
				set calendarNumberChoice to eachCalendar
				exit repeat
			else
				set eachCalendar to (eachCalendar + 1)
			end if
		end repeat
		
	end tell
	
	-- select the appropriate calendar from the calendar name chosen by the user
	set calendarChoice to item calendarNumberChoice of userCalendars
	
	-- reformat the start and end dates to standard date/time stamp
	set eventStart to date eventDate
	set eventEnd to date eventDate
	
	tell application "iCal"
		if eventStartTime is not false then
			-- change the times listed in the start and end times to those specified by the user
			set eventStart to date eventStartTime of eventStart
			set eventEnd to date eventEndTime of eventEnd
			
			-- this will (essentially) only include Actions taken if the user entered something there
			if eventActionTaken is not equal to "" then
				set eventActionTaken to return & return & "Actions taken so far:" & return & eventActionTaken
			end if
			
			-- actually create the event
			set theNewEvent to (make event at end of events of calendarChoice with properties 
				{start date:eventStart, end date:eventEnd, summary:"Reminder: " & eventRemindTo & " " & messageFrom & " about " & messageSubject, description:"Reminder set on " & timestamp & return & return & eventDescription & eventActionTaken} 
					)
		else
			(* If both times are set to midnight (which is the default if the user doesn't specify a start time), iCal sets the end date to the day before the start date, and the item becomes invisible. The first two lines below this comment are a workaround for that. *)
			set eventStart to date "01:00" of eventStart
			set eventEnd to date "02:00" of eventEnd
			
			-- this will (essentially) only include Actions taken if the user entered something there
			if eventActionTaken is not "" then
				set eventActionTaken to return & return & "Actions taken so far:" & return & eventActionTaken
			end if
			
			-- actually create the event
			set theNewEvent to (make event at end of events of calendarChoice with properties 
				{start date:eventStart, allday event:true, summary:"Reminder: " & eventRemindTo & " " & messageFrom & " about " & messageSubject, description:"Reminder set on " & timestamp & return & return & eventDescription & eventActionTaken})
		end if
		
		-- set an alarm for the event, if that was chosen
		if eventAlarmTime is not false then
			make new sound alarm at end of sound alarms of theNewEvent with properties {trigger interval:eventAlarmTime, sound name:"Windows XP Reminder"}
		end if
		
		(*
		
		from http://homepage.mac.com/aamann/Mail_Scripts.html as of 6/30/2005:
		The "mailbox" property of the "message" object is currently broken in Tiger - this means that mailbox pre-selection in the "Archive Messages", "Create Rule", and "Remove Duplicates" scripts does not currently work. The scripts work fine otherwise and the feature will start working as soon as Apple fixes this bug (Apple bug ID 4106253).
		
		I would like, in the future, to use the mailbox property of the message to add the file path of the message to the URL field of the iCal event, because it would be neat to be able to use the iCal event to tell Mail exactly which message it's referring to (in case you forget). I guess it has to wait until Apple fixes this problem.
		
		I tried to figure a way around this by attaching a script to the iCal event that would run at the same time as the alarm. The script would use the URL field of the event to tell Mail to display the message with that unique ID. Unfortunately, I can't get it to work. I can't figure out how to:
		
		1. Get iCal to create an alarm that runs the script in "~/Library/Scripts/iCal scripts" (say, openEmail.scpt). The only available option is an "open file" alarm. Why isn't the "Run Script" alarm option in iCal scriptable? I'm assuming that the appropriate place for scripts that should appear in the "Run Script" alarm is "~/Library/Scripts/iCal scripts".
		2. Write that openEmail.scpt so that it gets the URL field of the iCal event that referenced it in the first place, so that the script can pass the unique message ID to Mail so Mail can open that particular message. If anyone can figure out how to do this, please do!
		
		here's the code I was working on, for what it's worth...
		-- we need the unique id of the message
		if openEmailOnAlarm is "Yes" and eventAlarmTime is not false then
			set url of theNewEvent to messageUniqueID
			set scriptPath to quoted form of POSIX path of "/Users/" & name & "/Library/Scripts/iCal scripts/openEmail.scpt"
			make new script at end of scripts of theNewEvent with properties {trigger interval:eventAlarmTime, filepath:scriptPath}
		end if
		
		*)
		
		
	end tell
	
end createTheEvent


[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: mark hunte on Jul 01, '05 06:02:08AM

I did try and include a way of getting the urL of the mail message to be put in the event, but could not get the message id to set to a variable name. I will keep trying, if anyone does have any ideas of how get into a variable then that would be great.

Thanks for the comments and the updates...

---
mh



[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: zmagyar on Jul 04, '05 06:41:11AM

I managed to do this. To get the message ID is not a big deal but to open a message with this ID is not that easy. To be able to do this you have to define the mailbox of the message (beside the ID). The trouble is that the mailbox property is broken in Tiger, and this is filed as bug by Apple. So far no fix. Till then your approach seems to be a nice workaround. If you are interested in the script let me know, I will gladly share it with you. Zsolt



[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: mark hunte on Jul 04, '05 12:59:50PM
That would be nice thanks, I did figure the getting of the id. ie.

set selectionMessage to selection
	set thisMessage to item 1 of selectionMessage
	set theId to id of thisMessage
	set theUrl to "file:///Users/user/Library/Mail/path/to/file" & theId & ".emix" as string

but have only got back today so have not gone further in working out how to get the path

---
mh

[ Reply to This | # ]

Use iCal to set a response reminder for a Mail message
Authored by: zmagyar on Jul 05, '05 04:24:49AM
Hi Mark, First to the ID, here is a short example how to get the ID

tell application "Mail"
	activate
	set messageSelection to selected messages of message viewer 1
	if (count of messageSelection) is equal to 0 then
		display dialog "Please select a message in Mail first, then run this script again."
	else if (count of messageSelection) is equal to 1 then
		--geting the reference to the selected message
		--set selectedMessage to item 1 of messageSelection
		get properties of item 1 of messageSelection
	end if
end tell
Open the event log history in the script editor and you will see all the properties of one message. The trouble is that if you tell to Mail to open message with that ID it will fail. As far as I remember you had to specify the ID and the mailbox to make it happen, even though, this would sometimes also fail, if you moved the message after you got the ID and mbox to be able to open it later on. Nevertheless most of the time it worked. In Tiger, as I said, the mailbox value is missing, which you willl clearly see in the output of the example I gave you above. But your post remided me to something I overlooked. Now each message is a singe file, so knowing the path to it is solving the problem! Therefore I took another glimpse to the output I got from example above, and indeed there is a new property there, it is not a message id, but simply the id (very clear, isnt' it ;-)). However we still miss the path, but what a heck, we might simply try to search all the ~/Library/Mail folders after this ID. Maybe I find some good use for this spothlight after all ; Let me check my script and maybe I can fix it right away, then I will post the completed one. BTW if you have already some search code snippet then post it.. Tx Zsolt

[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: mark hunte on Jul 06, '05 01:24:33PM
Ok got this so far, but if the mail is moved it will not be found again as it gets a different number.. One way around this could be to move the mail into a special reminder mailbox first with the script.
tell application "Mail"
	set selectionMessage to selection
	set thisMessage to item 1 of selectionMessage
	set theId to id of thisMessage as string
	set the_search to do shell script "mdfind \"kMDItemKind == 'emlx' \"| grep -iw " & theId & ".emlx" & " | grep -v grep "
	set theUrl to "file://" & the_search as string
end tell

---
mh

[ Reply to This | # ]

Use iCal to set a response reminder for a Mail message
Authored by: mark hunte on Jul 06, '05 07:39:18PM
This seems to work, I created a mailbox called 'reminders' for the messages to be either
moved or duplicated to. The script shows how to get the url for the email , which can then be place in the url of the iCal event.
I will post an updated version of the full script later with this included. ( i need to go to bed)
tell application "Mail"
	set theCount to ""
	set selectionMessage to selection
	set thisMessage to item 1 of selectionMessage
	
	set the_mailbox to mailbox "reminders"
	set new_place to duplicate thisMessage to the_mailbox -- you can change duplicate to move
	set theCount to count messages in the_mailbox --this is just to get the path to the new mailbox
	set themessage to message theCount of the_mailbox -- this is just to get the path to the new mailbox
	set theId to id of themessage as string
	using terms from application "Finder"
		set the_Url to do shell script "mdfind \"kMDItemKind == 'emlx' \"| grep -iw " & theId & ".emlx" & " | grep -v grep " as string
		set the_delim1 to do shell script "echo " & quoted form of the_Url & " " & " |awk -FMessages '{print $1}'"
		set copy_folder to the_delim1 & "Messages/"
		set the_Url to "file://" & copy_folder & (do shell script "cd " & quoted form of copy_folder & " ; ls -t1| perl -pe 'exit if $. > 1'")	
	end using terms from
	
end tell

---
mh

[ Reply to This | # ]

Use iCal to set a response reminder for a Mail message
Authored by: zmagyar on Jul 07, '05 04:51:37AM
Hi Mark, this is starting to be interesting :-)) But is widening the discussion too, so let me know if you start to get bored, either/or prefer that we disccuss this directly in private mails and post only the results to forum... The URL thing is very cool, I overlooked this too, and it does solve the problem I hit yesterday, but cuts the functionality, but let me go one by one. Your approach with URL solves my latest problem and this is how to open this damn emlx file. Finder does not want to open it (or I'm doing something wrong), mail and message viewer do open it but show only an empty vidow with a b..it note that the message was not downloaded from the server... just try to add
 open the_search 
at the last line of your example code and you will see what do I mean. I went then into automator which opens it too but then we are getting tangled in AS - Automator calls and this does not go smoot either, so we better skip it. Why is this so complicated when a simple double click from finder works, I have no idea.... But with URL approach you miss one functionality I implemented and this is updates. When I have an update to the event, like they guy replied that he will answer in 3 days, then I write an update into the ical event, postpone it for 3 days, and in the update I write a new id with which I can open the refering email message. With the URL approach I could add the URL to the even text, but first the URL is long, second it will not work with a click. I could replace the original URL but the I would lose the reference to the first email... Also, there is one big difference between yours and mine, you search for the path at the moment of creation of the event, and I want to log only the ID and search for it at the moment of opening the emlx file, which overcomes the reminder mailbox problem. So now we can go two ways, one is yours, URL in event, no additional links to update emails, this makes the script much simpler, or mine but then we should figure out how to open an emlx file from applescript. As I said let me know when you had enough. For me it is kind of a challenge and therefore fun, but maybe you or others simply want a working solution no matter how good it is. BTW I have no idea why the mdfind takes so long, and maybe you can shorten it by using the -onlyin option. Let me know, Zsolt

[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: roballen on Jul 07, '05 06:09:40AM

Hi

I have been following this thread with interest, but with no apple scripting skill. One additional idea/request. An option to create the reminder as a to-do instead of a calendar event?

Thanks, Rob



[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: zmagyar on Jul 07, '05 11:15:59AM

It is not a problem to code it (I guess) but to make an appropriate dialog for selection, as the AS does not support radio buttons or checkmarks. This means you would need then two separate dialogs and that is not very ellegant, but again doable. Let us sort out the current problems and we might come back to this later on. Thanks for input.
Zsolt



[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: zmagyar on Jul 08, '05 12:03:16PM
OK, I managed to put it together today, so you might have some fun over the weekend.
Notes:
The search for the file is rather slow, I have no idea why is mdfind so slow on my machine considering it should search in index, but probably this can be fixed somehow, at the moment it takes on my machine about 5-10 seconds to find the file, and you will have absolutely no visual feedback that something is going on, unless you monitor your CPU or disk activity. A nice progress bar, or instant search would be nice. As I'm still wandering how to open an email file from AS, to give you a working code, the place where the files should open is just displaying a dialog with a file path. But as soon as you figure out how to open the file, just replace 3 lines of code and you are done.
Here is the script, at the end I will paste the usage....

--NOTE: the events will be created in the callender named "MailFollowup".
--it is hardcoded, if you don't like it, change it in the code ;-)
--for insturctions see Script Description

display dialog "Please Choose:" buttons {"Create Event", "Get ID", "Open Mail with ID"} default button 2 with icon 1
if button returned of result = "Create Event" then
	my Create_Event()
else if button returned of result = "Get ID" then
	my Get_ID()
else if button returned of result = "Open Mail with ID" then
	my Open_Mail_with_ID2()
else
	display dialog "Something went wrong"
end if

on Create_Event()
	set messInfo to (my Get_Mess_Info2())
	set messInfo to messInfo as list
	set messSubject to item 1 of messInfo
	set mailMessID to item 2 of messInfo
	
	tell application "iCal"
		activate
		set theCal to 0
		set callist to {}
		--repeat with i in (calendars whose writable is true)
		repeat with i in calendars
			set caltitle to title of i
			set callist to callist & caltitle --(title of i)
		end repeat
	end tell
	
	--set thecal to item 1 of (choose from list callist)
	set theCal to "MailFollowup"
	repeat with i from 1 to (count callist)
		if theCal = item i of callist then
			exit repeat
		end if
	end repeat
	set theCal to i
	
	tell application "iCal"
		calendar theCal exists
	end tell
	
	tell application "iCal"
		--	make new event at the end of events of calendar thecal with properties {start date:startdate, end date:enddate, summary:thetitle, description:descript}
		set newEvent to (make new event at the end of events of calendar theCal with properties {start date:(current date), end date:(current date), summary:messSubject, description:"Message ID: " & mailMessID})
		show newEvent
		--current date
	end tell
end Create_Event

on Get_ID()
	set messInfo to (my Get_Mess_Info2())
	set messSubject to item 1 of messInfo
	set mailMessID to item 2 of messInfo
	set the clipboard to "MMID " & mailMessID
	
	tell application "iCal"
		activate
	end tell
end Get_ID

on Open_Mail_with_ID2()
	tell application "Mail"
		activate
		set slectedMessmyMessIDs to (askPassword "Enter Message ID")
		--this is the part where we search for the email message file
		--the search is slow and CPU intensive, it has to run better
		set the_search to do shell script "mdfind \"kMDItemKind == 'emlx' \"| grep -iw " & slectedMessmyMessIDs & ".emlx" & " | grep -v grep "
		--here we should figure out how to open the found message file
		--as at the moment I don't know how, I simply display the path and file name
		--this shows if the code is working fine and you might even want to manually
		--navigate to this path and open it by doubleclicking
		--of course this is more then akward
		set the_search to the_search as string
		display dialog the_search
	end tell
end Open_Mail_with_ID2

------------------------------------------------------------------------------------------------

on Get_Mess_Info2()
	tell application "Mail"
		activate
		--set messageSelection to selected messages of message viewer 1
		--the line above is OK if you have only one message viewer open, but if you have
		--two or more then we have to find the front one...
		set mywin to window of the message viewers
		set mymsgviewers to message viewers
		set winindex to index of item 1 of mywin
		if winindex is equal to 1 then
			set frontmsgview to item 1 of mymsgviewers
		else
			set frontmsgview to item 2 of mymsgviewers
		end if
		set messageSelection to selected messages of frontmsgview
		if (count of messageSelection) is equal to 0 then
			display dialog "Please select a message in Mail first, then run this script again."
		else if (count of messageSelection) is equal to 1 then
			--geting the reference to the selected message
			set selectedMessage to item 1 of messageSelection
			set messSubject to subject of selectedMessage
			if messSubject is equal to "" then
				display dialog "Mail subject equals empty string! continuting..."
			end if
			set mailMessID to id of selectedMessage
			if mailMessID is equal to 0 then
				display dialog "Mail ID equals 0, something went wrong, exiting..."
				exit repeat
			end if
			return {messSubject, mailMessID}
		else
			display dialog "Please select only one message in Mail first, then run this script again."
		end if
	end tell
	return
end Get_Mess_Info2
Usual disclamer apply!!!
Usage:
Save the file in the "~/Library/Scripts/Mail Scripts", you can then invoke it thru the script menu.
I named it MailCalV7___ctl-e.app, in Jaguar this would let you invoke it with ctrl-e in the Mail, in Tiger I'm not sure if this works.
There are 3 ways to use it:
- create event: this will find the unique ID of the selected mail message and create a new event in iCal taking the mail subject as the title of the event, and the current date and time as the date and time of the event, it will also add string "MMID" and the ID of the message in the Notes of the event, where the MMID stands for Mail Message ID. Then it will take you to the event so that you can modify the date time and add some more comments
- get id: the idea is to get the ID of the selected message which is a followup to an already created event, copy it into the clipboard and take you to the iCal. Then you can find the event you want to update, select the notes and hit ctrl-v to paste the new MMID, then you can add comments as followup notes to the event
- open message with ID: this is when you want to actually see the content of the mail message you are referring to in the even notes. You check in the event which MMID you want to see, then start this script, select the option to open a message with ID, enter the ID manually, (sorry for bullets, I dont' know of any other way to enter text) and once you hit OK the mail message should appear. At this moment this will just show a dialog with a message path.
Have fun, Zsolt

[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: blueeye on Jul 11, '05 05:16:26PM

To avoid the delay caused by shell script mdfind, I found the following script much faster in producing a URL of the selected mail message, identified as variable theURL, to hand off to iCal.

property LibraryPath : (path to library folder from user domain) as string
property MailBoxPath : LibraryPath & "Mail:Mailboxes:"

tell application "Mail"
tell message viewer 1
set MailBoxName to ""
set b to item 1 of (get selected mailboxes)
set i to 1
try
repeat while class of b is mailbox
set {n, b} to {name, container} of b
if i is 1 then
set MailBoxName to n
else
set MailBoxName to n & ":" & MailBoxName
end if
set i to i + 1
end repeat
end try
end tell
set theMessages to selection --assuming that a message has been selected
repeat with eachMessage in theMessages
set msgID to id of eachMessage
end repeat
set URLPath to (MailBoxPath & MailBoxName & ".mbox:Messages:" & msgID & ".emlx")
tell application "System Events" to set theURL to URL of alias (URLPath)
end tell



[ Reply to This | # ]
Use iCal to set a response reminder for a Mail message
Authored by: mark hunte on Jul 11, '05 07:50:33PM
I do not seem to have any delay on my Mac using the mdfind, but i will try you script out,, cheers

also here is a way to jump to the event of the selected email. that zmagyar was
after using the id of the email, again I have been tied up so hav not had time to rewrite all of this into
on whole script.

but using these bits the script will now make the event reminder with a working
Url. and also be able to jump from a email to its event if it exists.

I will write it up soon, as I am sure others will, to their preferred version.

tell application "Mail"
	set theMessages to selection
	repeat with eachMessage in theMessages
		set theId to id of eachMessage as string
	end repeat
end tell

tell application "iCal"
	
	repeat with aCalendar in calendars
		tell aCalendar
			set the_none to "0"
			if exists (some event whose description contains theId) then
				
				set theEvent to (some event whose description contains theId)
				activate
				show theEvent
			else
				set the_none to "no match found"
			end if
			
		end tell
	end repeat
end tell
if the_none is equal to "no match found" then
	display dialog the_none
end if 

---
mh

[ Reply to This | # ]

10.4: Use iCal to set a response reminder for a Mail message
Authored by: zmagyar on Jul 16, '05 05:30:08PM
OK, here is the corrected version, for Finder to open the file I had to replace the / with :, sure, why make the life easy....
Whatever, here it is. For the todo functionality, please, just drag the event to the todo list and you are done, but if you really really want to have it, let me know...

--NOTE: the events will be created in the callender named "MailFollowup".
--it is hardcoded, if you don't like it, change it in the code ;-)
--for insturctions see Script Description

display dialog "Please Choose:" buttons {"Create Event", "Get ID", "Open Mail with ID"} default button 2 with icon 1
if button returned of result = "Create Event" then
	my Create_Event()
else if button returned of result = "Get ID" then
	my Get_ID()
else if button returned of result = "Open Mail with ID" then
	my Open_Mail_with_ID2()
else
	display dialog "Something went wrong"
end if

on Create_Event()
	set messInfo to (my Get_Mess_Info2())
	set messInfo to messInfo as list
	set messSubject to item 1 of messInfo
	set mailMessID to item 2 of messInfo
	
	tell application "iCal"
		activate
		set theCal to 0
		set callist to {}
		--repeat with i in (calendars whose writable is true)
		repeat with i in calendars
			set caltitle to title of i
			set callist to callist & caltitle --(title of i)
		end repeat
	end tell
	
	--set thecal to item 1 of (choose from list callist)
	set theCal to "MailFollowup"
	repeat with i from 1 to (count callist)
		if theCal = item i of callist then
			exit repeat
		end if
	end repeat
	set theCal to i
	
	tell application "iCal"
		calendar theCal exists
	end tell
	
	tell application "iCal"
		--	make new event at the end of events of calendar thecal with properties {start date:startdate, end date:enddate, summary:thetitle, description:descript}
		set newEvent to (make new event at the end of events of calendar theCal with properties {start date:(current date), end date:(current date), summary:messSubject, description:"Message ID: " & mailMessID})
		show newEvent
		--current date
	end tell
end Create_Event

on Get_ID()
	set messInfo to (my Get_Mess_Info2())
	set messSubject to item 1 of messInfo
	set mailMessID to item 2 of messInfo
	set the clipboard to "MMID " & mailMessID
	
	tell application "iCal"
		activate
	end tell
end Get_ID

on Open_Mail_with_ID2()
	tell application "Mail"
		activate
		set slectedMessmyMessIDs to (askPassword "Enter Message ID")
		--this is the part where we search for the email message file
		--the search is slow and CPU intensive, it has to run better
		--set the_search to do shell script "mdfind \"kMDItemKind == 'emlx' \"| grep -iw " & slectedMessmyMessIDs & ".emlx" & " | grep -v grep "
		
		set slectedMessmyMessIDs to slectedMessmyMessIDs & ".emlx" as string
		--log slectedMessmyMessIDs
		--log "mdfind \"kMDItemFSName = " & slectedMessmyMessIDs & "\" | grep /" & slectedMessmyMessIDs
		set the_search to do shell script "mdfind \"kMDItemFSName = " & slectedMessmyMessIDs & "\" | grep /" & slectedMessmyMessIDs
		
		--here we should figure out how to open the found message file
		--as at the moment I don't know how, I simply display the path and file name
		--this shows if the code is working fine and you might even want to manually
		--navigate to this path and open it by doubleclicking
		--of course this is more then akward
		set the_search to the_search as string
		--display dialog the_search
		set converted_path to my findAndReplace("/", ":", the_search)
		tell application "Finder"
			set bootvol to displayed name of startup disk
			set fullpath to bootvol & converted_path
			open file fullpath
		end tell
	end tell
end Open_Mail_with_ID2

------------------------------------------------------------------------------------------------

on Get_Mess_Info2()
	tell application "Mail"
		activate
		--set messageSelection to selected messages of message viewer 1
		--the line above is OK if you have only one message viewer open, but if you have
		--two or more then we have to find the front one...
		set mywin to window of the message viewers
		set mymsgviewers to message viewers
		set winindex to index of item 1 of mywin
		if winindex is equal to 1 then
			set frontmsgview to item 1 of mymsgviewers
		else
			set frontmsgview to item 2 of mymsgviewers
		end if
		set messageSelection to selected messages of frontmsgview
		if (count of messageSelection) is equal to 0 then
			display dialog "Please select a message in Mail first, then run this script again."
		else if (count of messageSelection) is equal to 1 then
			--geting the reference to the selected message
			set selectedMessage to item 1 of messageSelection
			set messSubject to subject of selectedMessage
			if messSubject is equal to "" then
				display dialog "Mail subject equals empty string! continuting..."
			end if
			set mailMessID to id of selectedMessage
			if mailMessID is equal to 0 then
				display dialog "Mail ID equals 0, something went wrong, exiting..."
				exit repeat
			end if
			return {messSubject, mailMessID}
		else
			display dialog "Please select only one message in Mail first, then run this script again."
		end if
	end tell
	return
end Get_Mess_Info2

on findAndReplace(tofind, toreplace, TheString)
	set ditd to text item delimiters
	set res to missing value
	set text item delimiters to tofind
	repeat with tis in text items of TheString
		if res is missing value then
			set res to tis
		else
			set res to res & toreplace & tis
		end if
	end repeat
	set text item delimiters to ditd
	return res
end findAndReplace

Let me know how does it work.
Zsolt

[ Reply to This | # ]
10.4: Use iCal to set a response reminder for a Mail message
Authored by: BOlle on Jul 16, '05 06:13:09PM

I feel like a freaking noob, but i can't seem to save the code in Scriptmaker.

It complains: Expected ", " but found ".
The . is part of the error message. I've translated the error, i'm on a Dutch OS X (10.3.9). Any suggestions?



[ Reply to This | # ]
10.4: Use iCal to set a response reminder for a Mail message
Authored by: BOlle on Jul 17, '05 05:44:21AM

Forgot to mention that Scriptmaker jumps to this line:

set slectedMessmyMessIDs to (askPassword "Enter Message ID")

and selects the first "



[ Reply to This | # ]
10.4: Use iCal to set a response reminder for a Mail message
Authored by: zmagyar on Jul 20, '05 03:40:18AM

To make the life easyer, post your email address and I will send you the script
Zsolt



[ Reply to This | # ]
10.4: Use iCal to set a response reminder for a Mail message
Authored by: BOlle on Jul 20, '05 04:44:46AM

Tnx: osxhints at xs4all dot nl



[ Reply to This | # ]
10.4: Use iCal to set a response reminder for a Mail message
Authored by: veric on Aug 19, '05 05:53:37PM
ok, it's very far at the end of this long hint... but i've got another script which might interest some of you. i've only done a very small modification on the Mail2IcalTodo from KleinWare:
http://macupdate.com/info.php/id/10494

i've only add a little (but so usefull) reminder alarm: (and it works perfectly with the amazing and beautiful Mail'shortcutaker "Act-on" ()

with KleinWare Mail2ical (event), it's perfect...



(*

this is a little modification (set alarm with Todo item) of :

	Mail2iCalToDo, rev. 1.3.1, © 2002-2005 by Georg Klein <gklein1@mac.com>
	This script is distributed as open source software
	You are free to copy, modify and share parts of or the entire script, as long as you
	a) Keep this notice in any modified version of the script
	b) Transfer this notice to any derrivative work
	c) Don't charge money for this script or any derrivative of it
	
	This software is provided "as is" without any warranty, explicit or implied.
	The author of this software is not liable to any loss or damage of data that
	may happen by installing or using it.
*)
property pCalName : ""
property pDueDate : 72

using terms from application "Mail"
	on perform mail action with messages allMessages
		try
			set mailCal to my checkForDefault("rule")
			my generateItems(allMessages, mailCal)
		on error theError number theNumber from theOffender
			beep
			--			display alert "Error " & theNumber & " occurred" message theError as critical buttons {"OK"} default button 1 giving up after 15
		end try
	end perform mail action with messages
end using terms from

on run
	set mailCal to my checkForDefault("menu")
	tell application "Mail"
		if (count of selected messages of message viewer 1) is 0 then
			display alert "No messages selected" message "Please select some messages to export or click 'Reset' to set new defaults" buttons {"Reset", "OK"} default button 2 giving up after 15
			copy result as list to {theButton}
			if theButton is "Reset" then
				set mailCal to my chooseCalendar()
				my setDueDate()
			end if
		else
			set allMessages to selected messages of message viewer 1
			my generateItems(allMessages, mailCal)
		end if
	end tell
end run

on checkForDefault(method)
	tell application "iCal"
		try
			set mailCal to calendar pCalName
		on error errMsg number errno
			if errno is 1 then -- no calendar with this name
				if method is "rule" then -- rule execution does not allow for user interaction
					set mailCal to my createCalendar("Email") -- create calendar with default name
				else
					set mailCal to my chooseCalendar()
					my setDueDate()
				end if
			else
				error errMsg number errno
				return ""
			end if
		end try
	end tell
	return mailCal
end checkForDefault

on chooseCalendar()
	tell application "iCal"
		set allCals to title of calendars
	end tell
	set theCal to choose from list allCals with prompt "Export to which calendar" default items {pCalName} cancel button name "New" with empty selection allowed without multiple selections allowed
	if theCal is false or (count of theCal) is 0 then
		display dialog "Name your calendar" default answer "Email" buttons {"Cancel", "OK"} default button 2
		copy the result as list to {theName, theButton}
		if theButton is not "Cancel" then
			set pCalName to theName
		else
			return
		end if
		set mailCal to my createCalendar(pCalName)
	else
		set pCalName to item 1 of theCal
		tell application "iCal"
			set mailCal to calendar pCalName
		end tell
	end if
	return mailCal
end chooseCalendar

on createCalendar(calName)
	tell application "iCal"
		set mailCal to make new calendar at the end of calendars
		tell mailCal
			set title to calName
		end tell
	end tell
	return mailCal
end createCalendar

on setDueDate()
	display dialog "Set due date (in hours from arrival of mail)" default answer pDueDate buttons "Set" default button 1
	copy result as list to {theText, theButton}
	set pDueDate to theText as integer
end setDueDate

on generateItems(allMessages, mailCal)
	tell application "Mail"
		repeat with i from 1 to number of items in allMessages
			set curMessage to item i of allMessages
			set curText to reply to of curMessage & ", " & subject of curMessage
			set theHeaders to all headers of curMessage
			set hasPrio to offset of "X-Priority:" in theHeaders
			if hasPrio is not 0 then
				set xPrio to (character (hasPrio + 12) of theHeaders) as integer
				if xPrio is 1 then set calPrio to 1
				if xPrio is 2 then set calPrio to 4
				if xPrio is 3 then set calPrio to 0
				if xPrio is 4 then set calPrio to 7
				if xPrio is 5 then set calPrio to 9
			else
				set calPrio to 0
			end if
			tell application "iCal"
				set newTodo to make new todo at the end of todos of mailCal
				tell newTodo
					set summary to curText
					set due date to ((current date) + pDueDate * hours)
					set priority to calPrio
					if pDueDate is not "" then
						set theAlarm to (pDueDate as integer) * -60
						make new sound alarm at end of sound alarms of newTodo with properties {trigger interval:theAlarm}
					end if
				end tell
			end tell
		end repeat
	end tell
end generateItems



[ Reply to This | # ]
10.4: Use iCal to set a response reminder for a Mail message
Authored by: jamieph on Sep 13, '05 01:11:37PM

You could also use MailTags to do the same thing from within Mail. It is very handy.

http://www.indev.ca/MailTags.html



[ Reply to This | # ]