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.
