Here’s an example of the kind of JavaScript for Automation code which can quickly fetch from the calendar using EventKit.
(You could use this route if you wanted to bypass Automator, for example)
// ROUGH EXAMPLE OF DIRECT JAVASCRIPT FOR AUTOMATION ACCESS
// TO CALENDAR
// THROUGH EVENTKIT
// Draft 0.001 Rob Trew - Twitter: @ComplexPoint
// Simply listing the titles of todays events (all calendars)
// Other available properties:
// (from EKCalendarItem):
// - calendar
// - title
// - location
// - creationDate
// - lastModifiedDate
// - timeZone
// - URL
// (from EKEvent):
// - eventIdentifier
// - availability
// - startDate
// - endDate
// - allDay
// - occurrenceDate
// - isDetached
// - organizer
// - status
(function () {
'use strict';
ObjC.import('EventKit');
// calEventsFromTo Args:
// 1. dateTime or undefined, defaults to start of today if undefined
// 2. dateTime or undefined, defaults to end of today if undefined
// 3. Possibly empty list of EKEvent and/or EKCalenderItem property names
// (if empty or undefined, defaults to [title, startDate])
// 4. Possibly empty list of calendar name strings
// (if empty, undefined, or unrecognised, fetches events from all calendars)
// calEventsFromTo :: maybe DateTime -> maybe DateTime -> [String] -> [String] -> Dictionary
function calEventsFromTo(
maybeStartDateTime, maybeEndDateTime,
propertyNames, calendarNames
) {
var es = $.EKEventStore.alloc
.initWithAccessToEntityTypes(
0
),
// FROM a specified datetime, or start of today
startDate = maybeStartDateTime ||
$.NSCalendar.currentCalendar
.startOfDayForDate(
$.NSDate.date
),
// Requested or default event fields
// See Apple docs for EKEvent, EKCalendarItem
lstProperties = propertyNames ? (
typeof propertyNames === 'string' ? [propertyNames] :
propertyNames
) : ['startDate', 'title'],
sortedEvents = es.eventsMatchingPredicate(
es.predicateForEventsWithStartDateEndDateCalendars(
// FROM
startDate,
// TO a specified datetime, or day after start
maybeEndDateTime ||
$.NSDate.dateWithTimeIntervalSinceDate(
(24 * 60 * 60) - 1,
startDate
),
// CALENDARS TO SEARCH
es.calendarsForEntityType(0)
.filteredArrayUsingPredicate(
$.NSPredicate.predicateWithFormat(
// ANY CALENDAR (could be one or more names)
'title IN %@', (calendarNames ? (
typeof calendarNames === 'string' ? (
[calendarNames]
) : calendarNames
) : [])
)
)
)
)
.sortedArrayUsingSelector(
'compareStartDateWithEvent:'
),
// A dictionary in which each key -> an ordered list of values
// (one for each event)
dctValues = lstProperties
.reduce(function (a, k) {
return (
a[k] = ObjC.deepUnwrap(
sortedEvents.valueForKey(k)
),
a
);
}, {
calendar: ObjC.deepUnwrap(
sortedEvents
.valueForKey('calendar')
.valueForKey('title')
)
});
// Given the list of the calendar strings (1 per event)
// derive a list of full dictionaries for each event
// with key:value pairs for each property requested
return dctValues.calendar
.map(function (strCal, i) {
return lstProperties.reduce(function (a, k) {
return (
a[k] = dctValues[k][i],
a
);
}, {
calendar: strCal
})
});
}
// Without arguments, returns
// calendar name, title, and startDate for
// all events (in all calendars) today
return calEventsFromTo();
})();