Contacts.app and Mavericks

I have been using this code to extract Contact info and import into Salesforce - now it breaks on the Phone number part:

tell application "Contacts"
	
	set selPerson to selection
	
	repeat with thisperson in selPerson
		
		-- This part get the email address from the vCard - if there is more than one address is available, then the user is prompted to choose a single address from a list
		
		set MailList to value of email of thisperson as list
		-- 		display dialog MailList
		set MailQty to count of items in MailList
		if MailQty is equal to 1 then
			set UseThisEmail to text of MailList
		else
			set UseThisEmail to (choose from list MailList) -- as list
		end if
		
		set EmailAddy to UseThisEmail
		
		-- This part get the phone number from the vCard - if there is more than one phone number is available, then the user is prompted to choose a single phone number from a list
		
		set PhoneList to value of phone of thisperson as list
		set PhoneQty to count of items in PhoneList
		if PhoneQty is equal to 1 then
			set UseThisPhone to PhoneList
		else
			set UseThisPhone to (choose from list PhoneList) as text
		end if
		
		set NewPhone to UseThisPhone as text
		
		-- then we format the number correctly
		
		set formattedNumber to do shell script "echo " & quoted form of (text ((offset of "(" in NewPhone) + 1) thru -1 of NewPhone) & " | tr -d ')'-' '"
		set formattedNumber to formattedNumber as text
		
		--	display dialog formattedNumber
		
		set formattedNumber to formattedNumber as Unicode text
		
		set AreaCode to (characters 1 thru 3 of formattedNumber) as text
		set PhExch to (characters 4 thru 6 of formattedNumber) as text
		set LastFourDigits to (characters 7 thru 10 of formattedNumber) as text
		set OrgPhone to "(" & AreaCode & ") " & PhExch & "-" & LastFourDigits as text
		
		--	display dialog OrgPhone
		
		set ContactFirstName to first name of thisperson -- as text
		set ContactLastName to last name of thisperson -- as text
		set QBBillingAddress1 to get street of addresses of thisperson as text
		set AccountCity to get city of addresses of thisperson as text
		set AccountState to get state of addresses of thisperson as text
		set AccountZip to get zip of addresses of thisperson as text
		set BillingCityStateZip to AccountCity & " " & AccountState & " " & AccountZip
		set QBBillingAddress1 to QBBillingAddress1 & "
" & BillingCityStateZip
		set AccountName to organization of thisperson
		
		set SFBillStreet to street of addresses of thisperson as text
		set SFCity to get city of addresses of thisperson as text
		set SFState to get state of addresses of thisperson as text
		set SFZip to get zip of addresses of thisperson as text
	end repeat
	
	-- display dialog SFZip
	
	display dialog AccountName & "
" & ContactFirstName & " " & ContactLastName & "
" & QBBillingAddress1 & "
" & EmailAddy & "¬
" & OrgPhone as text
end tell

Funny, “phone” doesn’t seem to be a valid property anymore:

tell application "Contacts"
	set selPerson to selection
	repeat with thisperson in selPerson
		get properties of thisperson
	end repeat
end tell

Hi.

A ‘phone’ isn’t a property in Contacts, it’s an element. (It’s a thing, not a value, and there can be more than one.)

The phone number extraction in your script works in Mavericks on my machine, but the line .

set PhoneList to value of phone of thisperson as list

. should be .

set PhoneList to value of phones of thisperson

If the person doesn’t have any phones, the empty list will be passed to ‘choose from list’ and cause an error. That section would be better like this:

		set PhoneList to value of phones of thisperson
		set PhoneQty to (count PhoneList)
		if (PhoneQty is less than 2) then -- No phone or only 1.
			set UseThisPhone to PhoneList
		else
			set UseThisPhone to (choose from list PhoneList)
			if (UseThisPhone is false) then error number -128 -- Cancel button clicked. Stop the script.
		end if
		
		set NewPhone to UseThisPhone as text

Thanks Nigel -

I’ve tried both phone and phones - both return the error -1728

error “Contacts got an error: Can’t get value of every phone of person id "3D973947-CF84-4980-83B8-1E3934C3DAC8:ABPerson".” number -1728 from value of every phone of person id “3D973947-CF84-4980-83B8-1E3934C3DAC8:ABPerson”

Well, I’m mystified. That particular error arises when a reference can’t be resolved, such as when the person has no phones and thus no values of phones. But with both Contacts on my Mavericks machine and Address Book on my Leopard one, that particular situation simpy returns an empty list.

The only other thing I can think of at the moment is a terminology clash. You said in your first post that you use the code to import the info into something called Salesforce, although there’s no mention of a Salesforce in it. Is the Contacts code perhaps nested within a ˜tell application “Salesforce”’ statement in the full script?

Thanks again Nigel -

I think Apple broke Contacts.app when it was updated for Mavericks. This line should work, and it doesn’t:

set PhoneList to value of phone of thisperson

There’s still a mention of “phone” in the scripting library, but contacts don’t have a “phone” property in real life.

My temporary fix is to manually copy/paste the phone number into the note field, and use this:


set PhoneList to note of thisperson
set NewPhone to UseThisPhone as text

Salesforce is irrelevant. I should be able to use this collected data in anything. The error comes when trying to retrieve the data.

Please yourself. Suffice it to reiterate:

¢ It’s still perfectly possible to get the values of people’s phones in Contacts in Mavericks. The reason why this isn’t happening in your case hasn’t been determined. The information I asked for regarding ‘tell’ statements hasn’t been forthcoming.
¢ The line you say should work but doesn’t in fact shouldn’t work but does. As I told you in my first reply, a ‘phone’ isn’t a property but an element. A ‘person’ can contain one or more ‘phones’ or none at all. (Similarly with ‘emails’ and ‘addresses’.) That’s why your code contains lines asking the user to choose when there are multiple phones. (And when there are multiple emails. It doesn’t cater for the possibility of multiple addresses or zero phones, emails, or addresses.) References to elements should indicate which such elements are meant: eg. ‘phone 1 of thisperson’, ‘every phone of thisperson’ (or ‘phones of thisperson’ or ‘thisperson’s phones’), etc. So a bald ‘phone of thisperson’ ought to throw an error, but instead, for some reason, it’s treated as its own plural.

I appreciate the help you’re offering - I don’t have another Mavericks machine here to test on - the fact that my script works on your installation is baffling.

This script should work as a standalone script - and it simply does not:


tell application "Contacts"
	--	activate
	set selPerson to selection
	
	repeat with thisperson in selPerson
		
		set PhoneList to value of phones of thisperson
		
		set PhoneQty to (count PhoneList)
		if (PhoneQty is less than 2) then -- No phone or only 1.
			set UseThisPhone to PhoneList
		else
			set UseThisPhone to (choose from list PhoneList)
			if (UseThisPhone is false) then error number -128 -- Cancel button clicked. Stop the script.
		end if
		
		set NewPhone to UseThisPhone as text
		
	end repeat
end tell

It fails on this line: “set PhoneList to value of phones of thisperson” showing the errors I’ve described previously.

The Contacts part of my script runs before the Salesforce part in a different tell block, but here’s that part anyway - Contacts runs first and collects the data, the SFScripting takes over and pushes the data to Salesforce:


tell application "SalesforceScripting"
	activate
	set session to login with saved credentials
	
	--  Create a new Account in Salesforce
	
	set acc to make SObject
	set type of acc to "Account"
	acc setField named "Name" to AccountName
	acc setField named "PDS__QB_Billing_Address__c" to (AccountName & "
" & ContactFirstName & " " & ContactLastName & "
" & QBBillingAddress1)
	acc setField named "BillingStreet" to SFBillStreet
	acc setField named "BillingCity" to SFCity
	acc setField named "BillingState" to SFState
	acc setField named "BillingPostalCode" to SFZip
	acc setField named "Phone" to OrgPhone -- formattedNumber
	set res to session create sobjects acc
	Id of first item of res
	set NewAccountID to Id of first item of res
	
	-- this is for the New Primary Contact on the New Account
	
	set cont to make SObject
	set type of cont to "Contact"
	cont setField named "FirstName" to ContactFirstName
	cont setField named "LastName" to ContactLastName
	cont setField named "AccountId" to NewAccountID
	cont setField named "PDS__Primary_Contact__c" with to
	cont setField named "Email" to EmailAddy
	cont setField named "Phone" to OrgPhone
	
	set res2 to session create sobjects cont
	set NewContactID to Id of first item of res2
	
	-- this makes the New Primary Contact the "Decision Maker"
	
	set crole to make SObject
	set type of crole to "AccountContactRole"
	crole setField named "AccountId" to NewAccountID -- as text
	crole setField named "ContactId" to NewContactID -- as text
	crole setField named "Role" to "Decision Maker" --as text
	crole setField named "IsPrimary" with to
	
	set crole to session create sobjects crole
end tell

-- all done, let's review the new account in Safari

tell application "Safari"
	activate
	open location "https://na9.salesforce.com/" & NewAccountID
	open location "https://na9.salesforce.com/" & NewContactID
end tell

Hi,

I recommend to check the number of phones before retrieving the values


tell application "Contacts"
	--    activate
	set selPerson to selection
	
	repeat with thisperson in selPerson
		
		set PhoneQty to count phones of thisperson
		if (PhoneQty is 1) then -- only 1.
			set NewPhone to value of phone 1 of thisperson
		else if (PhoneQty > 1) then
			set PhoneList to value of phones of thisperson
			set UseThisPhone to (choose from list PhoneList)
			if (UseThisPhone is false) then error number -128 -- Cancel button clicked. Stop the script.
			set NewPhone to UseThisPhone as text
		end if
	end repeat
end tell


Another thought is that the application running the script now needs permission to access your Contacts, although you’d see a system dialog telling you the app wanted such permission before the script even looked at a person, let alone the value of one of the person’s phones.

Does this error affect every person or just one or a few? If not every person, is there anything obviously special about those affected? Particularly about their phones? How many people are selected at a time? Is there a network involved? etc. I’m out of ideas myself, but questions like these could help you pin down the cause of the problem.