AI编程 · 架构思考 · 技术人生

微信 AppleScript 自动化:从入门到实战

智谱 GLM,支持多语言、多任务推理。从写作到代码生成,从搜索到知识问答,AI 生产力的中国解法。

微信 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 结构分析

赞(0)
未经允许不得转载:Toy's Tech Notes » 微信 AppleScript 自动化:从入门到实战
免费、开放、可编程的智能路由方案,让你的服务随时随地在线。

评论 抢沙发

十年稳如初 — LocVPS,用时间证明实力

10+ 年老牌云主机服务商,全球机房覆盖,性能稳定、价格厚道。

老品牌,更懂稳定的价值你的第一台云服务器,从 LocVPS 开始