背景:这段时间某位同事须要频繁登陆个人帐号,而且要验证手机验证码,每次都须要我手动将验证码转发给他,以为很是的麻烦,便想看一下有没有什么可以解放双手的办法,而后发现了
AppleScript
这么一个很是好用的东西 :)html
AppleScript
,那么一台MAC电脑天然是不可少的(macOS Catalina 10.15.5)AppleScript是用来编写运行于mac的脚本的,而且可以操做应用程序。苹果官方也要求开发mac上的软件须要留出可以共AppleScript可以操做的方法。利用AppleScript咱们能很是方便实现一些日常工做中重复工做的脚本化,提高工做效率,避免重复劳动。sql
AppleScript 的语法很是接近天然语言,几乎没有标点符号,语法不像其余语言那样严格chrome
-- 将百度网址赋值给变量url_str set url_str to "https://www.baidu.com"
-- 将百度网址赋值给变量url_str set url_str to "https://www.baidu.com" -- 通知 display notification "url set success"
-- 将百度网址赋值给变量url_str set url_str to "https://www.baidu.com" -- 将bing网址赋值给变量url_str2 set url_str2 to "https://www.bing.com" -- 通知 display notification "url set success" -- 操做应用 tell application "Google Chrome" -- 建立新窗口 set newWin to make new window -- 获取新窗口tab set theTab to get active tab of newWin -- 操做tab tell theTab -- 设置tabURL set URL of theTab to url_str -- 访问 go forward -- 延迟3秒 delay 3 --从新设置tabURL set URL of theTab to url_str2 go forward end tell end tell
苹果官方会要求mac软件的开发提供可以操做应用软件的方法,能够经过字典查询可否由AppleScript操控软件数据库
Script Editer -> 打开词典 -> 选择想要操做的软件vim
chrome dictionary.
安全
了解 AppleScript 的基础语法是掌握 AppleScript 自动化的第一步,在对 AppleScript 有了必定的了解后,在往后发现本身有重复操做时,就能够先想一想能够如何经过 AppleScript 解决它app
回到正题,由于对AppleScript
有过必定了解,而且也作过简单的测试,因此第一时间想到的就是能不能用自动话脚原本处理重复的短信转发工做(在这以前还从没用AppleScript解决过现实问题)iphone
首先须要的就是打开字典,由于Message自己就是苹果开发的,因此确定会有丰富的API供咱们使用的ide
经过翻找,咱们可以基本定位咱们发送短信须要用到的send方法,send方法中还须要咱们明确一个buddy,继续查看buddy学习
查看咱们的buddy,他是包含在一个service里面的,继续service ...
service 上层为application包含,所以咱们能够书写咱们的脚本了
tell application "Messages" send "test" to buddy "+86199xxxx" of service "SMS" end tell
很是简单的一段代码,能够测试发送了。在测试的过程当中发现须要有和该号码发过消息的记录(即须要打开有一个窗口)
在可以成功发送短信后,咱们距离解放双手已经很近了,接下来咱们只须要在接收到验证码信息的时候,调用咱们的发送脚本将咱们收到的消息转发出去就大功告成了:)
继续查看咱们的字典,有一个message received
事件,看字面上的意思就能知足咱们的须要,就是他了
很简单,咱们只须要获取到咱们须要的消息,以及发送给咱们的人用来判断(毕竟不能把全部的消息都转发出去)
using terms from application "Messages" on message received theMessage from theBuddy -- 通知接收到消息 display notification "message" -- 将Message App可见 set visible of window "Messages" to true -- 将Message App置顶 set frontmost of window "Message" to true end message received end using terms from
事情到这里就结束了嘛?哪有那么简单,正所谓“天之道,没那么容易让你成功~”
通过不断的测试,发现这个脚本根本就没达到个人预期,没有通知也没有置顶,是我哪里写的有问题嘛?好嘛,知错要改,要虚心学习。百度~,嗯,查不到,害,谷歌~(我的习惯,先百度,当发现查不到想要的信息或者百度上全是同一篇文章抄来抄去的时候才谷歌,毕竟谷歌是不被容许,我但是乖孩子)
不断的变换关键词及描述,用个人散装英语终于找到了一些解决办法
发现个人脚本写的是没有问题的,只是还少一些操做步骤。例如
copy the script into a new AppleScript Editor document and save it in ~/Library/Application Scripts/com.apple.iChat/ Then activate it by selecting it in Messages -> Preferences -> General -> AppleScript Handler:
以及
AppleScript file copied to ~/Library/Scripts/Messages by Messages, it started to work.
不一样的路径,可是好像都须要拷贝,因而分别考到目录下,可是一直没有找到Message -> Preference —> General(发现个人MAC好像和广大网友不太同样啊,买到了假货了吧)总之仍是不成功,继续google...
终于,原来Message.app Message Received Event Handler
在macOS High Sierra 10.13.4
版本被移除,而且开通了Business Chat
emmmmmmm.....,害~
事件的方式走不通了,只能换一种方式了。还能够用什么方式呢,因而我想到了一种可能,个人这些消息,哪怕时间再久远都能查到,他是怎么存放的呢。
OK,有思路就有方向,最后不断的搜索发现是存在目录/Users/herbert/Library/Messages
下 的chat.db
文件中
用sqlite打开看一下
sqlite3 /Users/herbert/Library/Messages/chat.db
查看表结构及表内部分数据
.schema message select * from message order by ROWID desc limit 5;
最终根据梳理的表结构关系,及传入我须要查询的号码整理SQL
-- 查询一分钟内来自指定号码xxxxxx_number的短信 SELECT text, handle_id,date,datetime(date/1000000000 + strftime('%s','2001-01-01'), 'unixepoch', 'localtime') as date_utc FROM message T1 INNER JOIN chat_message_join T2 ON T1.ROWID=T2.message_id INNER JOIN chat T3 ON T2.chat_id=T3.ROWID AND T3.chat_identifier = 'xxxxxx_number' where datetime(date/1000000000 + strftime('%s','2001-01-01'), 'unixepoch', 'localtime') > datetime('now','localtime','-1 minute') ORDER BY T1.date;
在查询数据的时候还发现了一个不常见的日期存储(我以前没有见过)一个18位的时间数字
处理方式:
datetime(date/1000000000 + 978307200,'unixepoch','localtime')
.
datetime(date/1000000000+ strftime('%s','2001-01-01'),'unixepoch','localtime')
咱们已经拿到咱们须要的数据了,接下来就只须要每一个一分钟取一次数据,若是可以去到数据,那么调用咱们发送短信的脚本就OK了
编写脚本auto_forward.sh
#/bin/sh phone="+86xxxx" call_apple() { while read line do osascript /Users/herbert/Documents/AppleScript/ForwardMessage/SendMessage.scpt $line $phone done } export -f call_apple sqlite3 /Users/herbert/Library/Messages/chat.db '.read /Users/herbert/Documents/AppleScript/ForwardMessage/select.txt' | call_apple
将咱们的sql存在单独的文件里,方便修改select.txt
SELECT text FROM message T1 INNER JOIN chat_message_join T2 ON T1.ROWID=T2.message_id INNER JOIN chat T3 ON T2.chat_id=T3.ROWID AND T3.chat_identifier = 'from_number' where datetime(date/1000000000 + strftime('%s','2001-01-01'), 'unixepoch', 'localtime') > datetime('now','localtime','-1 minute') ORDER BY T1.date;
SendMessage.scpt
on run argv set msgContent to item 1 of argv set phone to item 2 of argv sendMsg(msgContent, phone) end run on sendMsg(msgContent, phone) tell application "Messages" send msgContent to buddy phone of service "SMS" end tell end sendMsg
万事具有,只须要加入crontab中就好了
crontab -e */1 * * * * sh /Users/herbert/Documents/AppleScript/ForwardMessage/auto_forward.sh
此处在测试的时候仍是没有达到预期,可是单独执行脚本的时候可以成功,推测是cron的问题,因而查看日志
vim /var/mail/herbert
果真发现问题
sh: /Users/herbert/Documents/test/demo.sh: Operation not permitted
此问题会在Mojave 10.14, Catalina 10.15 以及后续版本出现 解决方法:系统偏好设置 -> 安全性与隐私 -> 隐私 -> 彻底磁盘访问权限 -> 添加cron