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
Staff meeting Thursday at 10am
busycalevent://new/Staff%20meeting%20Thursday%20at%2010am
Meeting with Joe June 7 at 3pm /Work
busycalevent://new/Meeting%20with%20Joe%20June%207%20at%203pm%20%2FWork
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
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.,
<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
-Pay Taxes April 15!!! /Personal
busycalevent://new/-Pay%20Taxes%20April%2015!!!%20%2FPersonal
-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
Find Task: Pay Taxes on April 15 2017 on Personal calendar
busycalevent://find/Personal/Pay%20Taxes/2017-04-15T12%3A00%3A00+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
_Find Event: Meeting with Joe on June 7 2016
busycalevent://find//Meeting%20with%20Joe/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
To go to the current date:
busycalevent://date/now
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.,
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
To turn DND off, specify 0 as the number of minutes:
busycaldnd://0
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