我用了你的
sqlite3
代码进行了一些小的调整,然后创建了这个AppleScript,它会生成一个提醒列表(在
提醒
应用程序)。唯一的缺点是,发件人显示为电话号码或iMessage地址,并且不会使用通讯簿“转换”为姓名。这可能通过以下方式实现
tell
命令到
联络
并对电话号码进行搜索,但目前这超出了这项特殊工作的范围。
do shell script (["sqlite3 -line ~/Library/Messages/chat.db ", ¬
"'SELECT MAX(date) lastMessageDate, h.id, text ", ¬
"FROM message m INNER JOIN handle h ON h.ROWID=m.handle_id ", ¬
"WHERE is_from_me = 0 GROUP BY h.ROWID' | egrep -io -e '\\w+ = .+'"] as text)
set query_response to result
set AppleScript's text item delimiters to "lastMessageDate = "
set query_response to rest of text items of query_response
-- Loop through the array organise each message
repeat with message in query_response
-- Split the array item up into its components
set [receivedOn, sentFrom, textContent] ¬
to [paragraph 1, ¬
text 6 thru -1 of paragraph 2, ¬
text 8 thru -1 of paragraph 3] of message
-- Convert ReceivedOn to a value representing
-- the number of days since 01/01/2001
set receivedOn to receivedOn / (1.0E+9 * 86400)
-- Convert ReceivedOn again to the date
-- corresponding to the number of days since
-- 01/01/2001, i.e. the date and time the message
-- was sent
set receivedOn to (date "Monday, 1 January 2001 at 00:00:00") + receivedOn * days
-- Make a reminder
tell application "Reminders"
if not (exists (list named "Awaiting My Reply")) then ¬
make new list with properties {name:"Awaiting My Reply"}
tell list named "Awaiting My Reply"
-- This creates a reminder with a past due date
-- meaning you can sort the reminder list by due
-- date to see who has been waiting longest
-- for you to reply
make new reminder with properties ¬
{name:"Reply To " & sentFrom, body:¬
textContent, due date:¬
receivedOn} ¬
end tell
end tell
end repeat
当然,如果您的任何文本消息碰巧包含短语“lastMessagedate=”,那么上面的脚本将无法正常工作。然而,这有一些变通方法,我尝试了
sqlite3
包括…在内
列表
,
柱
和
csv
,所有这些都有各自的优点和缺点。
附录:从匹配的电话号码中检索联系人详细信息
经过多次实验,我成功地将上述脚本与通讯簿搜索集成,以将电话号码替换为联系人姓名:
-- Replace dbID with your address book's serial number
-- (look in ~/Library/Application Support/AddressBook/Sources)
property dbID : "377FDA5C-013A-430A-A964-9943C0B40137"
property db : {Messages:"/Users/CK/Library/Messages/chat.db", Addresses:"/Users/CK/Library/Application Support/AddressBook/Sources/" & dbID & "/AddressBook-v22.abcddb"}
-- Run an SQL query on the messages database via shell script
set Messages to do shell script (["sqlite3 -line ", ¬
quoted form of (Messages in db) as text, ¬
" 'SELECT MAX(date) lastMessageDate, h.id, text", ¬
" FROM message m INNER JOIN handle h ON h.ROWID=m.handle_id", ¬
" WHERE is_from_me = 0 GROUP BY h.ROWID'", ¬
" | egrep -io -e '\\w+ = .+'"] as text)
--> lastMessageDate = %timestamp%
--> id = %phone number or iMessage address%
--> text = %message content%
--> ...
set PhoneNumbers to do shell script (["sqlite3 -list -separator : ", ¬
quoted form of (Addresses in db) as text, ¬
" 'select r.ZFIRSTNAME, r.ZLASTNAME, p.ZFULLNUMBER", ¬
" from ZABCDRECORD as r, ZABCDPHONENUMBER as p", ¬
" WHERE p.ZOWNER=r.Z_PK'", ¬
" | tr -c -d '[:alnum:]:[:cntrl:]:[:space:]:+
--> %first name%:%last name:%phone number%
--> ...
set NamesAndNumbers to paragraphs of PhoneNumbers
set AppleScript's text item delimiters to ":"
tell NamesAndNumbers to ¬
repeat with n from 1 to count it
set its item n to ¬
{firstname:text item 1, lastname:text item 2, phone:text item 3} ¬
of its item n
end repeat
-- Groups all messages into a single item of an array
-- Each occurence of "lastMessageDate = " indicates
-- a new message and, hence, a new array item.
set AppleScript's text item delimiters to "lastMessageDate = "
set Messages to rest of text items of Messages
-- Loop through the array organise each message
repeat with message in Messages
-- Split the array item up into its components
set [receivedOn, sentFrom, textContent] ¬
to [paragraph 1, ¬
text 6 thru -1 of paragraph 2, ¬
text 8 thru -1 of paragraph 3] of message
-- Convert ReceivedOn to a value representing
-- the number of days since 01/01/2001
set receivedOn to receivedOn / (1.0E+9 * 86400)
-- Convert ReceivedOn again to the date
-- corresponding to the number of days since
-- 01/01/2001, i.e. the date and time the message
-- was sent
set receivedOn to (date "Monday, 1 January 2001 at 00:00:00") + receivedOn * days
-- Keep the "+" delimiter but replace the "+44" with
-- your own country's intl dialling code, e.g. {"+1", "+"}
-- as this may or may not prefix a phone number
set AppleScript's text item delimiters to {"+44", "+"}
set sentFrom to last text item of sentFrom
-- Find the name to whom the phone number belongs
ignoring white space
set match to ""
repeat with person in NamesAndNumbers
if the person's phone contains sentFrom then
set match to contents of the person
exit repeat
end if
end repeat
end ignoring
set AppleScript's text item delimiters to space
if match is not "" then set sentFrom to the contents of ¬
{firstname, lastname} of match as text
-- Make a reminder
tell application "Reminders"
if not (exists (list named "Awaiting My Reply")) then ¬
make new list with properties {name:"Awaiting My Reply"}
tell list named "Awaiting My Reply"
-- This creates a reminder with a past due date
-- meaning you can sort the reminder list by due
-- date to see who has been waiting longest
-- for you to reply
make new reminder with properties ¬
{name:"Reply To " & sentFrom, body:¬
textContent, due date:¬
receivedOn} ¬
end tell
end tell
end repeat