Automators 1: Automating Calendar Events

This is an amazing action for Drafts 5 that uses chrono.js to parse events using natural language and then uses the Calendars API to create those events without leaving Drafts or having to flip flip between Drafts and Fantastical. This has become one of my favorite Drafts actions.

Here is a blog post explaining the action and a link to to the action itself.


Loved the show, but do have a problem with the use of tooling like IFTTT.
Their way to make money is unknown, so you are probably the product,
(Their privacy statement even strongly hints at that)

So I don’t know it that is the way to go…

A post was split to a new topic: Adding duplicate events to multiple days

IFTTT started to monetise partnerships a while back.

Great episode! Chock-full of useful information.

For those interested, here’s an AppleScript script (based upon an example at for parsing the selected rows of the Numbers table and adding events to Fantastical:

tell application "Numbers"
		if not (exists document 1) then error number 1000
		tell document 1
				tell active sheet
					set the selectedTable to ¬
						(the first table whose class of selection range is range)
				end tell
			on error
				error number 1001
			end try
			tell selectedTable
				set theseRows to the rows of selection range
				repeat with i from 1 to the count of theseRows
					set cellValues to the formatted value of every cell of item i of theseRows
					set calendarString to last item of cellValues
					tell application "Fantastical 2"
					    parse sentence calendarString with add immediately
					end tell
				end repeat
			end tell
		end tell
	on error errorMessage number errorNumber
		if errorNumber is 1000 then
			set alertString to "MISSING RESOURCE"
			set errorMessage to "Please create or open a document before running this script."
		else if errorNumber is 1001 then
			set alertString to "SELECTION ERROR"
			set errorMessage to "Please select a table before running this script."
			set alertString to "EXECUTION ERROR"
		end if
		display alert alertString message errorMessage buttons {"Cancel"}
		error number -128
	end try
end tell

The AppleScript man himself! Thanks Sal, this is a brilliant script. :grin:

Enjoyed the first episode. I’ve never got into workflow before but I’m now inspired to give it a try and have built one that automates dialling into conference calls. Pretty happy with it! I’ll share it in the iOS section.

1 Like

I read the article, but have also read the privacy statement.
In the monitization they promise ‚Äúextensive analytics‚ÄĚ and in the statement thay indicate they can share all your data with 3rd parties, without your explicit consent. So unfortunatey for me IFTTT is a non-starter.


Yeah. I wasn’t noting anything about privacy. Just responding to the point you made about their way to make money being unknown.

I don`t use Fantastical on my Mac, so I adapted the AppleScript @Sal made to create the multiple events from the Numbers sheet directly in stock Calendar app. The underlying Numbers sheet from @RosemaryOrchard had to be adapted slightly, you can find it here (Dropbox link).
To use it, just fill in or copy your events in the Numbers sheet. The event end date is calculated, just fill in duration (in minutes). Also the event alarm needs to be entered in minutes. Once you’re done, select the rows you want to make into events and run the script.
I learned a lot while writing and debugging the script, thanks a lot, Sal, for the guidance your script gave me.

tell application "Numbers"
        if not (exists document 1) then error number 1000
        tell document 1
                tell active sheet
                    set the selectedTable to ¬
                        (the first table whose class of selection range is range)
                end tell
            on error
                error number 1001
            end try
            tell selectedTable
                set theseRows to the rows of selection range
                repeat with i from 1 to the count of theseRows
                    set cellValues to the value of every cell of item i of theseRows
                    set theEventName to first item of cellValues
                    set theStartDate to third item of cellValues
                    set theEndDate to fifth item of cellValues
                    set theAlarm to seventh item of cellValues
                    set theNotes to sixth item of cellValues
                    set theLocation to second item of cellValues
                    set theCalName to eighth item of cellValues
                    tell application "Calendar"
                        tell calendar theCalName
                            set theEvent to make new event with properties {summary:theEventName, start date:theStartDate, end date:theEndDate, location:theLocation, description:theNotes}
                            tell theEvent
                                make new display alarm at end with properties {trigger interval:-theAlarm}
                            end tell
                        end tell
                    end tell
                end repeat
            end tell
        end tell
    on error errorMessage number errorNumber
        if errorNumber is 1000 then
            set alertString to "MISSING RESOURCE"
            set errorMessage to "Please create or open a document before running this script."
        else if errorNumber is 1001 then
            set alertString to "SELECTION ERROR"
            set errorMessage to "Please select a table before running this script."
            set alertString to "EXECUTION ERROR"
        end if
        display alert alertString message errorMessage buttons {"Cancel"}
        error number -128
    end try
end tell

I was just about to plug my Drafts action when I saw that @jmreekes had already done so above! Thanks for posting that.

Since I’m here, may as well give it another plug, and explain in more detail. It basically replicates the functionality of Fantastical natural language parsing for adding events, but directly in Drafts using the javascript calendar scripting. Especially for adding a large number of calendar events on iOS, it’s much faster than Fantastical because it doesn’t have to do the URL scheme hopping back and forth. All the events go straight into the calendar almost instantly.

Syntax is identical to Fantastical, except for recurring events, which are not currently supported (this is a limitation of the Drafts scripting capabilities).

More details in my blog post.


Excellent work.

Using a segment of your script, here‚Äôs an AppleScript ‚Äúclean and wax‚ÄĚ trick for getting and setting an array of values in a single line of code:

tell selectedTable
	set theseRows to the rows of selection range
	repeat with i from 1 to the count of theseRows
		set thisRow to item i of theseRows
		copy the formatted value of every cell of thisRow to ¬
			{eventName, startDate, endDate, eventAlarm, eventNotes, eventLocation, calendarName, eventString}
		tell application "Calendar"
			tell calendar theCalName
				set newEvent to make new event with properties ¬
					{summary:eventName, start date:startDate, end date:endDate, location:eventLocation, description:eventNotes}
				tell newEvent
					make new display alarm at end with properties {trigger interval:-eventAlarm}
				end tell
			end tell
		end tell
	end repeat
end tell

@RosemaryOrchard: Thank you for mentioning the scenario of entering information based on external (already digital!) data into a calendar. At the start of each year I used to manually put the ‚Äúrelease dates‚ÄĚ of magazines that I subscribe to in a separate calendar ‚ÄúMagazines‚ÄĚ to know when I can expect them. I manually entered one and then duplicated/moved that one in Fantastical (getting the dates from a web page from the publisher). I now realise that a simple Drafts JavaScript action makes this much easier:

let calendar = Calendar.find("Magazines");
let text = draft.content.split('\n');
let title = text.shift();
for (line of text) {
    let date = line;
    let event = calendar.createEvent();
    event.title = title;
    event.startDate = date;
    event.endDate = date;
    event.isAllDay = true;
    if (!event.update()) {

Enter the magazine name on the first line of a new draft and copy/paste the ‚Äúrelease dates‚ÄĚ below. Run the action. Done! :smiley:


Thanks for the tip :grinning:! I suppose the variables in the array have to be in the corresponding order to the columns in the spreadsheet? In my original script they were not listed in order, since they were referenced directly. Also there is one column (duration) that needs to be skipped.

1 Like

Yup, to use the ‚Äúclean & wax‚ÄĚ trick, the order of the array variables must match the order of columns. Cheers!


Great first episode!

One question regarding the Workflow. Is there a way to add multiple reminders to a created event?
For doctor’s appointments that are scheduled way in advance I usually add a reminder 2 months, 1 month, 1 week and 1 day in advance.
Just to be able to reschedule if my plans change

Sadly not, Fantastical for iOS supports adding multiple reminders to one event but I haven‚Äôt yet found a way to script that. The built in Calendar app only supports the one alert as far as I know. As a workaround you could create a reminders list called ‚Äúupcoming events‚ÄĚ and have Workflow add reminders to those - but of course these won‚Äôt change if your event changes.


Thanks for the great information - because of this new podcast I was able to automate the scheduling of courses I teach each quarter. I look forward to learning more in the future.

1 Like

An excellent start to the Automators podcast! May this be the first of many!

1 Like

Fantastic first episode, Rose and David. I’m sure that this will be one of my favorite podcasts. Thanks so much for your time and effort sharing these resources with the Apple community. You two are superstars!

Since Workflow/Shortcuts will no doubt be regularly featured, I thought it would be a good time to share Backup & Restore My Workflows.

This Reddit post includes a page that describes the workflow features:

Or the workflow can be directly downloaded here.