AppleScript and Contacts Broke in Ventura

Hello. I have a macro which updates contacts in Apple Contacts via Applescript.

This has worked fine previously, but since upgrading to Ventura the macro fails and I get this error:

Execute an AppleScript failed with script error: text-script:1858:1864: execution error: Not authorised to send Apple events to Contacts. (-1743).

Any ideas how to fix? It worked previously. I have given Keyboard Maestro permission to look up contacts etc.

Thanks

Andy

APPLESCRIPT BELOW

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions


# Set logging variable

set theLog to ""

# Set KM Variables as Applescript Variables

tell application "Keyboard Maestro Engine"
	
	set saac_JSONCountry to getvariable "saac_JSONCountry"
	set saac_JSONCounty to getvariable "saac_JSONCounty"
	set saac_JSONFirst_Name to getvariable "saac_JSONFirst Name"
	set saac_JSONHome_Email to getvariable "saac_JSONHome Email"
	set saac_JSONHome_phone to getvariable "saac_JSONHome phone"
	set saac_JSONMobile_phone to getvariable "saac_JSONMobile phone"
	set saac_JSONName to getvariable "saac_JSONName"
	set saac_JSONOrganisation to getvariable "saac_JSONOrganisation"
	set saac_JSONPostcode to getvariable "saac_JSONPostcode"
	set saac_JSONPrefix to getvariable "saac_JSONPrefix"
	set saac_JSONStreet to getvariable "saac_JSONStreet"
	set saac_JSONSummary to getvariable "saac_JSONSummary"
	set saac_JSONSurname to getvariable "saac_JSONSurname"
	set saac_JSONTown to getvariable "saac_JSONTown"
	set saac_JSONWork_Email to getvariable "saac_JSONWork Email"
	set saac_JSONWork_phone to getvariable "saac_JSONWork phone"
	set saac_JSONurl to getvariable "saac_JSONurl"
	
	# Logic to determine Organisation name
	
	if saac_JSONOrganisation = "true" then
		set saac_Org_name to saac_JSONName
		set saac_JSONOrganisation to true
	else
		set saac_Org_name to ""
		set saac_JSONOrganisation to false
	end if
	
	# Logic to determine address
	
	set saac_address to "true"
	
	if saac_JSONCountry = "" then
		if saac_JSONCounty = "" then
			if saac_JSONStreet = "" then
				if saac_JSONTown = "" then
					if saac_JSONPostcode = "" then
						set saac_address to "false"
					end if
				end if
			end if
		end if
	end if
	
end tell

