Skip to main content

URL Handler

BusyCal supports URL handlers for creating new events and finding events in BusyCal. Through the use of BusyCal’s URL handlers you can interact with BusyCal from AppleScript or other apps that can open URLs.

Creating Events in BusyCal

You can create a new event in BusyCal using natural language by opening a percent-escaped URL in the following format:

	busycalevent://new/<event description>/<notes>

The URL takes 2 parameters. The first is the event description, the second is an optional parameter for notes.

<event description>: The event description must contain an event title, date (today is assumed if no date), and a start time (an all-day event is assumed if no start time). In addition, you can include an optional calendar name preceded by a slash (e.g., /Work), and an optional final parameter containing a URL surrounded by angle brackets (e.g., <www.apple.com>). NOTE: All text must be URL encoded.

<notes>: New in v3.5.8+. The text you would like to show in the notes section.

Here are some example natural language phrases for creating events and the corresponding percent escaped URLs:

Baseball game tomorrow

[busycalevent://new/Baseball%20game%20tomorrow](busycalevent://new/Baseball game tomorrow)

Staff meeting Thursday at 10am

[busycalevent://new/Staff%20meeting%20Thursday%20at%2010am](busycalevent://new/Staff meeting Thursday at 10am)

Meeting with Joe June 7 at 3pm /Work

[busycalevent://new/Meeting%20with%20Joe%20June%207%20at%203pm%20%2FWork](busycalevent://new/Meeting with Joe June 7 at 3pm /Work)

Note: /Work must be encoded as %2FWork, preceded by a space (%20)

Meeting with Joe June 7 at 3pm /Work Some Notes

[busycalevent://new/Meeting%20with%20Joe%20June%207%20at%203pm%20%2FWork/Some%20Notes](busycalevent://new/Meeting with Joe June 7 at 3pm /Work/Some Notes)

Note: You must add a space (%20) after the title for the list name to be interpreted /Work (%2FWork)

Apple Earnings Conference Call Tuesday at 2pm <investor.apple.com>
busycalevent://new/Apple%20Earnings%20Conference%20Call%20Tuesday%20at%202pm%20%3Cinvestor.apple.com%3E

See Quick Entry for more information on the natural language syntax for creating events in BusyCal.

Creating Tasks in BusyCal

You can create a new task in BusyCal using natural language by opening a percent-escaped URL in the following format:

busycalevent://new/-<task description>/<notes>

The URL takes 2 parameters. The first is the task description, the second is an optional parameter for notes.

-<task description>: To create a task, precede the task description with a hyphen (-). You can provide a due date (an undated task is created if no date is provided), an optional priority via exclamation points (! = low, !! = medium, !!! = high), an optional calendar name preceded by a slash (e.g., /Work), and an optional final parameter containing a URL surrounded by angle brackets (e.g., <www.apple.com>).

<notes>: New in v3.5.8+. The text you would like to show in the notes section.

Here are some example natural language phrases for creating tasks and the corresponding percent-escaped URLs:

-Call Bob tomorrow

[busycalevent://new/-Call%20Bob%20tomorrow](busycalevent://new/-Call Bob tomorrow)

-Pay Taxes April 15!!! /Personal

[busycalevent://new/-Pay%20Taxes%20April%2015!!!%20%2FPersonal](busycalevent://new/-Pay Taxes April 15!!! /Personal)

-Buy Toner /Shopping <www.amazon.com_>

busycalevent://new/-Buy%20Toner%20%2FShopping%20%3Cwww.amazon.com%3E

See Quick Entry for more information on the natural language syntax for creating tasks in BusyCal.

Selecting an Event in BusyCal

You can show an event in BusyCal by opening the busycalevent://find/ URL, in the following format:

busycalevent://find/<Calendar>/<Title>/<DateTime>

OR

busycalevent://find/<Calendar>/<Title>/<Date>

The URL takes 2 or 3 parameters. The first is the calendar name, the second is the event title, and the third is the occurrence date of the event in “yyyy-MM-dd’T’HH:mm:ssZ” or “yyyy-MM-dd” format.

The calendar name can be blank if you want to search all calendars. If you have multiple calendars by the same name, only the first one will be used.

The occurrence date can be a date-time value. For date-only events such as all-day events or tasks, use 12:00:00+0000 or use the second date-only variant. If no date is given, the event is assumed to be an undated task.

Here are some examples:

Find Undated Task: Buy Toner

[busycalevent://find//Buy%20Toner](busycalevent://find//Buy Toner)

Find Task: Pay Taxes on April 15 2017 on Personal calendar

[busycalevent://find/Personal/Pay%20Taxes/2017-04-15T12%3A00%3A00+0000](busycalevent://find/Personal/Pay Taxes/2017-04-15T12:00:00+0000)

Find Event: Meeting with Joe on June 7 2016 at 3:00 PM Pacific Time

[busycalevent://find//Meeting%20with%20Joe/2016-06-07T15%3A00%3A00-0700](busycalevent://find//Meeting with Joe/2016-06-07T15:00:00-0700)

Find Event: Meeting with Joe on June 7 2016

[busycalevent://find//Meeting%20with%20Joe/2016-06-07](busycalevent://find//Meeting with Joe/2016-06-07)

Selecting a Date in BusyCal

You can highlight a date in BusyCal by opening the busycalevent://date/ URL, appended with the date in yyyy-MM-dd format:

busycalevent://date/2021-05-31

Click here to Try

To go to the current date:

busycalevent://date/now

Click here to Try

AppleScript Examples

Although BusyCal does not support AppleScript, you can use AppleScript to generate URLs that can be passed to BusyCal to create new events or tasks. Here are some AppleScript examples.

Display a Prompt to Create a New Event

This example shows how to capture input and send it to BusyCal.

	set myPrompt to display dialog "Create New Event in BusyCal" default answer "Movie at 7pm on Friday /Personal"
set response to the text returned of myPrompt
set quick_entry to encode(response)—see encode handler below
tell application "BusyCal"
activate
open location "busycalevent://new/" & quick_entry
end tell

Download the BusyCal New Event script

Create New Event from Text on Clipboard

This example shows how to use text from the clipboard as input and send it to BusyCal.

	set myText to (the clipboard as text)
set myPrompt to display dialog "Create New Event in BusyCal" default answer myText
set response to the text returned of myPrompt
set quick_entry to encode(response)—see encode handler below
open location "busycalevent://new/" & quick_entry
tell application "BusyCal"
activate
open location "busycalevent://new/" & quick_entry
end tell

Download the BusyCal New Event from Clipboard script

Create New event Linked to Current Safari Web Page

This example shows how to create an event that includes a link to the current Safari web page:

	tell application "Safari"
set theURL to URL of front document
set theName to name of front document
end tell
set myPrompt to display dialog "Create New Event in BusyCal" default answer theName
set response to the text returned of myPrompt
set encoded_response to encode(response & " <" & theURL & ">")—see encode handler below
tell application "BusyCal"
activate
open location "busycalevent://new/" & encoded_response
end tell

Download the BusyCal New Event from Safari script

If you’re using Chrome, change the tell application “Safari” section in the script above to this:

	tell application "Google Chrome"
set theURL to URL of active tab of front window
set theName to title of active tab of front window
end tell

Download the BusyCal New Event from Chrome script

Create New Event Linked to Selected Mail Message

This example shows how to create an event that includes a link to the message selected in Mail.

	tell application "Mail"
set theSelectedMessages to selection
set the selected_message to item 1 of the theSelectedMessages
set message_id to the message id of the selected_message
set message_subject to the subject of the selected_message
end tell
set myPrompt to display dialog "Create New Event in BusyCal" default answer message_subject
set response to the text returned of myPrompt
set quick_entry to encode(response & " <message:%3C" & message_id & "%3E>") --see encode handler below
tell application "BusyCal"
activate
open location "busycalevent://new/" & quick_entry
end tell

Download the BusyCal New Event from Mail script

Create New Event Linked to Selected Note in Evernote

This example shows how to create an event that includes a link to the note selected in Evernote.

	tell application "Evernote"
set theSelectedNotes to selection
set the selected_note to item 1 of the theSelectedNotes
set note_link to the note link of the selected_note
set note_title to the title of the selected_note
end tell
set myPrompt to display dialog "Create New Event in BusyCal" default answer note_title
set response to the text returned of myPrompt
set quick_entry to encode(response & " <" & note_link & ">")—see encode handler below
tell application "BusyCal"
activate
open location "busycalevent://new/" & quick_entry
end tell

Download the BusyCal New Event from Evernote script

Create New Event Linked to Selected Contact

This example shows how to create an event that includes a link to the person selected in Contacts.

	tell application "Contacts"
set theSelectedContacts to selection
set the selected_contact to item 1 of the theSelectedContacts
set contact_id to the id of the selected_contact
set contact_name to the name of the selected_contact
end tell
set myPrompt to display dialog "Create New Event in BusyCal" default answer contact_name
set response to the text returned of myPrompt
set quick_entry to encode(response & " <addressbook://" & contact_id & ">")—see encode handler below
tell application "BusyCal"
activate
open location "busycalevent://new/" & quick_entry
end tell

Download the BusyCal New Event from Contacts script

Encode Handler

This handler is used in each of the above scripts for encoding strings.

	on encode(msg)
set theText to do shell script "/usr/bin/python3 -c 'import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))' " & quoted form of msg
set AppleScript's text item delimiters to "/"
set theTextItems to text items of theText
set AppleScript's text item delimiters to "%2F"
set theText to theTextItems as string
set AppleScript's text item delimiters to {""}
return theText
end encode

Xcode Sample Code

If you are an app developer, you may find the following sample code useful for interacting with BusyCal.

Finding the Default Calendar Application

Below is sample code to find the default calendar application and show an event in BusyCal.

You can check the default calendar application like so:

	+ (NSString *)defaultICSHandlerBundleID
{
CFStringRef strRef = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, CFSTR("ics"), kUTTypeData);
CFStringRef bundleID = LSCopyDefaultRoleHandlerForContentType(strRef, kLSRolesEditor);
CFRelease(strRef);
return [NSMakeCollectable(bundleID) autorelease];
}

If the bundle ID returned is “com.apple.ical” then Calendar is the default calendar application. If it is “com.busymac.busycal3” then BusyCal 3 is the default calendar application.

URI Encoding a String

Below is a category on NSString for URI encoding a string:

	@interface NSString (URIEncoding)



- (NSString *)stringByURIEncoding;



@end



@implementation NSString (URIEncoding)



- (NSString *)stringByURIEncoding
{
// same as -stringByAddingPercentEscapesUsingEncoding but escapes ‘/’ and ‘?’
const CFStringRef leaveUnescaped = NULL;
const CFStringRef forceEscaped = CFSTR("!*'();:@&=+$,/?%#[]");
CFStringRef escapedStr = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef) self, leaveUnescaped, forceEscaped, kCFStringEncodingUTF8);
return [NSMakeCollectable(escapedStr) autorelease];
}



@end

Selecting an Event in BusyCal

All strings must be URI encoded with the -stringByURIEncoding method given above.

	- (void)busycalShowEvent:(NSString *)eventTitle inCalendar:(NSString *)calendarName onDate:(NSDate *)occurrenceDate
{
NSString *occurrenceDateStr = @"";
if (occurrenceDate != nil) {
NSDateFormatter *formatter = [[NSDateFormatter new] autorelease];
[formatter setDateFormat:@"yyyy-MM-dd’T’HH:mm:ssZ"];
occurrenceDateStr = [formatter stringFromDate:occurrenceDate];
}



NSString *url = [NSString stringWithFormat:@"busycalevent://find/%@/%@/%@",
[calendarName stringByURIEncoding], [eventTitle stringByURIEncoding], [occurrenceDateStr stringByURIEncoding]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
}

Here are some example URLs that you can paste into Safari for testing.

Event: “Appliance Sale” on calendar “Store” at 2017-01-18 12:00 PM PST

	busycalevent://find/Store/Appliance%20Sale/2017-01-18T12%3A00%3A00-0800

Task: “My Task” on calendar “Test” at 2017-01-29

	busycalevent://find/Test/My%20To%20Do/2017-01-29T12%3A00%3A00-0000

Undated Task: “Wash Car” on calendar “Chores”

	busycalevent://find/Chores/Wash%20Car

Highlighting a Date in BusyCal

To highlight a date in BusyCal:

	- (void)busycalShowDate:(NSDate *)date
{
NSString *dateStr = @"";
if (date != nil) {
NSDateFormatter *formatter = [[NSDateFormatter new] autorelease];
[formatter setDateFormat:@"yyyy-MM-dd"];
dateStr = [formatter stringFromDate:date];
}



NSString *url = [NSString stringWithFormat:@"busycalevent://date/%@", [dateStr stringByURIEncoding]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
}

Here is an example URL:

	busycalevent://date/2017-05-31

Forcing a Sync with All CalDAV Servers

You can force BusyCal to perform a sync with all CalDAV Servers (iCloud, Google Calendar, etc.) to ensure that it is in sync with the events in Calendar (or your app). To force a sync, pass the following URL to BusyCal:

	busycalsync://caldav

Creating a New Event in BusyCal

You can create a new event with a natural language string using the busycalevent://new/ URL. It takes one parameter, which is a URI-encoded string. Like regular natural language strings entered into the Quick Event window in BusyCal, the URI-encoded string can contain an optional /calendar prefix or suffix, an optional “-” prefix to indicate a task, optional exclamation points (! = low, !! = medium, !!! = high) to indicate priority, and an optional URL in angle brackets (e.g., <www.busymac.com>).

The string parameter must be URI-encoded with the -stringByURIEncoding method given above.

	- (void)busycalCreateEvent:(NSString *)string url:(NSString *)urlParam inCalendar:(NSString *)calendarName
{
if (urlParam != nil)
string = [string stringByAppendingFormat:@" <%@>", urlParam];
if (calendarName != nil)
string = [string stringByAppendingFormat:@" /%@", calendarName];
NSString *url = [NSString stringWithFormat:@"busycalevent://new/%@", [string stringByURIEncoding]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
}



- (void)busycalCreateToDo:(NSString *)string priority:(NSInteger)priority url:(NSString *) urlParam inCalendar:(NSString *)calendarName
{
string = [@"-" stringByAppendingString:string];
while (priority-- > 0)
string = [string stringByAppendingString:@"!"];
[self busycalCreateEvent:string url:urlParam inCalendar:calendarName];
}

Here are some example URLs that you can paste into Safari for testing.

Event: “Lunch with Bob Tuesday at 1pm” on calendar “Work” with URL “apple.com”

	busycalevent://new/Lunch%20with%20Bob%20Tuesday%20at%201pm%20%3Capple.com%3E%20%2FWork

Task: “Feed Fish” on calendar “Test” at 2016-06-29 with priority high

	busycalevent://new/-Feed%20Fish%202016-06-29!!!%20%2FTest

Undated Task: “Wash Car” on calendar “Chores”

	busycalevent://new/-Wash%20Car%20%2FChores

Calling a URL without Bringing BusyCal to the Foreground

To call the URL without bringing BusyCal to the foreground:

	[[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:[NSURL URLWithString:urlString]]
withAppBundleIdentifier:nil
options:NSWorkspaceLaunchWithoutActivation | NSWorkspaceLaunchAsync
additionalEventParamDescriptor:nil
launchIdentifiers:NULL];

Turning Do-Not-Disturb (DND) On and Off in BusyCal

Starting with v2022.3.2, you can turn DND on in BusyCal by opening the busycaldnd://<minutes> URL, replacing <minutes> with a number, e.g:

	busycaldnd://15

Click here to Try

To turn DND off, specify 0 as the number of minutes:

	busycaldnd://0

Click here to Try

Turning Settings On / Off

Starting with v2023.2.1, the following settings can be set via the terminal / using a script.

Change the logging level

busycalsetting://loglevel/<level> URL, replacing <level> with a number, e.g:

  Off = -2

Error = -1

Warn = 0

Info = 1

Detailed (Default) = 2

Verbose = 3

Low Level = 4

busycalsetting://level/3

Click here to Try: Logging Level Detailed

Turn automatic crash reporting on / off

busycalsetting://crashreporting/<option> URL, replacing <option> with a number, e.g:

  Off = 0

On (Default) = 1

busycalsetting://crashreporting/1

Click here to Try: Turn reporting On