For those with a busy lifestyle and need to keep track of appointments here is a tutorial that will work together with iCal, your cell phone and XTension to send a text message to you phone whenever you have an appointment. You will need: - iCal - XTension with an internet connection - Know your cell phone text email address (usually your phone number and your cell phone domain ex: 1234567890@somewhere.com) This will look at every calendar event only in calendars you specify. The trigger time is the alarm time and not the actual time. If you don't put in an alarm time it will not send an alert. The script will be up to 4 minutes and 59 seconds before or after the event. It has a window plus or minus 5 minutes of the actual time of the event. Don't expect it to see the event exactly on the time of the event. The data it sends to your cell phone is only the information in the event and will not send anything else. It is a very large script but is easy to get working if you follow the instructions. Every item in **bold** will have to be changed with your information. property |unitlist| : {"**put your cell phone text email address here. Leave in the quotes.**"} property plstCalendars : {"**calendar name", "another calendar name", "put as many as you want**"} property plstEventsFired : {} property pdatYesterday : "" my subRetrieveAlarms() on subRetrieveAlarms() if pdatYesterday = "" then set pdatYesterday to (current date) end if --Get the current date and time set datToday to current date if (pdatYesterday - (time of pdatYesterday)) ≠ (datToday - (time of datToday)) then --the day has changed so empty the list of fired events and set the date set plstEventsFired to {} set pdatYesterday to datToday end if set datStartOfToday to datToday - the (time of datToday) tell application "iCal" repeat with itmCalendarTitle in plstCalendars --Reset these lists for each calendar set lstAlarmEvents to {} set lstTriggerIntervals to {} set lstEventsToFire to {} set lstEventTimes to {} tell (every calendar whose title is itmCalendarTitle) --Get every event on the current day set lstTodaysEvents to (every event whose start date > datStartOfToday and start date < (datStartOfToday + (24 * 60 * 60))) set lstEventIDs to (uid of every event whose start date > datStartOfToday and start date < (datStartOfToday + (24 * 60 * 60))) --Find all the events with alarms repeat with itmEvent in lstTodaysEvents --These trys get the trigger interval of any alarm set for the current event --Inside each try we are adding the event and its trigger interval to a list for use later try set intInterval to trigger interval of first display alarm of itmEvent set end of lstAlarmEvents to itmEvent set end of lstTriggerIntervals to intInterval on error try set intInterval to trigger interval of first open file alarm of itmEvent set end of lstAlarmEvents to itmEvent set end of lstTriggerIntervals to intInterval on error try set intInterval to trigger interval of first mail alarm of itmEvent set end of lstAlarmEvents to itmEvent set end of lstTriggerIntervals to intInterval on error try set intInterval to trigger interval of first sound alarm of itmEvent set end of lstAlarmEvents to itmEvent set end of lstTriggerIntervals to intInterval end try end try end try end try end repeat -- Every event of the current day --Find all the alarmed events that have alarm times within the next x minutes (default is 5) repeat with intCounter from 1 to count of lstAlarmEvents set datEventStart to start date of item intCounter of lstAlarmEvents --timEventTime is the time of the event in seconds set timEventTime to time of datEventStart set intInterval to item intCounter of lstTriggerIntervals --This line gets a date that is the event date and time + the trigger interval set datAlarmTime to datEventStart + (intInterval * minutes) --Time of the alarm in seconds set timAlarmTime to time of datAlarmTime --The alarm is supposed to go off in the next x minutes so add that event and its start time to a list for use later --Subtract the alarm time (future) from the last time run (past) (timTimeLastRun - timAlarmTime) to get a positive --number that should be less than the delay amount, if it is, and we haven't gone negative (the alarm time is now in --the past) then add the event to the list set timNow to time of (current date) if intInterval < 0 then set intAbsoluteInterval to intInterval * -1 else set intAbsoluteInterval to intInterval end if if timNow ≥ timAlarmTime then --the current time is greater than or equal to the alarm time --if the current time is within the alarm interval (timNow - timAlarmTime) then trigger the alarm if ((timNow - timAlarmTime) / minutes) ≤ intAbsoluteInterval then if plstEventsFired does not contain uid of item intCounter of lstAlarmEvents then set end of lstEventsToFire to item intCounter of lstAlarmEvents set end of lstEventTimes to datEventStart set end of plstEventsFired to uid of item intCounter of lstAlarmEvents end if end if end if end repeat --Every event with an alarm --Get the title and time of each event that is needs to be triggered repeat with intCounter from 1 to count of lstEventsToFire try set strSummary to summary of item intCounter of lstEventsToFire on error set strSummary to "-NO TITLE" end try try exists strSummary on error set strSummary to "-NO TITLE-" end try try set strLocation to location of item intCounter of lstEventsToFire on error set strLocation to "-NONE-" end try try exists strLocation on error set strLocation to "-NONE-" end try set strEventTime to time string of item intCounter of lstEventTimes --Right here we have the Title and Time of an event with an alarm that is going to go off in the next 5 minutes --strSummary is the title of the event, or "-NO TITLE-" if it didn't have one --strEventTime is the time of the event as a string --For ease of editing this script we pass these values to another handler that can be modified as needed without messing --up all this iCal stuff my subDoStuff(strSummary, strEventTime) end repeat --Every event with an alarm in the next x minutes (default is 5) end tell end repeat --Calendars end tell --After cycling through all of the calendars set the last run date/time set pdatDateLastRun to current date end subRetrieveAlarms on subDoStuff(strSummary, strEventTime) --Put whatever you want to happen with the provided event summary (title) and time string in this handler --For example, this displays the summary and start time in a dialog alert user "The event: '" & strSummary & "' occurs at" & return & strEventTime --This is a texting routine repeat with unitName in |unitlist| -- this allowed the event to go to any recipient I put in the list set theName to "" set theSender to "**put the name of the email address you are sending from here**" set theBody to strSummary --if you want the time string included in the message you could do it like so: --include it in the subject: set theSubject to "You have an appointment at " & strEventTime --include it in the body: set theBody to "You have an appointment at " & strEventTime & " " & strSummary & return & return set theAddress1 to unitName tell application "XTension" write log "You have an appointment at " & strEventTime & " " & strSummary color green speak "You have an appointment at " & strEventTime & " " & strSummary execute script "Get up macro" -- this can be removed. I use it to turn on lights and the stereo it will not run if you don't have a scrip by that name end tell tell application "Mail" -- this sends the event to the cell phone set newMessage to make new outgoing message with properties {subject:theSubject, content:theBody & return & return} tell newMessage set visible to true set sender to theSender make new to recipient at end of to recipients with properties {name:theName, address:theAddress1} tell content end tell send newMessage end tell end tell end repeat end subDoStuff Once this is in set up then put in a Scheduled Event to activate this script every 5 minutes. That's it. You're done.