tell application "Contacts"
	
	
	set theTest to (id of people whose value of urls contains saac_JSONurl) as string
	
	
	if theTest = "" then
		
		# If contact does not already exist, create the contact
		
		set thePerson to make new person with properties {first name:saac_JSONFirst_Name, last name:saac_JSONSurname, organization:saac_Org_name, title:saac_JSONPrefix, note:saac_JSONSummary, company:saac_JSONOrganisation}
		
		if saac_JSONHome_Email = "" then
		else
			make new email at end of emails of thePerson with properties {label:"home", value:saac_JSONHome_Email}
		end if
		
		if saac_JSONWork_Email = "" then
		else
			make new email at end of emails of thePerson with properties {label:"work", value:saac_JSONWork_Email}
		end if
		
		if saac_JSONMobile_phone = "" then
		else
			make new phone at end of phones of thePerson with properties {label:"mobile", value:saac_JSONMobile_phone}
		end if
		
		if saac_JSONHome_phone = "" then
		else
			make new phone at end of phones of thePerson with properties {label:"home", value:saac_JSONHome_phone}
		end if
		
		if saac_JSONWork_phone = "" then
		else
			make new phone at end of phones of thePerson with properties {label:"work", value:saac_JSONWork_phone}
		end if
		
		if saac_address = "true" then
			make new address at end of addresses of thePerson with properties {label:"home", street:saac_JSONStreet, city:saac_JSONTown, state:saac_JSONCounty, zip:saac_JSONPostcode, country:saac_JSONCountry}
		end if
		
		if saac_JSONurl = "" then
		else
			make new url at end of urls of thePerson with properties {label:"home", value:saac_JSONurl}
		end if
		
		
		set theLog to "- Created new contact" & return
		
	else
		
		# If contact does exist, compare and update the attributes
		
		set thePeople to (people whose value of urls contains saac_JSONurl)
		
		set thePerson to item 1 of thePeople
		
		if saac_JSONFirst_Name = "" then
			if first name of thePerson is missing value then
			else
				set first name of thePerson to missing value
			end if
		else
			if first name of thePerson is saac_JSONFirst_Name then
			else
				set first name in thePerson to saac_JSONFirst_Name
				set theLog to theLog & "- First Name updated" & return
			end if
		end if
		
		
		if saac_JSONSurname = "" then
			if last name of thePerson is missing value then
			else
				set last name of thePerson to missing value
			end if
		else
			if last name of thePerson is saac_JSONSurname then
			else
				set last name in thePerson to saac_JSONSurname
				set theLog to theLog & "- Last Name updated" & return
			end if
		end if
		
		if saac_Org_name = "" then
			if organization of thePerson is missing value then
			else
				set organization of thePerson to missing value
			end if
		else
			if organization of thePerson is saac_Org_name then
			else
				set organization in thePerson to saac_Org_name
				set theLog to theLog & "- Organisation Name updated" & return
			end if
		end if
		
		if company of thePerson is saac_JSONOrganisation then
		else
			set company in thePerson to saac_JSONOrganisation
			set theLog to theLog & "- Company status updated" & return
		end if
		
		if saac_JSONPrefix = "" then
			if title of thePerson is missing value then
			else
				set title of thePerson to missing value
			end if
		else
			if title of thePerson is saac_JSONPrefix then
			else
				set title in thePerson to saac_JSONPrefix
				set theLog to theLog & "- Prefix (title) updated" & return
			end if
		end if
		
		if saac_JSONSummary = "" then
			if note of thePerson is missing value then
			else
				set note of thePerson to missing value
			end if
		else
			
			if note of thePerson is saac_JSONSummary then
			else
				set note in thePerson to saac_JSONSummary
				set theLog to theLog & "- Notes updated" & return
			end if
		end if
		
		
		set theEmails to emails of thePerson
		set emailsToDelete to ""
		
		repeat with theEmail in theEmails
			set theEmailValue to (value of theEmail) as string
			if (label of theEmail) contains "home" then
				if saac_JSONHome_Email = "" then
					set emailsToDelete to emailsToDelete & (id of theEmail) & return
					set theLog to theLog & "- Deleted home email: " & theEmailValue & return
				else
					if (value of theEmail) = saac_JSONHome_Email then
					else
						set (value of theEmail) to saac_JSONHome_Email
						set theLog to theLog & "- Updated home email: " & saac_JSONHome_Email & return
					end if
					set saac_JSONHome_Email to ""
				end if
			else
				if (label of theEmail) contains "work" then
					if saac_JSONWork_Email = "" then
						set emailsToDelete to emailsToDelete & (id of theEmail) & return
						set theLog to theLog & "- Deleted work email: " & theEmailValue & return
					else
						if (value of theEmail) = saac_JSONWork_Email then
						else
							set (value of theEmail) to saac_JSONWork_Email
							set theLog to theLog & "- Updated work email: " & saac_JSONHome_Email & return
							
						end if
						set saac_JSONWork_Email to ""
					end if
				else
					set emailsToDelete to emailsToDelete & (id of theEmail) & return
					set theLog to theLog & "- Deleted unknown email: " & theEmailValue & return
					
				end if
			end if
		end repeat
		
		set emailsToDelete to paragraphs of emailsToDelete
		
		repeat with emailDelete in emailsToDelete
			if emailDelete = "" then
			else
				delete (emails of thePerson whose id is emailDelete)
			end if
		end repeat
		
		if saac_JSONHome_Email = "" then
		else
			make new email at end of emails of thePerson with properties {label:"home", value:saac_JSONHome_Email}
			set theLog to theLog & "- Added home email: " & saac_JSONHome_Email & return
		end if
		
		if saac_JSONWork_Email = "" then
		else
			make new email at end of emails of thePerson with properties {label:"work", value:saac_JSONWork_Email}
			set theLog to theLog & "- Added work email: " & saac_JSONWork_Email & return
		end if
		
		
		
		
		
		
		set thePhones to phones of thePerson
		set phonesToDelete to ""
		
		repeat with thePhone in thePhones
			set thePhoneValue to (value of thePhone) as string
			if (label of thePhone) contains "home" then
				if saac_JSONHome_phone = "" then
					set phonesToDelete to phonesToDelete & (id of thePhone) & return
					set theLog to theLog & "- Deleted home phone: " & thePhoneValue & return
				else
					if (value of thePhone) = saac_JSONHome_phone then
					else
						set (value of thePhone) to saac_JSONHome_phone
						set theLog to theLog & "- Updated home phone: " & saac_JSONHome_phone & return
					end if
					set saac_JSONHome_phone to ""
				end if
			else
				if (label of thePhone) contains "work" then
					if saac_JSONWork_phone = "" then
						set phonesToDelete to phonesToDelete & (id of thePhone) & return
						set theLog to theLog & "- Deleted work phone: " & thePhoneValue & return
					else
						if (value of thePhone) = saac_JSONWork_phone then
						else
							set (value of thePhone) to saac_JSONWork_phone
							set theLog to theLog & "- Updated work phone: " & saac_JSONHome_phone & return
							
						end if
						set saac_JSONWork_phone to ""
					end if
				else
					if (label of thePhone) contains "mobile" then
						if saac_JSONMobile_phone = "" then
							set phonesToDelete to phonesToDelete & (id of thePhone) & return
							set theLog to theLog & "- Deleted mobile phone: " & thePhoneValue & return
						else
							if (value of thePhone) = saac_JSONMobile_phone then
							else
								set (value of thePhone) to saac_JSONMobile_phone
								set theLog to theLog & "- Updated mobile phone: " & saac_JSONMobile_phone & return
								
							end if
							set saac_JSONMobile_phone to ""
						end if
					else
						set phonesToDelete to phonesToDelete & (id of thePhone) & return
						set theLog to theLog & "- Deleted unknown phone number: " & thePhoneValue & return
						
					end if
					
				end if
			end if
		end repeat
		
		set phonesToDelete to paragraphs of phonesToDelete
		
		repeat with phoneDelete in phonesToDelete
			if phoneDelete = "" then
			else
				delete (phones of thePerson whose id is phoneDelete)
			end if
		end repeat
		
		if saac_JSONMobile_phone = "" then
		else
			make new phone at end of phones of thePerson with properties {label:"mobile", value:saac_JSONMobile_phone}
			set theLog to theLog & "- Added mobile phone: " & saac_JSONMobile_phone & return
		end if
		
		if saac_JSONHome_phone = "" then
		else
			make new phone at end of phones of thePerson with properties {label:"home", value:saac_JSONHome_phone}
			set theLog to theLog & "- Added home phone: " & saac_JSONHome_phone & return
		end if
		
		if saac_JSONWork_phone = "" then
		else
			make new phone at end of phones of thePerson with properties {label:"work", value:saac_JSONWork_phone}
			set theLog to theLog & "- Added work phone: " & saac_JSONWork_phone & return
		end if
		
		
		
		
		
		set theAddresses to addresses of thePerson
		set addressesToDelete to ""
		set saac_addressmatch to "false"
		
		repeat with theAddress in theAddresses
			if (label of theAddress) contains "home" then
				if saac_address = "false" then
					set addressesToDelete to addressesToDelete & (id of theAddress) & return
					set theLog to theLog & "- Deleted home address" & return
				else
					
					if saac_JSONStreet = "" then
						set aa1 to missing value
					else
						set aa1 to saac_JSONStreet
					end if
					
					if saac_JSONTown = "" then
						set aa2 to missing value
					else
						set aa2 to saac_JSONTown
					end if
					
					if saac_JSONCounty = "" then
						set aa3 to missing value
					else
						set aa3 to saac_JSONCounty
					end if
					
					if saac_JSONPostcode = "" then
						set aa4 to missing value
					else
						set aa4 to saac_JSONPostcode
					end if
					
					if saac_JSONCountry = "" then
						set aa5 to missing value
					else
						set aa5 to saac_JSONCountry
					end if
					set a1 to (street of theAddress) & (city of theAddress) & (state of theAddress) & (zip of theAddress) & (country of theAddress)
					set a2 to aa1 & aa2 & aa3 & aa4 & aa5
					
					if a1 = a2 then
						set saac_addressmatch to "true"
					end if
					
					set saac_address to "false"
					if saac_addressmatch = "true" then
					else
						
						set (street of theAddress) to saac_JSONStreet
						set (city of theAddress) to saac_JSONTown
						set (state of theAddress) to saac_JSONCounty
						set (zip of theAddress) to saac_JSONPostcode
						set (country of theAddress) to saac_JSONCountry
						
						
						set theLog to theLog & "- Updated home address" & return
					end if
				end if
			else
				set addressesToDelete to addressesToDelete & (id of theAddress) & return
				set theLog to theLog & "- Deleted unknown address" & return
				
			end if
		end repeat
		
		set addressesToDelete to paragraphs of addressesToDelete
		
		repeat with addressDelete in addressesToDelete
			if addressDelete = "" then
			else
				delete (addresses of thePerson whose id is addressDelete)
			end if
		end repeat
		
		if saac_address = "true" then
			make new address at end of addresses of thePerson with properties {label:"home", street:saac_JSONStreet, city:saac_JSONTown, state:saac_JSONCounty, zip:saac_JSONPostcode, country:saac_JSONCountry}
			set theLog to theLog & "- Added home address" & return
		end if
		
		
		
		
	end if
	
	save
	
