开源短信转发器自制指南:4G Cat.1模组从AT指令到通知栏
发布时间:2026/9/29 4:25:20来源:尧图网络
刚躺下准备睡觉手机却响了——不是电话是短信。你睡眼蒙眬地爬起来摸到床头柜里的备用机屏幕亮了“您的登录验证码是……”这样的场景在我家重复了无数次直到我动手做了一套开源短信转发器才算彻底解脱。今天这篇不聊概念直接上干货一套从硬件选型、串口调AT指令、再到把短信推到手机通知栏的完整开源自制方案。如果你手里有两张以上的SIM卡、有一台吃灰的旧手机或者正在做物联网项目想收设备告警短信这篇文章都能帮你省不少事。短信转发器和“开源”这两个词放在一起热度确实一直不低——GitHub上搜 sms forwarder 能看到一堆项目但实际能落地、能长期稳定跑的并没有那么多。我自己折腾了一个多月踩了不少坑最后用一块不到六十块钱的4G Cat.1模组把整条链路跑通了。下面就把整个过程掰开揉碎讲给你听。1. 短信转发器到底解决什么问题1.1 多卡党的真实痛点先说说我的生活状况主力机一张卡工作机一张卡老家还有一台旧手机插着家里宽带送的流量卡专门用来收各类网站和银行验证码。问题在于人常常坐在办公室旧手机在老家抽屉里震动短信来了根本看不见。真到要用验证码的时候只能打电话让家里人凑到屏幕前一条条念一来一回急得跳脚。后来我又试过把卡装到主力机的双卡槽里但主力机一天被各种App通知轰炸验证码混在一堆推送里反而更容易漏掉。短信转发器的本质就是把“短信来了”这个事件从一个不在你当前手上的SIM卡通过网络转发到你正在看的手机上。它解决的从来不是“短信能不能收到”的问题而是“短信到了你却没看到”的信息差问题。这个信息差在现实里非常致命——验证码半小时过期、银行动账通知晚看到几分钟、快递取件码隔天才发现……这些都让我觉得值得专门搭一套系统。1.2 为什么必须开源自制你可能会说淘宝上也有现成的短信转发硬件一百多块一个插上SIM卡就能用何必自己折腾这话没毛病但我想聊聊背后的账。商用短信猫一台便宜的也要两三百功能单一多数还只支持2G的SIM800方案遇到运营商逐步关停2G网络就废了。云转发SaaS按月订阅一年下来也够买几块开发板了而且短信内容要经过别人的服务器心里总不踏实。开源自制的方案硬件加软件全部自己可控成本算下来差不多是商用方案的零头代码能审日志能查想加过滤规则随时改。更重要的是一套短信转发器本质上就是一个常驻运行的嵌入式系统。你亲手从AT指令开始把短信读出来并推到手机这个过程中学到的东西远比“买一个成品”多得多。对我这种做嵌入式相关的开发者来说这种“知其所以然”的掌控感比省下的那几百块钱更有价值。1.3 这套方案适合谁先说清楚这套方案不是给所有人都准备的。如果你是只想收验证码、不想碰任何代码的人直接装个Android端的开源App比如GitHub上star很多的SmsForwarder会更省事。但如果属于下面这几类人我强烈建议往下看手上有多张SIM卡且环境里有一个能7x24小时运行的树莓派、NUC或旧电脑。在做IoT项目设备告警需要通过短信发送到运维手机又不想依赖云厂商的短消息服务。想学习GSM模块、AT指令、串口通信用一个小而完整的项目练手。手里有一块吃灰的ESP32或STM32开发板想让它发挥点实际作用。我最终选定的路线是“4G Cat.1模组 轻量服务器转发”这套组合兼顾了成本、功耗和可控性。下面我会把每一层设计的原因都讲清楚这样你复现的时候不会只知其然。2. 一条短信从SIM卡到通知栏经历了什么2.1 整体链路设计在设计之前先把整条链路画清楚。短信从空中飞到你手机界面上中间一共四步SIM卡驻网并接收短信 → 通信模组通过串口把短信原始数据吐出来 → 上位机树莓派/开发板/服务器解析并执行过滤规则 → 通过HTTP/MQTT等通道推送到你的目标手机。每一步都有它的坑但逻辑本身非常朴素。我见过不少人一上来就对着串口读AT指令结果读到的全是乱码问题往往不是代码而是卡在SIM卡没驻网或者天线没接好这种最基础的地方。所以我把整条链路的顺序理清楚按顺序排查会省很多时间。在设计转发通道时我一开始还考虑过直接用邮件推送、用Telegram bot推送等方案后来发现无论是可达性还是排查成本都不如国内常用的Bark、企业微信机器人、Server酱来得直接。转发通道不是越高大上越好越简单、越不容易断的才是好通道。2.2 三套主流硬件方案怎么选后来我在社群里问了一圈发现大家做短信转发器基本是三条路线各有各的适用场景方案核心硬件优点缺点适合谁手机端App方案闲置安卓手机成本几乎为0已有开源App可直接用旧手机电池容易鼓包且需长期保持联网家里正好有旧手机、不想碰硬件的用户树莓派模组方案树莓派/香橙派 4G模组性能充裕方便跑Python脚本和数据库功耗高整套放弱电箱需额外配电源有服务器运维基础、追求全掌控的玩家MCU直连方案ESP32/单片机 Cat.1模组功耗低、体积小、成本最低调试门槛高模组固件和串口问题都得自己处理嵌入式开发者、动手能力强的人我自己的选择是第三种变体用合宙Air724UG开发板它不是纯MCU而是模组自带LuatOS系统可以直接跑脚本同时保留了串口AT指令模式。好处是我不需要单独准备单片机一块板子就完成了“读短信走网络”两个功能。如果你手头有树莓派Zero那第二种方案也很舒服逻辑完全一致。这里插一句个人经验千万别一上来就买最便宜的老款2G模块SIM800系列淘宝一搜一大把。虽然便宜到十几块钱但国内2G退网是大趋势很多城市弱覆盖已经很严重放在家里根本收不到信号。一步到位选Cat.1模块支持移动/联通/电信4G多花的二三十块钱非常值。2.3 转发通道Bark、企业微信机器人还是MQTT短信内容解析出来之后要通过某个通道送到你手上。我试过三种给你对比一下BarkiOS端的一个开源推送App用起来最清爽。往一个URL发GET请求手机就会弹出通知还支持设置分组和自动复制。缺点是仅限iPhone。企业微信群机器人通过Webhook往群里发一条文本手机装个企业微信就能实时收到Android和iOS都没问题。缺点是会在你所有的企业微信里刷屏适合单独建一个家庭群。MQTT最硬核但最通用。你需要一个MQTT Broker比如云服务器上docker起一个EMQX手机端装MQTT客户端订阅主题。优点是消息不经过任何第三方平台完全私有化而且可以和其他IoT设备联动。我的建议是如果你是苹果用户直接上Bark五分钟跑通如果你用安卓且不想折腾企业微信机器人最稳如果你有其他智能家居或自动化需求那就走MQTT一次配好以后复用。文章后面我给的示例代码会同时兼容这三种方式你按自己的情况换一行地址就行。3. 实操用一块4G模组把转发器从0搭出来3.1 硬件清单与接线动手之前先把东西备齐。我用的是合宙Air724UG开发板之所以选它除了价格便宜之外还有一个重要原因板子自带SIM卡座、天线接口、USB转串口插上电脑就能当调试板用不用自己飞线。如果你用其他模组注意确认是否带SIM卡座和串口电平转换。需要准备的清单Air724UG开发板或任何支持Cat.1的4G模组开发板一块板子即可模组本身几十块钱。一张能正常收发短信的SIM卡建议用自己主力号之外的备用卡欠费停机那就什么都没戏。USB数据线一根用于供电和串口调试。杜邦线几根。虽然板载接口够用但如果你想把天线引到弱电箱外最好准备一根延长线。电脑上装好Python环境以及pyserial库pip install pyserial。接线方面Air724UG比较省事插上SIM卡、拧上天线、连USB线就行。如果你用的是树莓派独立模组的方案接线也很固定模组的TX接树莓派的RX模组的RX接树莓派的TXGND必须共地否则串口通信会不稳定。这里我不厌其烦地强调一句共地是几乎所有串口通信问题的根源先查地线再查代码。3.2 核心代码用AT指令把短信读出来模组上电后第一步是和它建立通信靠的是AT指令。这可能是整个方案里最劝退新手的环节但拆开看其实就三条命令ATCMGF1 把短信模式设置为文本模式不然你读到的是一堆PDU协议编码。ATCNMI2,1,0,0,0 开启新短信主动上报短信来时模组会主动往串口吐一条 CMTI 开头的通知。ATCMGR索引号 读取指定位置的短信内容。Python脚本的骨架大概是这样import serial import time ser serial.Serial(/dev/ttyUSB0, 115200, timeout2) # 初始化文本模式 新短信上报 ser.write(bATCMGF1\r\n) time.sleep(0.5) ser.write(bATCNMI2,1,0,0,0\r\n) time.sleep(0.5) while True: line ser.readline().decode(errorsignore).strip() if line.startswith(CMTI): # 例如CMTI: SM,4 _, _, index line.partition(,) ser.write((ATCMGR%s\r\n % index).encode()) time.sleep(0.2) # 接下来循环读取来拿完整短信这里有很多新手会犯的第一个错AT指令结尾一定要带 \r\n不是你平时按回车那种 \n 就行。很多模组只认回车少一个字节它就不理你表现就是串口一片安静。另一个常见问题是读串口时用了阻塞模式程序死等问题不大但在长跑场景里尽量给端口设置超时避免某根线异常时整个脚本挂掉。短信内容读出来后ATCMGR 的响应分两行第一行是发件人和时间第二行是正文。我一般只保留正文和发件人号码转发时可选择是否显示号码。短信正文之前有CMGR: REC READ,8613800138000,,23/01/12,10:30:0032这样的信息头解析的时候注意别把整段都转发过去不然通知栏会特别乱。3.3 发送逻辑短信内容怎么推到你手机短信内容解析出来之后接下来就是把它推出去。我同时实现了Bark和企业微信群机器人两种通道核心代码非常短import requests import urllib.parse def push_bark(title, body): # Bark的URL大概是 https://api.day.app/你的Key/标题/内容 url fhttps://api.day.app/YOUR_BARK_KEY/{urllib.parse.quote(title)}/{urllib.parse.quote(body)} requests.get(url, timeout10) def push_wecom(title, body): webhook https://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyYOUR_KEY data { msgtype: text, text: { content: f【短信转发】{title}\n{body} } } requests.post(webhook, jsondata, timeout10)如果你走MQTT路线就是把requests换成一个mqtt库的publish调用格式都是现成的。但不管走哪条通道我建议你一定要加一个关键字过滤逻辑。我自己的规则很简单KEYWORDS [验证码, 取件码, 告警, 登录] if any(kw in body for kw in KEYWORDS): push_bark(新短信, body)不加过滤的后果很严重。你以为会安静地收到几个验证码实际可能一天下来被银行理财广告轰炸几十条推送的体验直接崩盘。还有广播短信、商家促销全都不值得转发。在这个项目里过滤规则的价值比转发本身更大。推荐先在自己电脑上跑通这个Python脚本确认短信能正确读到并推送到手机再考虑把脚本部署到长期运行的设备上。如果直接用开发板跑LuatOS脚本逻辑一样但开发调试效率会低不少。4. 我踩过的坑转发器常见问题排查速查表4.1 短信就是收不到这是最让人抓狂的一个问题。我一开始把SIM卡插到模组上天线也接了代码看着也没毛病但发测试短信过去半天没反应。后来一步步排查才发现是模组没有开启数据业务也没配置APN。在AT指令模式下你需要手动确认这两件事ATCSQ 查看信号强度。返回值是个数字比如CSQ: 15,0一般大于10基本可用。如果返回 99 或 0说明根本没搜到网络先检查天线和SIM卡。ATCGDCONT1,IP,CMNET 配置APN接入点。移动一般是CMNET联通是UNINET电信是CTNET。APN不对能打电话能收短信但走不了网络转发自然就废了。顺带提醒一句SIM卡一定要先放普通手机里确认能正常收发短信。有一次我折腾了半天最后发现那张卡已经停机两个月了纯粹是浪费感情。另外如果是那种纯物联网卡很多虚拟运营商对短信有特殊限制强烈建议选正规的号卡避免后续踩坑。4.2 串口乱码、AT指令没反应乱码多半是波特率不对。Air724UG默认115200但市面上很多模块出厂是9600、57600各不相同你先用电脑的串口助手扫一遍常见波特率能打出OK的就是正确的。串口没反应则要先看硬件接线尤其是地线是否连通我之前提到过共地是串口通信稳定的铁律。还有一种很隐蔽的情况USB转串口芯片供电不足。开发板本身用USB供电没问题但如果你把模组的5V也接在同一个USB口上电流不够就会出现“时好时坏”的诡异现象。我最后是把模组和树莓派分开供电问题立刻消失。记住这不是玄学是电源余量问题。最后千万别同时开两个串口工具连同一个端口。Windows下COM口会互斥你后面启动的终端把端口占住了Python脚本自然读不到数据。这个错误我犯过不止一次每次都很浪费时间。4.3 重复推送、误报刷屏跑了一段时间后我发现同一个验证码被推送了两三次本来以为又中招了结果一查原因是我开了两个消息上报路径一个是ATCNMI的主动上报另一个是脚本里还写了一个轮询读取所有短信的逻辑。两者叠加短信被读取了两遍。解决办法是只保留主动上报机制轮询逻辑删干净。另外还有一个容易忽略的点短信存储位置满了之后模组会拒绝新短信。我建议在脚本里定期清理已读短信纯AT指令搞不定的可以发一条ATCMGD索引号手动删除。如果想偷懒有的模组支持ATCMGD,1删除所有已读短信但这个指令不同模组兼容性有差异最好查一下你的模组手册。下面这个排查表是我在实践中总结出来的你可以直接存一份症状可能原因处理办法完全收不到短信SIM卡欠费/停机、天线脱落、未驻网换卡测试、接好天线、检查ATCSQ能收短信但脚本读不到波特率不对、串口被占用重新扫描波特率、关闭其他串口工具串口输出乱码波特率不匹配、供电不足调整波特率、分开供电收到重复推送主动上报和轮询同时启用保留一种读取方式删除轮询逻辑短信内容被截断串口读取超时太短、读取逻辑不完整增大超时按行循环读完再推送5. 安全和边界操作之前先看清楚5.1 短信内容在你手里值多少钱短信这种东西天然包含敏感信息。验证码、取件码、账单提醒随便哪一条都是个人隐私。我在做转发器的时候最先考虑的不是功能而是权限边界。说白了短信转发等于把原本只存在运营商网络和SIM卡里的数据通过网络转发到了另一个终端上。中间经过的每一层服务理论上都有截获的可能。所以我给自己定了几个原则只转发必要的短信能不说话就不说话。我的过滤规则会先把验证码、告警这类高价值短信挑出来其余直接丢弃不做全文转发。转发内容脱敏比如只推送“收到一条来自138xxxx的短信”具体验证码内容自己去旧手机上看充分降低数据泄露风险。优先选可控通道MQTT自建Broker优于第三方云推送Bark好于域名不明的小众推送服务。用完就走短信转发不是聊天记录验证码这类东西看完就过期转发通道的缓存时间越短越好。5.2 有些地方不能碰这部分我必须要多说两句。短信转发器这个技术本身是中性的但它也有很危险的用法。圈子里有人把短信转发器和卡池、猫池联系起来搞批量注册账号、接码牟利这绝对不应该碰。我做这套转发器用的一直是自己的SIM卡、自己的号码解决的是自己生活里的实际麻烦。技术开源从来不是为了让人去钻空子。如果你只是好奇用自己手机号测试怎么折腾都没问题但如果你脑子里想的是“能不能搞一堆卡自动收验证码”我劝你趁早打消这个念头。短信权限在绝大多数场景里都属于强权限往灰产方向用轻则账号被封重则有法律风险这不是开玩笑的。我的态度就一句话把这个小工具当作家里的智能告警设备来做而不是当成一个牟利工具。有了这个底线你怎么玩都行。写在最后的经验这套转发器我断断续续跑了一个多月最大的感触不是代码多漂亮而是它让我的生活少了一个焦虑源。以前总担心漏掉哪条验证码现在不管人在哪里重要短信都会主动跑过来。如果你也想做我的建议是先别急着买模组翻翻抽屉里有没有旧安卓手机。有的话先用开源App把流程跑通确认自己确实需要一套独立方案再切换到本文这种模组路线。最后再分享一个小技巧部署好之后一定给自己设一个定时巡检任务每天早上给转发器发一条测试短信确认链路是通的。不然等到真正需要验证码时才发现系统挂了那才是真的无解。我就是有一次收到银行验证码前整整两天都没发现转发器掉线从那以后就加了这条定时自检。工具这东西越是安静地工作越显重要。
网站建设高端定制企业官网