Fire keyboard maestro based on calendar event

I hope anyone can help.

I would like to have my desktop setup for the specific customer I serve on a particular day. This can be any day of the week.

I made a keyboard maestro task to set up my computer for a specific client. Thanks to the David Sparks field guide :wink:

I would like to have a script to determine whether I have an agenda event with ’ABC’ in de name of any event in calendar ’XYZ’. I guess apple script can do that.

I did some research on internet but could not find something similar and I’m not familiar with Apple script. Anyone knows were to get a script that:

Reads all my calendar ’XYZ’ appointments for today to see if any of these contains ’ABC’. The output needs a true / false variable or something I can feed into my keyboard maestro job.

1 Like

Some of the approaches in this thread might be of help:

If you have BusyCal there’s an interesting approach mentioned in the KM forum too:

icalBuddy would work perfectly for this. Unfortunately the easiest way to install it is with brew which will take a little bit of time if it is not already installed, but isn’t very difficult at all. I believe the original version is 32-bit, which means it will not work in Catalina; however, if you are in a hurry and just want to try it out, you could still use it in Mojave and earlier, and deal with Catalina later.

For example, I have a meeting today with a group called “Respect” and the calendar name is “Tj” so I could use this:

/usr/local/bin/icalBuddy --noCalendarNames --includeCals 'Tj' eventsToday \
| fgrep -iq 'respect'

and then use Keyboard Maestro to check to see if that script returns “success” (meaning there was a matching event) or “failure” (meaning there was no matching event).

If you need any help, feel free to post a followup. I usually check the forum every day.

ps - in Keyboard Maestro you would use this as part of a shell script, not an AppleScript. And it assumes you have icalBuddy installed at /usr/local/bin/icalBuddy which is where brew puts it.

1 Like

Thanks,

I solved it for now as follow:

The given script did not work for some reason:
/usr/local/bin/icalBuddy --noCalendarNames --includeCals ‘Tj’ eventsToday
| fgrep -iq ‘respect’

I modified it to something that worked, maybe not the most elegant way, but it works.

1 Like

Well, my example script wouldn’t have worked unless you had a calendar named ‘Tj’ and were looking for an event with the word ‘respect’ in it :slight_smile:

But if you got it to work, that was the main goal, so, great!

Yes I did replace those with my calendar name and search criteria😉 but still failed. Anyhow you put me on the right pad to a solution. Thanks.

well cool. Glad to have helped, however circuitous it was.

I can see that you seem to have found a solution to your problem, but I wanted to post an AppleScript solution, which is what you originally requested. I imagine iCalBuddy does the job fine, but I tend not to reach for third-party solutions if there are already built-in (and, in this case, very simple) ways to do the same thing.

As you also stated that this was for a client, I also feel it’s especially important to minimise the number of dependencies that a solution relies on, as anyone looking to a professional for help will not wish to have the additional hassle of downloading extra software onto their computer.

I’m presuming the calendars are stored in the native Calendar app on macOS. This AppleScript will return true or false depending on whether or not there are any events in the calendar named "Udo Consultancy" (you can change this) that coincide with today’s date and contain the word "dekra" (you can change this too) in its name:

property calendarName : "Udo Consultancy" -- name of the specific calendar 
property searchTerm : "dekra" -- or whatever
--------------------------------------------------------------------------------
tell (the current date) to tell (it - time) to set today to [it, it + 1 * days]

tell application "Calendar" to set eventsToday to a reference to ¬
	(every event in the calendar named calendarName ¬
		whose ((start date ≥ the beginning of today ¬
		and start date < the end of today) ¬
		or (end date ≥ the beginning of today ¬
		and end date < the end of today)) ¬
		and summary contains the searchTerm)

the number of eventsToday is greater than 0

This can be incorporated into a KM macro like so:

where SearchFound will contain either true or false, which can be tested as a condition in the if...then...else action that proceeds it.

If you prefer to set your calendarName and searchTerm variables from within KM, you can do so by assigning your chosen values to variables in actions preceding the script:

then changing the first two lines of the script from this:

property calendarName : "Udo Consultancy" 
property searchTerm : "dekra" 

to this:

property calendarName : system attribute "KMVAR_calendar"
property searchTerm : system attribute "KMVAR_query"

where "KMVAR_calendar" and "KMVAR_query" should be changed to reflect the names of the variables you choose within Keyboard Maestro.

3 Likes

Just to clarify, the OP indicated he was setting up his computer for a client, so the client is isn’t actually downloading additional software, just the OP.

But your approach does have the benefit of addressing the 32-bit/Catalina upgrade caveat. :slightly_smiling_face:

Thank you so much for your help! This would make it future proof (64 bit).

I run into some error messages and calandar app hanging.

I did enter this script into KM:

My calendar event to be found by the script:
Screenshot%20agenda%20taak

It results in various errors… Am I doing something wrong?

Screenshot%20macro%20error%20609 Screenshot%20non%20responsive%20calendar Screenshot%20macro%20error%201712

It’s timing out, possibly because you have quite a few events for it to search through, and the default waiting time is only about 2 minutes.

One solution might be to surround the tell application "Calendar" chunk with:

try
	with timeout of 600 seconds
		tell application "Calendar" to ...
                   .
                   .
                   .
	end timeout
end try

the number of eventsToday is greater than 0

That should give it a ten minute window to return a result. However, in case you aren’t keen to wait for ten minutes to obtain a result, then this script will be a lot faster if it gets the right authorisation privileges:

property calendarName : "Udo Consultancy"
property searchTerm : "dekra"

use framework "EventKit"
use framework "Foundation"
use scripting additions

property this : a reference to the current application
property nil : a reference to missing value
property _1 : a reference to reference

property EKEntityTypeEvent : a reference to 0
property EKEventStore : a reference to EKEventStore of this
property NSPredicate : a reference to NSPredicate of this

property EKAuthorizationStatus : ["Restricted", "Denied", "Authorized"]
--------------------------------------------------------------------------------
tell (the current date) to tell it - time
	set today to [it, it + 1 * days]
end tell

tell EKEventStore
	tell item authorizationStatusForEntityType_(EKEntityTypeEvent) of ¬
		EKAuthorizationStatus to if it ≠ "Authorized" then error it
	
	tell alloc()'s init()
		tell calendarsForEntityType_(EKEntityTypeEvent)
			filterUsingPredicate_(NSPredicate's ¬
				predicateWithFormat:("title ==[c] %@") ¬
					argumentArray:[calendarName])
			if |count|() = 0 then error "Calendar not found"
			set cal to the firstObject()
		end tell
		
		its predicateForEventsWithStartDate:(beginning of today) ¬
			endDate:(end of today) calendars:[cal]
		tell eventsMatchingPredicate_(result)
			filterUsingPredicate_(NSPredicate's ¬
				predicateWithFormat:("title CONTAINS[c] %@") ¬
					argumentArray:[searchTerm])
			|count|() > 0
		end tell
	end tell
end tell

If there are any issues from either of these attempts, compare what happens when you execute the script within Script Editor and feedback.