Applescript to Create Tasks Based on Calendar Events

I’ve long wanted a feature to repeat tasks based on calendar events, or defer until next “X” calendar event, etc., and have cobbled together this script in the meantime.

This script creates a task based on all events in a given calendar for the current calendar month. I use it with my “Work” calendar, and it creates work tasks like “List some items on eBay,” etc.

You’ll need to adjust it based on your calendar setup, and to check more event info if the calendar you point it at has events other than the ones you’re targeting.

It requires the CalendarLib EC library.
https://www.macosxautomation.com/applescript/apps/Script_Libs.html#CalendarLib_EC
-------------------------------------------------------------------------------------------
use script “CalendarLib EC” – https://www.macosxautomation.com/applescript/apps/Script_Libs.html#CalendarLib_EC
use scripting additions

set d1 to current date
set day of d1 to 1
set d2 to current date
set day of d2 to daysInMonth(d1)
set createdCount to 0

set theStore to fetch store
set theCal to fetch calendar "YOUR CALENDAR NAME" cal type cal cloud event store theStore -- change calendar here
set theEvents to fetch events starting date d1 ending date d2 searching cals theCal event store theStore

repeat with anEvent in theEvents
	set eventInfo to event info for event anEvent
	set eventStart to eventInfo's event_start_date
	set eventEnd to eventInfo's event_end_date
	
	tell application "OmniFocus"
		tell front document
			set theTask to "YOUR TASK NAME" -- change task name here
			set theProject to (first flattened project where its name = "YOUR PROJECT NAME") -- change project here
			set theContext to (first flattened context where its name = "YOUR CONTEXT NAME") -- change context here
			
			if not (exists (first flattened task where its name = theTask and its context = theContext and its defer date = eventStart and its due date = eventEnd)) then
				tell theProject to make new task with properties {name:theTask, context:theContext, defer date:eventStart, due date:eventEnd}
				set createdCount to createdCount + 1
				
			end if
			
		end tell
	end tell
end repeat

if createdCount = 1 then
	set tasks to "task"
else if createdCount ≠ 1 then
	set tasks to "tasks"
end if

display dialog "Created " & createdCount & " new \"" & theTask & "\" " & tasks & "." buttons {"OK"} default button "OK"

-------------------------------------------------------------------------------------------
# HANDLERS
-------------------------------------------------------------------------------------------
on daysInMonth(aDate)
	--http://stackoverflow.com/questions/39055945
	local aDateCopy
	copy aDate to aDateCopy
	set day of aDateCopy to 1
	if month of aDateCopy is December then
		set year of aDateCopy to ((year of aDateCopy) + 1)
		set month of aDateCopy to 1
	else
		set month of aDateCopy to ((month of aDateCopy) + 1)
	end if
	return day of (aDateCopy - 1 * days)
end daysInMonth
-------------------------------------------------------------------------------------------
1 Like

Just a quick update. Several months down now and still loving this script; however, I’ve modified it now to set the range of dates as:

set d1 to (current date) - 30 * days
set d2 to (current date) + 30 * days
set createdCount to 0

This way I don’t have to wait until any particular month begins to run the script.