Add Sender to Address Book and Reply
When I posted the FAQ concerning my transition from Apple, it included a way for people interested in user automation to receive future communications from me about the topic. To my delight and surprise, I received requests (via email) from hundreds of folks from around the world.
Replying to a large volume of messages can be challenging, as these steps are required for each of the messages:
So what I came up with is an AppleScript script, saved to the Script Menu in Mail, and run individually after selecting each requester message, one-at-a-time. It turns out that the script is a great way to process a large number of individual emails, while retaining the ability read and respond to those requesters who added personal comments and questions.
All-in-all, responding to each of the requests took three days to complete, but was it very informative and never tedious, all thanks to the User Automation support in Mail and Contacts.
I don’t know if you’ll ever be in the same situation, but perhaps there are some ideas and tools you can use from this script:
Add Sender to Address Book and Reply | ||
Open in Script Editor | ||
01 | use framework "Foundation" | |
02 | use scripting additions | |
03 | ||
04 | set messageBody to "Thank you for your interest and support. You’ve been added to my newsletter list. Should you ever wish to stop receiving communications from me, just send me another email!" & return & return & "Cheers," & return & return & "Your Name Here" & return & "Twitter: | |
05 | ||
06 | tell application id "com.apple.AddressBook" | |
07 | if not (exists group "Newsletter") then | |
08 | make new group with properties {name:"Newsletter"} | |
09 | end if | |
10 | set targetGroup to group "Newsletter" | |
11 | end tell | |
12 | ||
13 | tell application id "com.apple.mail" | |
14 | activate | |
15 | try | |
16 | if (count of message viewers) is 0 then | |
17 | error "No message viewer is open." | |
18 | end if | |
19 | set theseMessages to (get selected messages of the front message viewer) | |
20 | if theseMessages is missing value then | |
21 | error "No message is selected." | |
22 | end if | |
23 | -- Process multiple messages although likely used for one message at a time | |
24 | set messageCount to the count of theseMessages | |
25 | repeat with i from 1 to the messageCount | |
26 | set thisMessage to item i of theseMessages | |
27 | set messageSenderData to sender of thisMessage | |
28 | (*Johnny Appleseed <john@appleseed.com>*) | |
29 | copy my extractSenderDataFromSenderObject(messageSenderData) to {senderName, emailAddress} | |
30 | if the (count of words of senderName) is not 1 then | |
31 | set greetingName to the first word of senderName | |
32 | set firstName to first word of senderName | |
33 | set lastName to last word of senderName | |
34 | else | |
35 | set greetingName to senderName | |
36 | set firstName to senderName | |
37 | set lastName to "" | |
38 | end if | |
39 | set newMessage to reply thisMessage with opening window and reply to all | |
40 | set content of newMessage to greetingName & ", " & return & return & messageBody | |
41 | -- The Contacts application | |
42 | tell application id "com.apple.AddressBook" | |
43 | activate | |
44 | set aPerson to make new person with properties {first name:firstName, last name:lastName} | |
45 | tell aPerson | |
46 | make new email with properties {label:"work", value:emailAddress} | |
47 | end tell | |
48 | -- to set changes, the database must be saved | |
49 | save | |
50 | add aPerson to targetGroup | |
51 | save | |
52 | if i is messageCount then | |
53 | -- OPTIONAL: to assist with editing, select the new person in the Contacts app | |
54 | set selection to {aPerson} | |
55 | end if | |
56 | end tell | |
57 | end repeat | |
58 | on error errorMsg number errorNum | |
59 | activate | |
60 | display alert (errorNum as string) message errorMsg | |
61 | end try | |
62 | end tell | |
63 | ||
64 | on extractSenderDataFromSenderObject(messageSenderData) | |
65 | set x to the offset of "<" in messageSenderData | |
66 | if x is 0 then -- no name/address combo | |
67 | set emailAddress to messageSenderData | |
68 | set z to offset of "@" in emailAddress | |
69 | if z is 0 then | |
70 | return {emailAddress, emailAddress} | |
71 | else | |
72 | set senderName to text 1 thru (z - 1) of emailAddress | |
73 | return {senderName, emailAddress} | |
74 | end if | |
75 | else | |
76 | set y to the offset of ">" in messageSenderData | |
77 | if y is 0 then | |
78 | set senderName to messageSenderData | |
79 | else | |
80 | if x is 1 then | |
81 | set senderName to "unknown" | |
82 | else | |
83 | set senderName to text 1 thru (x - 1) of messageSenderData | |
84 | set senderName to my trimWhiteSpaceAroundString(senderName) | |
85 | end if | |
86 | end if | |
87 | end if | |
88 | set emailAddress to text from (x + 1) to (y - 1) of messageSenderData | |
89 | return {senderName, emailAddress} | |
90 | end extractSenderDataFromSenderObject | |
91 | ||
92 | on trimWhiteSpaceAroundString(thisString) | |
93 | set theString to current application's NSString's stringWithString:thisString | |
94 | set theWhiteSet to current application's NSCharacterSet's whitespaceAndNewlineCharacterSet() | |
95 | set theString to theString's stringByTrimmingCharactersInSet:theWhiteSet | |
96 | return theString as text | |
97 | end trimWhiteSpaceAroundString |