Updated July 8th, 2019.
No matter how careful you are about putting stuff into your calendar you still have to look at it to see where you’re supposed to be. I had the same problem, but not anymore, because I figured out how to have my Mac read my appointments to me out loud, every day, on a timer. It’s very cool, and since it’s scheduled to run every morning at 7:30 AM, I think it’s going to help me out quite a bit. Especially on weekends, when I tend to forget to check the calendar.
I was hoping to do this with an Automator Workflow, and if not for an iCal bug Automator would have been the way to go. I worked pretty hard at making it work with Automator but eventually realized that the reason it didn’t work was something I couldn’t work around. So I turned to AppleScript.
Here’s the script. The gray parts are comments, put there to help you understand what’s going on. Note: the script gets you part of the way there. You still need something to trigger the script at the appropriate time. Lots of programs can do that for you. I chose Script Timer, a nice little $12 program that I just found out about. Here’s the link. You can get a free 30-day trial.
set the_text to “”
set today to current date
set time of today to 0
set tomorrow to (today) + 86400 — seconds
—
— Here are the calendars I want to check. Yours will be different. Change the following line to match the names of your calendars.
— If you are going to check ALL of your calendars this script could be simplified. Send me an email and I’ll help you.
— Christian Boyce, macman@christianboyce.com
set the_calendar_list to {“CB & A”, “usc football 2009”, “Cal Football 2009”, “Texas Football 2009”, “UCLA Football 2009”, “Birthdays”}
—
tell application “iCal”
— First we need to tell iCal which calendars are going to be checked. We match the names in “the_calendar_list” to the names of the actual calendars in iCal. The ones that match are added to our “the_calendars” list.
—
set the_calendars to {}
set every_calendar to every calendar
— Now we have a list of calendars to check.
repeat with an_item in the_calendar_list
set end of the_calendars to (first calendar whose name is an_item)
end repeat
— Now we check, on a calendar by calendar basis, for appointments on the current day.
repeat with a_calendar in the_calendars
tell a_calendar
set the_events to (every event whose start date > today and start date < tomorrow)
—
— Here we sort the list of events for the day. If we don’t do this they won’t be chronological. iCal sorts them in creation order unless we run this little “sortEvents” routine.
—
set the_events to my sortEvents(the_events)
— Now we have a sorted list. Let’s create a string for the Mac to speak. Loop through the events and make that string.
set i to 1
repeat with an_event in the_events
set x to properties of an_event
set the_summary to summary of an_event
set the_start_date to start date of an_event
set the_end_date to end date of an_event
set the_start_time to time string of the_start_date
set the_end_time to time string of the_end_date
—
set the_text to the_text & return & “Appointment number” & i & “.” & return & the_start_time & ” to ” & the_end_time & “.” & return & summary of an_event & return & return
set i to i + 1
end repeat
end tell
end repeat
—
— If there aren’t any events the string “the_text” will be empty. In that case we want to say something different.
if the_text is “” then
set the_text to “Good morning.” & return & “Today is ” & date string of (current date) & return & return & “Unfortunately, you have no appointments today.”
else
set the_text to “Good morning.” & return & “Today is ” & date string of (current date)