开源短信转发器实战:从备用机验证码到Webhook自动化管道
如果你也经历过这种时刻——手机放在客厅充电人瘫在书房电脑前银行验证码“叮”一声落在手机上等你发现并走过去拿手机时验证码已经过了一分钟或者专门拿旧手机当备用机跑脚本、挂自动化可每当需要收验证码时还得低头去翻那个没有通知亮屏的老古董——那你大概率会在某些群里看到“短信转发器开源项目”这一串字。这个方向我前前后后折腾了小半年从直接用第三方转发软件到自己编规则、改源码、接内部系统中间踩了不少坑。这篇就把整个链路讲透包括短信转发器的原理、开源项目的选型思路、从零部署的完整步骤以及部署后真正容易翻车的几个环节。内容既适合第一次接触转发器的普通用户也适合想把短信接进自己自动化体系的开发者和发烧友。1. 需求不只是一个“转发”而是把短信变成可编程的输入源1.1 我踩过的真实场景备用机上的验证码永远慢半拍很多人第一次搜索“短信转发器”动机特别朴素想把手机 A 的短信转到手机 B 上。但真正用起来之后你会发现这个需求一旦展开比想象中大得多。最典型的场景是你有一台旧手机插着副卡平时专门用来收快递、注册账号、绑定服务商验证码。这台手机可能没有装任何社交软件甚至屏幕都懒得解锁。问题是等你要用某个账号登录时才意识到那条验证码还在旧手机里躺着而旧手机的屏幕在另一个房间甚至还开启了勿扰模式。另一个常见场景是自动化联动你在家里跑着群晖、跑着内网穿透、跑着一些无人值守的脚本这些服务偶尔需要短信验证码才能完成登录或者续期。人不可能天天盯着旧手机这时候短信转发器就不再是“通知同步工具”而是把短信这个最传统、最封闭的信息渠道转成一条可以程序化消费的数据流。说白一点你要的不是“把短信挪个地方显示”而是“让短信能够进入你的消息总线、脚本、服务端程序”。这也是为什么我建议在动手之前先想清楚自己的核心用途。如果只是想在电脑上看到验证码那任何一款能转发短信的 App 都够用如果你想把短信通过 Webhook 推到公司内部 IM、自动写入表格、在特定关键词触发某个脚本那从一开始就要选支持规则匹配和自定义请求的开源项目。1.2 软件转发和硬件 GSM 网关到底该选哪条路做短信转发业内其实有两条路线一条是软件派拿一台 Android 备用机装开源转发 App另一条是硬件派买 SIM900/GSM 模块配合单片机或者开发板把收到的短信转成串口数据或者 HTTP 请求。两条路我都试过先给结论除非你的使用场景是完全无人值守、功耗要求极低、并且对 Android 系统稳定性没有信心的嵌入式场景否则普通人和普通开发者都应该优先选软件方案。硬件方案的吸引人之处在于功耗低、体积小、可以 7x24 小时跑但真正做起来坑非常多。首先是 SIM 卡开机后的网络注册问题GSM 模块在信号不稳时经常掉网重新注册要十几秒其次中文字符集编码是一个长期痛点PDU 模式下中文短信解析一不小心就是乱码再者硬件方案的转发逻辑几乎要自己写规则过滤、去重、状态上报这些能力全部从零开始。相比之下软件方案的优势非常明显Android 系统本身已经帮你解决了短信解 PDU、中文编码、SIM 卡识别的问题开源转发器项目又在此基础上完成了规则引擎、转发通道、日志、远程指令等模块。你要做的只是提供一台能用 WiFi、能插 SIM 卡的旧手机。成本上一台旧的安卓机二手可能只要一两百块而且它不仅仅是短信转发器还可以兼职做内网穿透客户端、网络摄像头、离线下载器。硬件方案则基本只能专机专用。这个对比在文末进阶章节还会再展开这里先定个基调软件方案是绝大多数人的最佳起步点。2. 转发链路内部到底发生了什么2.1 一条短信到达 Android 时系统做了什么要真正理解短信转发器的工作原理得先知道 Android 系统收到短信时的内部流程。短信到达基带后系统会先把 PD 数据解码成标准的 SmsMessage然后由系统进程发出一条广播action 是android.provider.Telephony.SMS_RECEIVED。所有声明了接收这条广播、并且持有RECEIVE_SMS权限的应用都会在广播分发过程中被唤醒。这里有个很关键的细节从 Android 8.0 开始系统对隐式广播做了大量限制不过短信接收广播是一个例外因为它属于“系统发送的关键事件广播”系统会保证应用在接收短信时能够被短暂唤醒。所以短信转发的核心机制并不是 App 在后台一直轮询查短信而是事件驱动的平时 App 的进程可以休眠一条短信进来系统把进程唤醒App 在主线程之外解析短信内容然后执行你的转发规则。常见的开源转发器在这个阶段做的事情基本一致读取 SMSC短信中心、发件人号码、短信正文、时间戳然后把这些字段拼接成一条结构化数据。有些项目还会读取 SIM 卡索引用来区分双卡手机里到底是哪一张卡收到的短信。接下来就到了转发的核心逻辑是否转发、转发到什么渠道、按什么模板发送。需要说明的是正常开源项目不会使用READ_SMS去扫历史短信它只需要接收新短信即可但很多项目为了兼容部分机型的双卡识别或测试功能仍然会申请这个权限安装时你能在权限列表里看到。2.2 规则引擎与去重不是所有短信都值得转发很多人以为短信转发器就是把所有短信一股脑发出去恰恰相反做得好的项目一定有成体系的规则引擎。为什么因为备用机上的垃圾短信、运营商通知、快递取件码、银行营销短信这些噪音如果全部转发你很快会麻木最后连真正重要的验证码也被淹没在推送里。规则引擎一般包含三类能力。第一是关键词匹配支持正则表达式例如只把包含“验证码”“校验码”“动态码”的短信转出去第二是发件人白名单和黑名单可以精确到号码或按前缀模糊匹配第三是时间窗口比如深夜时段不转发非紧急短信。真正开源的优秀项目规则之间可以组合比如“发件人命中白名单 且 正文匹配正则 才转发”“黑名单或垃圾关键词命中则不转发”。去重是另一件容易被忽略的事。某些服务商会连续发两条内容完全相同的短信或者上游网管重复下发如果不做去重你的电脑端会收到两条一模一样的通知再触发脚本做一次重复操作麻烦就大了。实现原理不复杂维护一个以“发件人正文摘要短时窗口”为键的数据结构例如 60 秒内同号同内容只转发一次。别小看这个细节它直接决定转发链路是否“靠谱”。2.3 Webhook 是万能出口其他渠道都是它的特例短信转发器的出口五花八门企业微信机器人、钉钉机器人、Server酱、Bark、邮件、MQTT、自定义 HTTP 请求。乍一看很复杂但如果你看过项目源码就会发现这些所有渠道入口都做了同一件事把短信内容组装成一个 HTTP 请求往指定的接口发出去。所谓企业微信机器人本质就是往某个带 token 的 Webhook URL POST 一段 JSON所谓 Server酱本质就是往https://sctapi.ftqq.com/SendKey.send发一个 GET 或 POST 请求标题和正文放在参数里。理解了这一层你就能明白为什么“接入自己的系统”这件事没有想象中难。哪怕开源项目没内置你需要的渠道只需要看看它是否支持“自定义 Webhook/API 请求”支持的话你在接收端随便起一个 HTTP 服务就能把短信数据完整接进自己系统。这也是我在选型时最看重的一个能力。很多项目虽然没有丰富的渠道生态但只要自定义请求做得好它的扩展性就远超那些预置渠道多但不可定制的闭源工具。3. 开源方案横评为什么社区型 App 比脚本更适合大多数人3.1 主流方案的取舍对比我接触过的开源路线大致可以分为四类专业短信转发器 App、自动化工具脚本Tasker/MacroDroid 类、自写 Xposed/LSPosed 模块、以及从零自研接收端。这里列个表你一眼能看出差距。方案类型代表思路上手门槛规则能力渠道扩展性二次开发成本专业转发 AppSmsForwarder 等低装 APK 配权限即可强正则黑白名单时段中等取决于项目内置的渠道和 Webhook 支持中项目结构清晰但需看懂源码自动化脚本Tasker 事件触发中高需要理解任务流强但配置繁琐取决于你写脚本的能力高规则依赖活动场景迁移成本大系统模块自写 Xposed 模块高需要 root 和框架最强可以 Hook 短信入库由你的代码决定极高只在特殊的定制需求下才值得全自研自己写 App 监听短信高需熟悉 Android 开发全部自己实现全部自己实现极高不推荐第一版就这么干我个人的选择是专业转发 App具体项目名这里不恰饭了GitHub 上搜一下短信转发器挑 star 数量适中、最近一年还在更新的项目就行。我用的项目有这几个特点APK 可以直接从 Releases 下载不强制 root内置正则规则、Webhook 自定义请求、企业微信/钉钉/Server酱/Bark 这些常见渠道支持远程指令例如回短信、查询状态。这类项目最大的好处是普通用户零基础也能在半小时内跑起来等跑通之后想深度扩展再去读源码也不迟。3.2 怎么判断一个开源项目值不值得部署开源项目虽然免费但部署时间也是成本。选项目时我建议看三件事更新频率、issue 响应、以及作者对“离线运行”的态度。短信转发器涉及隐私数据如果项目强制要求登录云端账号才能使用基本可以直接排除。更新频率是一个重要信号。Android 系统每年都有行为变更比如 Android 13 引入的通知权限、Android 14 对前台服务类型的限制如果一个项目两三年没更新很可能在较新的手机上出现转发延迟甚至完全失效的情况。还要看作者对云端依赖的处理方式。优秀的项目应该把云端只当作可选的转发通道之一核心逻辑完全在本地运行即使没有网络也能把短信先缓存住等网络恢复再重放。这一点对于备用机常年在弱网环境的人特别重要。我自己选型时专门看了项目的 README 和 Wiki确认离线缓存、重试机制这些基础能力都有文档说明才决定部署。如果你在 GitHub 上看到一个项目代码写得不错但文档完全没有提及断网重连和缓存机制建议保持谨慎这类细节往往要等真实场景踩坑时才会暴露。4. 实操部署从 APK 到第一条转发成功4.1 准备一台“永远在线”的备用机硬件上任何能运行 Android 7.0 以上的手机都可以但有两个小建议。一是尽量选支持双卡且能区分卡槽的设备因为很多人的备用机插着副卡主卡在日常机里但偶尔也会把主卡放进备用机这时候能区分卡槽会让规则更精确。二是尽量选 ROM 干净、少广告的机型特别是国产手机那些系统级“省电精灵”“安全管家”对后台进程的管制非常激进会直接杀掉转发 App这个问题在第 5 章专门说。系统设置层面插好 SIM 卡后先把 WiFi 连上关闭系统自动休眠、关闭锁屏后的网络断开选项如果手机支持“默认 SMS 应用”的概念可以考虑把备用机设为默认短信应用虽然这不是必须的但部分机型在非默认状态下第三方应用接收广播会有延迟。另外说个容易被忽略的点取一张纸记录一下这台备用机的 IMEI 后几位和 SIM 卡 ICCID 后四位后面排查“是不是卡没信号”“是不是换过卡槽”这类问题时对账会特别方便。4.2 权限是转发链路的地基少一个都可能断安装 APK 后很多人的第一反应是打开 App 开始配规则然后第二天发现一条短信都没转出去。大概率是权限没给全。短信转发器需要的权限清单如下权限作用缺失后果接收短信RECEIVE_SMS接收新短信广播核心权限完全无法收到短信事件读取短信READ_SMS部分项目用于双卡识别与兼容双卡信息可能识别错乱通知使用权部分项目通过通知栏监听作为补充通道个别机型转发不可靠电池优化白名单避免系统深度休眠时进程被冻结转发延迟甚至中断自启动管理开机后自动拉起前台服务手机重启后转发服务不恢复悬浮窗/后台弹窗部分项目需要后台弹出界面和标记AI 拦截或后台限制导致被杀每个权限都有其存在的逻辑。电池优化白名单尤其重要Android 的 Doze 模式会在设备静止一段时间后进入深度休眠如果你的手机一直插着电放桌上系统很容易进入 Doze这时普通后台应用的网络请求和广播处理会被大幅延后。把转发 App 加入电池优化白名单本质是告诉系统“这个应用需要实时处理关键事件不要冻结它”。设置路径不同厂家差异很大但大致思路一致系统设置 → 应用 → 找到转发 App → 电池 → 不限制。同时进入手机管家类应用打开“自启动”开关并在“后台耗电管理”里选择允许后台运行。这一步一定要自己动手逐项排查别指望刷一次机或者装一个绿色守护就能搞定。4.3 多渠道出口配置企业微信机器人与 Server酱部署完权限接下来配置转发出口。这里用我们最经常用的两个渠道示例企业微信群机器人和 Server酱。企业微信机器人的设置方式在目标群里添加一个“群机器人”拿到 Webhook 地址形如https://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx。然后在转发器的“发送通道”里新建“企业微信应用消息”或“群机器人”项填入 Webhook 地址消息模板可以自定义提交后点击“测试”。测试成功的话群里会收到一条消息内容是转发的测试短信。注意企业微信机器人对消息内容和频率是有限制的每分钟最多 20 条日常个人使用足够但是如果你拿它跑一些高频率的物联网告警就会触发限流这时建议走自定义 Webhook 到自己后端自己做聚合和缓冲。Server酱是另一个思路特别适合一个人使用。去服务器酱官网用 GitHub 账号登录拿到一个 SendKey形如SCTxxxxxxxxxxxxxxxxxx然后在转发器里选择 Server酱通道填入 SendKey 保存。它的实现本质是 GET 或 POST 请求到https://sctapi.ftqq.com/SendKey.send把title和desp两个参数带上推送到你的微信。整个链路非常轻不用专门去搞服务器唯一要注意的是免费版的消息条数限制以及推送消息会走服务器酱的公共网关如果对隐私非常敏感建议用企业微信机器人或自建 Webhook。配置通道时消息模板里建议把“卡槽信息”“接收时间”“发件人”这些都带上。卡槽信息和时间这两个字段在排查问题时极其好用发件人即使你不是每条都关注也可以先保留着。实测下来模板字段越全后期回溯越省事。4.4 规则验证给自己发一条测试短信转发通道配置完成之后不要急着把手机放到角落。我强烈建议花十分钟做一轮完整的规则测试。先创建一条规则关键词设置为“验证码”正则建议写成这样[验证码校验码动态码]?\s*[:为是]?\s*[0-9]{4,8}这条正则的意思是在短信正文里寻找“验证码”“校验码”“动态码”这类词允许后面跟着冒号、中文冒号、“为”“是”等分隔字符再匹配 4 到 8 位数字。它覆盖了“验证码123456”“您的验证码为 123456”“动态码1234”这些常见写法。然后拿另一台手机或直接用运营商发给自己的测试短信试一下。有些转发器 App 自带“模拟短信”功能可以直接在 App 里伪造一条短信事件来验证规则是否命中这比自己真发一条更省事。测试通过之后再做一次“负向测试”给自己发一条没有关键词的普通短信确认它不会被转发。这一步很多人会跳过但漏报和误报是两种完全不同的烦恼负向测试能确保你不会被垃圾短信轰炸。至此一条完整链路正式跑通短信到达备用机 → 广播唤醒转发 App → 规则命中 → 组装消息 → 推送到你的电脑端或手机端。5. 部署后最容易翻车的四个环节与排查链路5.1 转发链路的存活问题后台被杀、省电策略与 Doze运行几天之后你收到的第一条“真实告警”往往是一条验证码短信已经到备用机了但电脑端迟迟没有收到推送。这时候不要急着怀疑转发器坏了按照下面的链路逐步排查。先看发送端打开备用机上的转发 App查看日志。绝大多数专业化转发器都有日志功能一条短信从收到到转发的每个环节都会记录。如果日志里完全没有这条短信的记录说明应用根本没被唤醒问题出在系统后台限制检查是否被加进了电池优化白名单、自启动是否打开、以及手机管家里有没有把接收 SMS 广播的这个应用进程标记为“不活跃”。如果日志显示已经触发转发但网络请求失败检查备用机当前是否连接了 WiFi、系统有没有停用后台网络访问。部分国产 ROM 在锁屏后会限制应用的网络权限需要在“网络权限管理”里手动允许该应用始终联网。另外也值得检查备用机的日期时间是否准确因为很多 HTTP 接口会校验请求时间戳。如果日志显示请求发出去了但电脑端没有收到推送那问题大概率出在转发通道上。企业微信机器人换一个 key、Server酱是否欠费、Webhook 地址里的参数是否被模板变量污染了逐个测一遍就能定位。实话说90% 的“转发不成功”都是由后台限制和权限缺失造成的而不是应用自身的 bug。5.2 双卡手机只转发主卡短信的问题双卡手机的短信转发有一个经典问题有的开源项目在旧版本里只读取 SIM 卡 0 的短信或者因为某个机型的数据绑定实现不完善副卡短信到了却拿不到正确的卡槽信息导致规则误判为“非目标卡”而放弃转发。排查这个问题的思路有两个方向。一是确认项目是否支持“按 SIM 卡过滤”。如果是打开开关并明确指定要监听的卡槽如果项目没有这个功能就需要检查它是否有获取 SubscriptionInfo 的新版本。Android 5.1 之后有SubscriptionManager可以拿到卡的订阅信息但部分厂商定制系统返回的数据不准确所以兼容性很依赖项目在 issue 区积累的修复。第二个方向是管理预期如果手机系统和 App 版本都比较老别硬抗直接换一台系统版本新一点的备用机或者把副卡放到一个单独的转发器实例里跑。这里补充一点实践经验我最终为双卡场景配了两台备用机每台机只插一张卡转发规则不再区分卡槽系统复杂度骤减。虽然多占一个插座但稳定性提升非常明显。5.3 正则过宽导致“通知轰炸”正则表达式是规则引擎里最容易出问题的环节。写过的人应该都有体会刚开始写得很宽比如匹配“码”字结果把“取件码”“二维码”“邀请码”全部命中了写得特别窄比如只匹配“验证码”结果漏掉了“动态码”“校验码”。我的建议是维护两组正则列表一组是“必转规则”如果正文命中任意一条必然转发另一组是“排除规则”如果正文命中即使前面命中了必转规则也不转发。例如排除规则可以写成退订|回复TD|续费|营销|广告这样快递取件码、营销短信就不会被当成验证码转发。正则规则库是在使用中不断生长的别想着一次写到完美。建议每遇到一种误报或漏报就在手机上记一行日志一个月下来再回看基本能覆盖到 95% 的场景。另外不要在正则里写死短信开头的固定文本因为不少服务商会在验证码前后加括号、角标、或者“【XX银行】如果你没有操作可忽略”之类的内容。5.4 偶发延迟的排查顺序如果转发功能总体正常但偶尔隔了 5 到 10 分钟才收到推送这种情况最磨人。不要直接去怀疑服务器先按照下面的顺序排查第一步看备用机是否进入低电量模式。低电量模式下系统会强制推迟后台任务即使应用在白名单里也可能有延迟。第二步看 WiFi 是否休眠。部分手机在息屏一段时间后会断开 WiFi可以用路由器后台检查备用机的在线时长。第三步检查转发器是否有缓存重试机制。如果配置的 Webhook 接收端偶尔超时好的转发器会自动重试重试间隔越长感知延迟越大。第四步检查接收端本身是否有冷启动时间。例如用 Server酱时服务器可能因为上次访问后进入了休眠状态第一次请求需要冷启动加上 DNS 解析和 TLS 握手延迟就是这么一点点攒出来的。如果以上都排查过了仍然有偶发延迟最终方案是给备用机加一条“每周自动重启”的计划任务同时开启转发器的保活守护。旧手机长期运行后系统缓存堆积某些系统服务会异常重启能解决大部分莫名问题。每周重启一次对备用机这类专用设备来说几乎无感但转发链路的稳定性会显著提升。6. 从转发工具到私有数据管道二次开发与长期维护6.1 自己写一个 Webhook 接收端三十行代码接入内部系统当你不满足于“收到验证码只看一眼”而是想让短信直接驱动业务流程时就该走到自定义 Webhook 这一步了。开源转发器把短信推到你指定的 URL你在这个 URL 背后做任何事都由你自己决定。这里给一个最简单可用的接收端示例使用 Flask把接收到的短信持久化到文件同时如果短信是验证码就调用内部的告警接口。示例代码可以直接跑from flask import Flask, request, jsonify import json import re import requests app Flask(__name__) TOKEN your-secret-token SMS_LOG /var/log/sms_forwarder.log app.route(/sms, methods[POST]) def handle_sms(): if request.headers.get(X-Forward-Token) ! TOKEN: return jsonify({error: unauthorized}), 401 data request.get_json(); sender data.get(sender, ) body data.get(body, ) slot data.get(slot, 0) received_at data.get(time, ) with open(SMS_LOG, a, encodingutf-8) as f: f.write(json.dumps({sender: sender, body: body, slot: slot, time: received_at}, ensure_asciiFalse) \n) if re.search(r验证码|校验码|动态码, body): requests.post( https://internal-alert.example.com/notify, json{type: sms_code, sender: sender, body: body}, timeout5 ) return jsonify({ok: True}) if __name__ __main__: app.run(host0.0.0.0, port8080)这个 Flask 服务做了三件事鉴权、记录日志、识别验证码后触发内部告警。把代码部署在你有公网访问能力的服务器上或者在局域网内用内网穿透暴露出来然后在转发器里配置自定义 Webhook地址填http://你的地址:8080/sms再加一个自定义 HeaderX-Forward-Token: your-secret-token整个私有短信通道就跑通了。把日志文件夹接入统一日志系统或者用 cron 定期分析统计短信就不再是孤岛了。6.2 安全边界不能省token、HTTPS 与日志脱敏短信内容天然包含隐私验证码、快递信息、银行营销短信随便哪一条泄露出去都是麻烦。自定义 Webhook 暴露在公网上时安全问题必修。首先token 鉴权是底线。转发器发出的每个请求必须带一个随机生成的 header 字段接收端校验这个字段校验失败直接拒绝。要注意token 不要放在 URL 查询参数里因为 URL 有可能会被网关或 Web 服务器记日志泄露风险比放在 header 里大得多。其次公网传输必须用 HTTPS。如果你没有域名的证书可以先用带 HTTPS 的内网穿透或反代。不要裸奔 HTTP短信内容是明文任何中间网络设备都能看到。不太建议直接在转发器里用 IP端口的方式裸奔哪怕是测试环境也建议用 Caddy/Nginx 套一层 TLS。最后是日志脱敏。保存短信日志时至少要过滤掉“验证码”后面的数字。我见过有人把验证码存进日志系统结果每次修改脚本、查询日志时都提示验证码不匹配排查半天才发现是自动化在跟自己打架。更稳妥的做法是日志里只保存发件人和短信摘要或者对验证码数字用正则替换成****真正需要验证码的即时消息走推送通道不在日志里留任何痕迹。6.3 长期运行的维护习惯到这里整个短信转发系统已经不是“一个安装在旧手机上的 App”而是一条持续运行的数据管道。既然是管道就有长期维护问题。分享几个我自己的习惯。第一给备用机加一个定时任务每周自动重启一次。旧手机内存小系统服务跑久了很容易产生内存碎片表现为转发延迟变长、日志写入变慢。每周重启对转发服务的影响几乎可以忽略但对稳定性的提升非常明显。第二定期检查电池温度。备用机长期插着充电器放着电池鼓包是最大的安全隐患。如果手机出现背部凸起或者电量下降异常立刻停止使用。有些项目支持在转发规则里加入“低电量报警”“高温报警”可以当作免费的温度监控用。第三版本升级不要追新。开源项目发新版本后先观察几天 issue 区如果大面积反馈转发异常就再等等但如果新版本修复了后台被杀、双卡识别这类关键问题或者跟随 Android 新版本权限适配那就要及时升级这类问题不修备用机迟早会出幺蛾子。我目前这套链路已经跑了接近两年旧手机 开源转发器 企业微信机器人 自建 Webhook 接收端。日常验证码秒到自动化脚本需要验证码的时候直接读接口旧手机只在每周重启和偶尔给家人发短信时才会被想起来。短信转发器的核心价值不在于它把短信从一个屏幕挪到另一个屏幕而在于它让“接收短信”这个动作真正变成了可以编排、可以过滤、可以对接程序的基础能力。你要做的就是从一台闲置手机开始把这条管道一点一点搭起来。