BusyCal support

Here’s my scripts to add BusyCal support. It needs a short delay for the clipboard to catch up, so let me know if the delay is too short. It could be improved to get just the title by just keeping everything before the link but that’s beyond my AppleScript knowledge — please let me know if you know how to do this. Feedback welcomed.

Get Name

tell application "System Events"
	tell process "BusyCal"
		if enabled of menu item "Copy Event URL with Title" of menu 1 of menu bar item "File" of menu bar 1 then
			-- Item selected
			click menu item "Copy Event URL with Title" of menu 1 of menu bar item "File" of menu bar 1
			delay 0.1
			get the clipboard
		end if
		-- else item not selected
	end tell
end tell

Get Address

tell application "System Events"
	tell process "BusyCal"
		if enabled of menu item "Copy Event URL to Clipboard" of menu 1 of menu bar item "File" of menu bar 1 then
			-- Item selected
			click menu item "Copy Event URL to Clipboard" of menu 1 of menu bar item "File" of menu bar 1
			delay 0.1
			get the clipboard
		end if
		-- else item not selected
	end tell
end tell
1 Like

OK, I’ve sorted out the title:

Get Name

-- Text that indicates end of title
set afterTitle to " <busycalevent://info/"

tell application "System Events"
	tell process "BusyCal"
		if enabled of menu item "Copy Event URL with Title" of menu 1 of menu bar item "File" of menu bar 1 then
			-- Item selected
			click menu item "Copy Event URL with Title" of menu 1 of menu bar item "File" of menu bar 1
			delay 0.1
			set theURLWithTitle to the clipboard
			repeat until theURLWithTitle ends with afterTitle
				set theURLWithTitle to characters 1 thru ((length of theURLWithTitle) - 1) of theURLWithTitle as string
			end repeat
			set theURLWithTitle to characters 1 thru ((length of theURLWithTitle) - (length of afterTitle)) of theURLWithTitle as string
			set trimmedTitle to theURLWithTitle
			get trimmedTitle
		end if
		-- else item not selected
	end tell
end tell
1 Like

Both scripts in their final versions above work beautifully. Thank you @stevelw. Better than what Hook does with Fantastical 2 because the link is to a specific event with these BusyCal scripts. Fantastical links are links to the day, which is less useful for a busy calendar.

2 Likes

We’ve added this to the Hook integration script server.

1 Like

I’ve been having some crashes and one way links with this today. I think what’s going on is that if the clipboard hasn’t updated in the brief delay then the loop never stops.

I think the fix is to check if the string being searched for never appears and if so try to get the clipboard again — if the clipboard is still the same then exit with an error. Alternatively the delay could just be increased but this will slow it down even when it doesn’t need to be.

When I have updated my script I’ll post it here, unless someone else gets to it first

I haven’t seen those problems with the script. There is a long delay before the Hook window opens, so a user might think something is broken.

A dividend of the BusyCal integration is that Hook works not only with calendar entries, but also with the reminders panel in BusyCal.

OK, I have updated the scripts with a number of improvements.

  1. The scripts should never hang in a loop now if the clipboard is not updated properly or the input is not formatted as expected.
  2. A delay is only used if needed and proportionately to the delay needed for the speed of system and current load on the system.
  3. Instead of using a loop to trim the Name the script uses a single calculation.

Hopefully this should speed up the scripts and make them much more robust.

Are you still seeing the long delay? Hopefully not with these changes.

That’s great — I don’t use the To Do feature, so it’s good to know.

Get Name

set afterTitle to " <busycalevent://info/"
set lengthOfClipboardAfterTitle to 69

