Okay, I’m a worst case scenario - little knowledge and no fear of tweaking.
Here’s what I’m trying to do:
- Based on a selected email(s)
- Add the sender to a group(s) in Contacts
I had a script that used to work but somehow gave up the ghost.
So now I tried to cobble together two different scripts and I’ve gotten something that runs without error but does NOTHING! (perfect, right?)
Can anyone tell me either where my errors are in the script attached OR a better way to do this?
Thanks,
Anthony
tell application "Mail" to set theSelection to selection
if theSelection is {} then return beep 2
if length of theSelection = 1 then
set thePrompt to "Select the group(s) to which to add the sender of the selected message."
else
set thePrompt to "Select the group(s) to which to add the senders of the selected messages."
end if
tell application "Contacts" to set theList to name of groups
set R to choose from list theList with prompt thePrompt with multiple selections allowed
if R is false then return
tell application "Mail"
activate
set theSenders to {}
repeat with thisMessage in theSelection
set theSender to extract name from sender of thisMessage
set nameArray to my split(theSender, " ")
set theFirstName to item 1 of nameArray
set theLastName to last item of nameArray
set theEmail to extract address from sender of thisMessage
copy theSender to the end of theSenders
end repeat
end tell
tell application "Contacts"
activate
repeat with thisSender in theSenders
delay 0.1
set thePersons to (people whose value of emails contains (thisSender as text))
if (count thePersons) = 1 then
repeat with theGroupName in items of R
add (item 1 of thePersons) to group theGroupName
end repeat
else
repeat with theGroupName in items of R
repeat with thisPerson in thePersons
add thisPerson to group theGroupName
set thePerson to make new person with properties {first name:theFirstName, last name:theLastName}
make new email at end of emails of thePerson with properties {label:"Work", value:theEmail}
save
end repeat
end repeat
end if
end repeat
save
set selected of group theGroupName to true
end tell
on split(theString, theDelimiter)
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theArray to every text item of theString
set AppleScript's text item delimiters to oldDelimiters
return theArray
end split
My understanding is that there is an error with the instruction:
set thePersons to (people whose value of first email contains (thisSender as text))
I guess that it’s supposed to be something like:
set thePersons to (people whose value of first email contains (theEmail as text))
Of course it assume that you trace the emails as you trace the senders.
Here is an edited script :
tell application "Mail" to set theSelection to selection
if theSelection is {} then return beep 2
if length of theSelection = 1 then
set thePrompt to "Select the group(s) to which to add the sender of the selected message."
else
set thePrompt to "Select the group(s) to which to add the senders of the selected messages."
end if
tell application "Contacts" to set theList to name of groups
set R to choose from list theList with prompt thePrompt with multiple selections allowed
if R is false then return
tell application "Mail"
activate
set theSenders to {}
set theEmails to {} # ADDED
repeat with thisMessage in theSelection
set theSender to extract name from sender of thisMessage
set nameArray to my split(theSender, " ")
set theFirstName to item 1 of nameArray
set theLastName to last item of nameArray
set theEmail to extract address from sender of thisMessage
copy theSender to the end of theSenders
copy theEmail to the end of theEmails # ADDED
end repeat
end tell
tell application "Contacts"
activate
set indx to 0 # ADDED
repeat with thisSender in theSenders
delay 0.1
set indx to indx + 1 # ADDED
set theEmail to item indx of theEmails # ADDED
set thePersons to (people whose value of first email contains (theEmail as text)) # MODIFIED
if (count thePersons) = 1 then
repeat with theGroupName in items of R
add (item 1 of thePersons) to group theGroupName
end repeat
else
repeat with theGroupName in items of R
repeat with thisPerson in thePersons
add thisPerson to group theGroupName
set thePerson to make new person with properties {first name:theFirstName, last name:theLastName}
try
make new email at end of emails of thePerson with properties {label:"Work", value:theEmail}
end try
save
end repeat
end repeat
end if
end repeat
save
set selected of group theGroupName to true
end tell
on split(theString, theDelimiter)
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theArray to every text item of theString
set AppleScript's text item delimiters to oldDelimiters
return theArray
end split
CAUTION : I tested only with datas in which there is no people sharing the same email (which means that thePersons contain only one item).
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 2 mars 2019 19:04:36
Here is an extended version.
This one create a new record if there was no existing one matching the mail address.
(*
https://macscripter.net/viewtopic.php?pid=195222#p195222
add sender from Mail to Contacts
2019/03/04 added code for special case where theArray contains a single string
and enhanced the mode replaceEmail is false
*)
property replaceEmail : false
(*
set it to true to replace the email in a record matching first name, last name but not the email
set it to false to add a new email in a record matching first name, last name but not the email
*)
tell application "Mail" to set theSelection to selection
if theSelection is {} then return beep 2
if length of theSelection = 1 then
set thePrompt to "Select the group(s) to which to add the sender of the selected message."
else
set thePrompt to "Select the group(s) to which to add the senders of the selected messages."
end if
tell application "Contacts" to set theList to name of groups
set R to choose from list theList with prompt thePrompt with multiple selections allowed
if R is false then return
tell application "Mail"
activate
set theSenders to {}
set theEmails to {} # ADDED
set theFirstNames to {} # ADDED
set theLastNames to {} # ADDED
repeat with thisMessage in theSelection
set theSender to extract name from sender of thisMessage
set theEmail to extract address from sender of thisMessage
copy theSender to the end of theSenders
copy theEmail to the end of theEmails # ADDED
set nameArray to my split(theSender, " ")
if (count nameArray) > 1 then # ADDED
copy item 1 of nameArray to the end of theFirstNames # ADDED
else # ADDED
copy "" to the end of theFirstNames # ADDED
end if # ADDED
copy item -1 of nameArray to the end of theLastNames # ADDED
end repeat
end tell
tell application "Contacts"
activate
set indx to 0 # ADDED
repeat with thisSender in theSenders
delay 0.1
set indx to indx + 1 # ADDED
set the_MailAddress to item indx of theEmails # ADDED
set the_FirstName to item indx of theFirstNames # ADDED
set the_LastName to item indx of theLastNames # ADDED
set thePersons to (people whose value of first email contains (the_MailAddress as text)) # MODIFIED
if (count thePersons) = 0 then
# must create a card
(* try to grab an existing record *)
try
if the_FirstName = "" then # ADDED
set the_Person to get (1st person whose (last name is the_LastName)) # ADDED
else # ADDED
set the_Person to get (1st person whose (first name is the_FirstName) and (last name is the_LastName))
end if # ADDED
the_Person (* Generates an error if there is no such a person *)
(*
We are here if there is already a record for such first and last name. Edit its mail address.
On est là s'il existe déjà une fiche pour ce couple nom + prénom. On édite l'adresse mail *)
tell the_Person
if the_MailAddress is not missing value then
if replaceEmail then
try (* 1 *)
set value of (get email 1) to the_MailAddress
on error
(*
We are here if there was no email data in the record, create it
On est là si la fiche ne contenait pas d’adresse mail, on en insère une *)
try (* 2 *)
make new email at the end of emails with properties {value:the_MailAddress, label:"Work"}
end try (* 2 *)
end try (* 1 *)
else
(*
There is already at least an email, check if the new one is already stored # ADDED
*)
set theEmails to (get every email) # ADDED
set isAvailable to false # ADDED
repeat with anEmail in theEmails # ADDED
if (get value of anEmail) = the_MailAddress then # ADDED
set isAvailable to true # ADDED
exit repeat # ADDED
end if # ADDED
end repeat # ADDED
try (* 3 *)
if not isAvailable then make new email at the end of emails with properties {value:the_MailAddress, label:"Work"} # EDITED
end try (* 3 *)
end if
end if -- the_MailAddress
end tell -- the_Person
on error
(*
We are here if there was no such a record. Create a new one.
On est là si ce couple nom + prénom n’existait pas dans ce groupe, on crée une fiche *)
try (* 1 *)
# Cette formule semble préférable à la création d'un prénom contenant une chaîne vide
# On laisse ainsi le même état que lors d'une création manuelle.
if the_FirstName is "" then
set the_Person to (make new person with properties {last name:the_LastName, company:true})
else
set the_Person to (make new person with properties {first name:the_FirstName, last name:the_LastName, company:true})
end if
end try (* 1 *)
tell the_Person
try (* 1 *)
make new email at the end of emails with properties {value:the_MailAddress, label:"Work"}
end try (* 1 *)
end tell -- the_Person
end try
repeat with theGroupName in items of R
add the_Person to group theGroupName (* inserts the person in the group(s). *)
end repeat
else if (count thePersons) = 1 then
repeat with theGroupName in items of R
add (item 1 of thePersons) to group theGroupName
end repeat
else
repeat with theGroupName in items of R
repeat with thisPerson in thePersons
add thisPerson to group theGroupName
set thePerson to make new person with properties {first name:the_FirstName, last name:the_LastName} # EDITED
try
make new email at end of emails of thePerson with properties {label:"Work", value:the_MailAddress} # EDITED
end try
save
end repeat
end repeat
end if
end repeat
save
set selected of group theGroupName to true
end tell
on split(theString, theDelimiter)
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theArray to every text item of theString
set AppleScript's text item delimiters to oldDelimiters
return theArray
end split
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 3 mars 2019 14:02:59
Edited to add the option : replaceEmail
Edited : added code for special case where theArray contains a single string
and enhanced the mode replaceEmail is false
Merci beaucoup! C’est parfait!
Thanks for the feedback.
I added some enhancements above.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 4 mars 2019 17:41:52