User Tools

Site Tools


tutorials:ical

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)

  1. -Put whatever you want to happen with the provided event summary (title) and time string in this handler
  1. -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.

tutorials/ical.txt · Last modified: 2023/02/13 14:52 by 127.0.0.1