tell application "System Events"
	tell process "BusyCal"
		if enabled of menu item "Copy Event URL with Title" of menu 1 of menu bar item "File" of menu bar 1 then
			-- Item selected
			click menu item "Copy Event URL with Title" of menu 1 of menu bar item "File" of menu bar 1
			set titleFound to false
			repeat 3 times
				set theURLWithTitle to the clipboard
				if theURLWithTitle contains afterTitle then
					set lengthOfTitle to (length of theURLWithTitle) - lengthOfClipboardAfterTitle
					set trimmedTitle to characters 1 thru lengthOfTitle of theURLWithTitle as string
					set titleFound to true
					exit repeat
				else
					-- Clipboard doesn't contain title of selected item, so try getting clipboard again
					delay 0.1
				end if
			end repeat
			if titleFound then
				get trimmedTitle
			end if
		end if
		-- else item not selected
	end tell
end tell

Get Address

set startOfURL to "busycalevent://info/"

tell application "System Events"
	tell process "BusyCal"
		if enabled of menu item "Copy Event URL to Clipboard" of menu 1 of menu bar item "File" of menu bar 1 then
			-- Item selected
			click menu item "Copy Event URL to Clipboard" of menu 1 of menu bar item "File" of menu bar 1
			set urlFound to false
			repeat 3 times
				set theURL to the clipboard
				if theURL contains startOfURL then
					set urlFound to true
					exit repeat
				else
					-- Clipboard doesn't contain URL of selected item, so try getting clipboard again
					delay 0.1
				end if
			end repeat
			if urlFound then
				get theURL
			end if
		end if
		-- else item not selected
	end tell
end tell
1 Like

Thank you! We have updated the Hook integration server accordingly

1 Like

Thanks much again for your contribution!

Improved BusyCal support is now in Hook itself (build 2317).

1 Like

Sorry, I’ve introduced a minor bug here which miss-reads the title (it inserts ‘id=’ between each character of the title). I had noticed the title not working but it used to work properly and no-one else was complaining so I thought the error must be somewhere else.

The line to replace is:

set trimmedTitle to characters 1 thru lengthOfTitle of theURLWithTitle as string

With the correct code:

set trimmedTitle to text 1 thru lengthOfTitle of theURLWithTitle

@LucB

A race condition exists if the clipboard contains a link to a BusyCal item before Hook is invoked, which can lead to a unidirectional Hook connection being created. Fixed code below.

Get Name

set afterTitle to " <busycalevent://info/"
set lengthOfClipboardAfterTitle to 69

tell application "System Events"
	tell process "BusyCal"
		set the clipboard to ""
		if enabled of menu item "Copy Event URL with Title" of menu 1 of menu bar item "File" of menu bar 1 then
			-- Item selected
			click menu item "Copy Event URL with Title" of menu 1 of menu bar item "File" of menu bar 1
			set titleFound to false
			repeat 3 times
				set theURLWithTitle to the clipboard
				if theURLWithTitle contains afterTitle then
					set lengthOfTitle to (length of theURLWithTitle) - lengthOfClipboardAfterTitle
					set trimmedTitle to text 1 thru lengthOfTitle of theURLWithTitle
					set titleFound to true
					exit repeat
				else
					-- Clipboard doesn't contain title of selected item, so try getting clipboard again
					delay 0.1
				end if
			end repeat
			if titleFound then
				get trimmedTitle
			end if
		end if
		-- else item not selected
	end tell
end tell

Get Address

set startOfURL to "busycalevent://info/"

tell application "System Events"
	tell process "BusyCal"
		set the clipboard to ""
		if enabled of menu item "Copy Event URL to Clipboard" of menu 1 of menu bar item "File" of menu bar 1 then
			-- Item selected
			click menu item "Copy Event URL to Clipboard" of menu 1 of menu bar item "File" of menu bar 1
			set urlFound to false
			repeat 3 times
				set theURL to the clipboard
				if theURL contains startOfURL then
					set urlFound to true
					exit repeat
				else
					-- Clipboard doesn't contain URL of selected item, so try getting clipboard again
					delay 0.1
				end if
			end repeat
			if urlFound then
				get theURL
			end if
		end if
		-- else item not selected
	end tell
end tell

@LucB @grahamb This line seems to be missing from the script server which is leaving startOfURL undefined and causing the integration to fail.

Thanks for noticing that, I was testing with the Setapp version of BusyCal and forgot to update the standalone version’s scripts.