end tell

tell application "Keyboard Maestro Engine"
	setvariable "saac_individual_log" to theLog
end tell

Hi Andy, please post your macro including the AppleScript in question so we can help. We have little way of knowing what the issue might be without seeing them. :wink:

-Chris

Hi,

I've pasted the AppleScript into the original post, thanks.

Basically it grabs a load of variables from Keyboard Maestro, checks them against an existing contact, and updates the contact if there are changes.

It is a hacky way of getting a one way sync.

But it was working fine (ran once a day) up until Ventura.

Andy

1 Like

I can confirm that AppleScript for Contacts in Ventura is broken.

I have a much used Macro to create new contacts and this has stopped working (only on my Ventura Mac) with the same error message about permissions. A Google Search shows this being mentioned on other Forums - and there is no user fix it seems.

I hope Apple mends this.

1 Like

Yep, for whatever reason Contacts doesn't appear to passing on the authorisation request, and there's no way to manually authorise in "Privacy & Settings".

Bad Apple...

2 Likes

Hey Guys,

Be sure an complain to Apple.

-Chris

1 Like

I have had this problem on every computer I upgraded to Ventura which REALLY broke a lot of my automations.

I have found that the Contacts portion of Shortcuts is pretty robust and have replaced my calls to Contacts with calls to "Shortcuts Events".

As an example:

	tell application "Shortcuts Events"
		set setOfPeople to run the shortcut named ¬
			"Get Contact with Email" with input theSender
	end tell

Rick

1 Like

Clearly Apple broke something. Please take the time to complain to Apple – the more people who do the quicker they're likely to fix it.

1 Like

Yes, I have reported to Apple and I notice it has also been included in the list of Ventura bugs on MacRumours since October.

2 Likes

On it, Chris.

2 Likes

UPDATE - this AppleScript Contacts bug appears to have been fixed by Apple in Ventura 13.1

1 Like

I'm so tired of saying ”Bad Apple!“ that I just have to say it:

Good on Apple (for a change)!

:sunglasses:

4 Likes

Tim Apple?

That's great that Apple fixed it!

1 Like