微信 AppleScript 自动化:从入门到实战
一、问题
微信群管理的三大痛点:
– 消息太多:每天几百条群消息,看不过来
– 重复劳动:相同问题回复100遍
– 误发风险:手动操作容易发错群
核心疑问:如何用 AppleScript 自动化微信操作?
二、方案
AppleScript 自动化的三大能力:
1. 消息监控:自动检测新消息
2. 智能回复:关键词触发自动回复
3. 批量操作:一键删除、转发、导出
生活比喻:
– 手动管理:像人工客服,累且慢
– AppleScript:像聊天机器人,24小时在线
三、快速开始
3.1 环境准备
系统要求:
– macOS 10.14+
– 微信 Mac 版 3.0+
– 开启辅助功能权限
权限设置:
# 系统偏好设置 → 安全性与隐私 → 辅助功能
# 添加:脚本编辑器、终端
3.2 第一个脚本
目标:自动打开微信并发送消息
-- 打开微信
tell application "WeChat"
activate
delay 2
end tell
-- 模拟点击
tell application "System Events"
tell process "WeChat"
-- 点击搜索框
click text field 1 of group 1 of window 1
-- 输入联系人名称
keystroke "文件传输助手"
delay 1
keystroke return
-- 输入消息
keystroke "Hello from AppleScript!"
keystroke return
end tell
end tell
四、核心技术
4.1 UI 元素定位
问题:如何找到”发送按钮”在哪?
工具:Accessibility Inspector
# 打开工具
/System/Library/CoreServices/Applications/Accessibility\ Inspector.app
步骤:
1. 打开 Accessibility Inspector
2. 点击”锁定”按钮
3. 鼠标悬停在微信界面元素上
4. 查看元素属性(role、title、position)
示例:
-- 定位发送按钮
tell application "System Events"
tell process "WeChat"
-- 方法1:通过 role 和 title
click button "发送" of group 1 of window 1
-- 方法2:通过坐标
click at {800, 600}
end tell
end tell
4.2 动态获取群名
问题:硬编码群名会导致消息发错群
解决方案:动态扫描未读消息
-- 获取当前聊天窗口名称
tell application "System Events"
tell process "WeChat"
set chatName to value of static text 1 of group 1 of window 1
return chatName
end tell
end tell
完整流程:
-- 1. 扫描未读消息
tell application "System Events"
tell process "WeChat"
-- 获取聊天列表
set chatList to rows of table 1 of scroll area 1 of group 1 of window 1
repeat with chatRow in chatList
-- 检查是否有未读标记
set hasUnread to exists (UI element 1 of chatRow whose description contains "unread")
if hasUnread then
-- 点击进入聊天
click chatRow
delay 0.5
-- 获取群名
set groupName to value of static text 1 of group 1 of window 1
-- 处理消息
my processMessages(groupName)
end if
end repeat
end tell
end tell
-- 2. 处理消息函数
on processMessages(groupName)
-- 读取最新消息
-- 判断关键词
-- 自动回复
end processMessages
4.3 替换固定延迟
问题:delay 2 不稳定,网络慢时会失败
解决方案:条件等待
-- 坏代码:固定延迟
click button "发送"
delay 2 -- 可能太短或太长
-- 好代码:等待元素出现
on waitForElement(elementRef, timeout)
set startTime to current date
repeat
try
if exists elementRef then
return true
end if
end try
if (current date) - startTime > timeout then
return false
end if
delay 0.1
end repeat
end waitForElement
-- 使用
set sendButton to button "发送" of group 1 of window 1
if waitForElement(sendButton, 5) then
click sendButton
end if
五、实战案例
5.1 自动回复机器人
功能:检测关键词,自动回复
-- 主循环
repeat
-- 获取最新消息
set latestMessage to my getLatestMessage()
-- 判断关键词
if latestMessage contains "价格" then
my sendReply("产品价格请查看:https://example.com/price")
else if latestMessage contains "客服" then
my sendReply("人工客服工作时间:9:00-18:00")
end if
delay 1
end repeat
-- 获取最新消息
on getLatestMessage()
tell application "System Events"
tell process "WeChat"
set messageList to UI elements of group 2 of window 1
set lastMessage to item -1 of messageList
return value of static text 1 of lastMessage
end tell
end tell
end getLatestMessage
-- 发送回复
on sendReply(replyText)
tell application "System Events"
tell process "WeChat"
-- 点击输入框
click text area 1 of group 3 of window 1
-- 输入文本
keystroke replyText
-- 发送
keystroke return
end tell
end tell
end sendReply
5.2 批量删除消息
功能:删除包含特定关键词的消息
on deleteMessagesWithKeyword(keyword)
tell application "System Events"
tell process "WeChat"
set messageList to UI elements of group 2 of window 1
repeat with msg in messageList
try
set msgText to value of static text 1 of msg
if msgText contains keyword then
-- 右键点击
perform action "AXShowMenu" of msg
delay 0.2
-- 点击"删除"
click menu item "删除" of menu 1
delay 0.2
-- 确认删除
click button "删除" of window 1
end if
end try
end repeat
end tell
end tell
end deleteMessagesWithKeyword
-- 使用
deleteMessagesWithKeyword("广告")
5.3 定时发送消息
功能:每天早上9点发送问候
-- 保存为 ~/Library/LaunchAgents/com.wechat.morning.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.wechat.morning</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/osascript</string>
<string>/path/to/morning_greeting.scpt</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>9</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
加载定时任务:
launchctl load ~/Library/LaunchAgents/com.wechat.morning.plist
六、优化策略
6.1 错误处理
问题:脚本遇到异常就崩溃
解决方案:try-catch 包裹
on safeClick(elementRef)
try
click elementRef
return true
on error errMsg
log "点击失败: " & errMsg
return false
end try
end safeClick
6.2 日志记录
问题:出错不知道哪里有问题
解决方案:详细日志
on logMessage(msg)
set logFile to (path to desktop as text) & "wechat_bot.log"
set timestamp to (current date) as text
set logEntry to timestamp & " - " & msg & return
try
set fileRef to open for access file logFile with write permission
write logEntry to fileRef starting at eof
close access fileRef
on error
close access file logFile
end try
end logMessage
-- 使用
logMessage("开始处理消息")
6.3 配置管理
问题:硬编码参数难以维护
解决方案:外部配置文件
-- config.json
{
"bot_name": "小助手",
"reply_delay": 1,
"keywords": {
"价格": "产品价格请查看官网",
"客服": "人工客服9:00-18:00在线"
}
}
-- 读取配置
on loadConfig()
set configPath to (path to desktop as text) & "config.json"
set configJSON to read file configPath
return do shell script "echo " & quoted form of configJSON & " | python3 -m json.tool"
end loadConfig
七、常见问题
7.1 权限被拒绝
错误:System Events got an error: osascript is not allowed assistive access
解决:
1. 系统偏好设置 → 安全性与隐私 → 辅助功能
2. 添加”脚本编辑器”和”终端”
3. 重启脚本
7.2 元素找不到
错误:Can't get button "发送" of group 1
解决:
1. 用 Accessibility Inspector 重新定位
2. 检查微信版本是否更新
3. 增加 delay 等待界面加载
7.3 消息发错群
原因:硬编码群名,群名变化导致错误
解决:动态获取当前窗口名称,发送前二次确认
on sendMessageSafely(targetGroup, message)
-- 获取当前群名
set currentGroup to my getCurrentGroupName()
-- 二次确认
if currentGroup is not targetGroup then
display dialog "警告:当前群名不匹配!" & return & ¬
"目标群:" & targetGroup & return & ¬
"当前群:" & currentGroup
return false
end if
-- 发送消息
keystroke message
keystroke return
return true
end sendMessageSafely
八、小结
核心要点:
1. AppleScript 通过 System Events 控制微信 UI
2. 用 Accessibility Inspector 定位元素
3. 动态获取群名,避免消息发错
4. 条件等待替代固定延迟,提升稳定性
技术栈:
– AppleScript:UI 自动化
– System Events:模拟鼠标键盘
– Accessibility Inspector:元素定位
– LaunchAgent:定时任务
适用场景:
– ✅ 群消息自动回复
– ✅ 批量删除广告消息
– ✅ 定时发送通知
– ❌ 大规模营销(违反微信规则)
参考资料:
– Apple AppleScript 官方文档
– Accessibility Inspector 使用指南
– 微信 Mac 版 UI 结构分析






程序员数学扫盲课
AI周刊:大模型、智能体与产业动态追踪
Claude Code 全体系指南:AI 编程智能体实战
Karpathy神经网络零基础课程
最新评论
开源的AI对话监控面板很实用,正好团队在找这类工具。准备试用一下。
折叠屏市场确实在升温,不过售罄也可能是备货策略。期待看到实际销量数据。
从磁盘I/O角度解释B树的设计动机,这个切入点很好。终于理解为什么数据库不用二叉树了。
IT术语转换确实是个痛点,之前用搜狗总是把技术词汇转成奇怪的词。智谱这个方向值得期待。
这个工具结合LLM和搜索API的思路很有意思,正好解决了我在做知识管理时遇到的问题。请问有没有部署文档?
这个漏洞确实严重,我们团队上周刚遇到类似问题。建议补充一下如何检测现有项目是否受影响的方法。
从简单规则涌现复杂性这个思路很有意思,让我想起元胞自动机。不过数字物理学在学术界争议还挺大的。
我也遇到了指令跟随变差的问题,特别是多轮对话时容易跑偏。不知道是模型退化还是负载优化导致的。