1. 为什么我会想干这件事短信和滴答清单之间的“最后一公里”1.1 一个让我崩溃的场景先说个真实场景。我手机常年静音微信、企业IM、邮件全都靠滴答清单来兜底唯独短信这玩意儿一直游离在体系之外。运营商验证码、银行动账通知、快递柜取件码、客户临时改时间的短信……每一条都有时效性错过就是麻烦。有一天我因为没看到一条“下午三点会议室变更”的短信抱着笔记本在旧会议室傻等了半小时。那一刻我真想把短信直接变成滴答清单里的一个任务到点提醒我处理。这个需求一点都不复杂来一条短信自动在滴答清单里建一个任务内容包含发件人和短信原文带上截止时间或标签。但真要手动实现又涉及安卓端的短信监听、HTTP回调、第三方开放API的鉴权、去重逻辑怎么想都觉得不值当。直到我开始用 AI 编程的方式干活用 Gemini 3.0 来写中间这一层胶水代码事情才变得可行。1.2 为什么不用现成工具市面上当然有 IFTTT、Tasker、Automate 这类自动化工具。我也试过但始终没长期用起来原因很实在大部分自动化工具对短信的读取权限限制很严尤其在 Android 高版本上第三方应用拿不到全部短信内容。滴答清单的官方 API 开放能力很强但第三方自动化平台的封装层往往只暴露“新建任务”这种粗粒度动作没法灵活设置标签、优先级、提醒时间。免费方案不稳定付费方案按量计费为了一个个人小工具长期订阅肉疼。所以绕了一圈最靠谱的路线是自己搭一个中间服务短信转发器负责把短信变成 HTTP 请求中间服务负责解析内容再调用滴答清单的开放接口建任务。这正好也是 AI 编程最擅长的场景——不涉及复杂算法纯粹是接口胶水、数据转换、异常处理。1.3 “说人话”指挥 Gemini 3.0 这事靠不靠谱我必须诚实说接这个项目之前我半信半疑。Gemini 3.0 这类大模型生成个冒泡排序、写个响应式页面大家都见多了。但要完成“短信系统到滴答清单接口的桥接”涉及手机端配置、服务端接口、第三方 API 鉴权、生产环境部署AI 真能一步到位实际体验下来结论是能但有前提。前提是你得把需求讲得像跟一个脾气不太好但技术很硬的同事沟通一样——边界清晰、输入输出明确、异常情况说清楚。这也是为什么我强调“说人话”而不是“说黑话”。不需要堆术语但得把业务逻辑讲明白。Gemini 3.0 对这种事务型代码的理解能力比我预期强很多尤其擅长把“描述性的流程”直接转换成“可运行的代码骨架”。2. 先把链路和技术方案定下来接口不是写代码是划边界2.1 整条链路的架构设计项目动手前我先在纸上画了一条链路总共四段安卓手机短信 → 短信转发器 → 自建中间服务 → 滴答清单 OpenAPI这个图不需要多高级理解成“消息从左流到右”就行。短信进来后转发器截获内容用 POST 请求推给我的服务器服务器收到后做一次解析和去重再调用滴答清单的接口创建任务。中间服务是我唯一需要写代码的部分也是整个项目的核心。选择这个结构有几个原因。第一它把手机端和服务端解耦以后换手机、换转发器都不影响服务端逻辑。第二所有调试都可以在电脑上完成不用反复折腾手机日志。第三中间服务以后还能挂载更多自动化逻辑不局限于短信。2.2 短信侧转发器怎么把短信变成 HTTP 请求手机端我选的是开源项目 SMS Forwarder也就是常说的“短信转发器”。它在 Android 上监听系统短信数据库变化并通过规则匹配把短信内容转发到指定 URL。配置时有几个关键参数接收号码用正则匹配比如只处理非 106 开头的号码避免垃圾短信涌入。请求方式POSTJSON 格式方便服务端解析。请求体包含 sender、content、date 三个字段足够覆盖后续所有逻辑。这里有个容易忽略的细节转发器发出去的请求服务端无法确认它是否真的收到了短信所以必须在服务端做“收到即确认”返回 200。如果转发器没收到 200就会按自己的重试策略再推一次。这个行为既是好事也是麻烦后面我会单开一节讲幂等性。2.3 滴答清单侧OpenAPI 的接口约定滴答清单的开放接口网上资料不少最核心的就是创建任务的接口。它用的是 OAuth2 鉴权先拿到 access_token 和 refresh_token。实际调用时直接往任务列表接口 POST 一组 JSON 字段包括 title、content、tags、dueDate、priority 这些。官方文档写得比较规范但我第一次看的时候愣是没找到“项目 ID”是从哪获取的。其实很简单调用项目列表接口就能拿到当前账号下所有项目及其 ID。把那个 ID 填到请求里任务就会落到指定的清单目录。这个环节是“接口定义”的部分。你需要明确定义中间服务接收的短信格式是什么输出给滴答清单的任务字段是什么。就像订合同一样先把甲乙方边界说清楚。2.4 中间这层“翻译接口”如何设计我把中间服务定义成一个极简的 Webhook 接收器只暴露一个路由POST /api/sms请求体示例{ sender: 10086, content: 您的话费余额已不足10元请及时充值。, date: 2026-05-18 10:24:00, sms_id: abc123 }服务端拿到这个请求后做三件事查一下 sms_id 有没有处理过处理过就直接返回 200不重复建任务。把 sender 和 content 拼成滴答清单的任务标题或备注设置一个标签比如“短信”。调用滴答清单接口创建任务成功返回 200失败则返回 502 并让转发器触发重试。这里的 sms_id 是我特意要求 Gemini 3.0 加上的。一条短信每转发一次该 ID 保持不变后续重复请求再频繁也不会导致任务重复。这也是接口设计里常说的“幂等性控制”。你不可能要求第三方推送系统永远只推一次但你的服务可以做到同一条消息只处理一次。2.5 为什么不用更“重”的方案有人可能会问干嘛不直接在手机上加一个监听服务或者直接用安卓的 BroadcastReceiver我的答案很简单个人项目最重要的是可维护性和可替换性。手机上的应用生态变化太快今天能监听短信的权限明天可能就被系统收紧。把短信转成 HTTP 请求之后手机那边就变成了一个“传感器”服务端才是真正的“大脑”。将来我甚至可以再加一个入口让邮件、Slack 通知也走同一套中间服务。用“服务器 Webhook”的另一个好处是Gemini 3.0 对这种模式非常熟。模型见过大量类似的 Webhook 接收代码生成出来的代码质量很高我只要做少量修改就能上线。3. Gemini 3.0 实战从一句人话到可以跑的代码3.1 第一版提示词该怎么写我踩过不少次提示词设计的坑慢慢总结出一个靠谱的套路不说术语但把流程按“输入 → 处理 → 输出”讲清楚。以下是我实际发给 Gemini 3.0 的第一个版本我搭了一个短信转发器它会向我的服务器 POST 一个 JSON格式是 {sender: 发件人号码, content: 短信内容, date: 短信时间, sms_id: 唯一ID} 请你写一个 FastAPI 服务包含 1. 一个路由 POST /api/sms接收上面的 JSON 2. 先把 sms_id 存到 SQLite 里如果已经存在就直接返回 200 3. 如果不存在就调用滴答清单的创建任务接口把 sender 和 content 拼接成任务标题标签设置为“短信”提醒时间设为10分钟后 4. 滴答清单接口的鉴权信息用环境变量传入 5. 如果创建失败返回 502 6. 日志要完整把请求体和响应体都打出来。 请直接给出全部代码包含 requirements.txt。这段话没有任何高深词汇但 Gemini 3.0 能准确理解“先把 sms_id 存到 SQLite 里”是什么意思。它生成的代码里还主动加了 CORS 中间件虽然我这个场景其实用不上但说明模型对 Web 服务的安全习惯有默认预期。3.2 代码生成后手动补哪些关键细节AI 生成的代码骨架能跑但距离“能放心用”还有几段路要走。我拿到第一版代码后重点检查了四件事环境变量滴答清单的 client_id、client_secret、access_token、refresh_token 是否都从环境变量读取没硬编码。Token 刷新滴答清单的 access_token 大概几小时就会过期必须要有 refresh 逻辑。Gemini 3.0 生成的初始版本只写了读取 token刷新逻辑是我追问后补上的。请求超时外部 API 调用必须设置 timeout。如果不设置滴答清单接口万一挂起整个服务都会卡住。时区处理滴答清单的 dueDate 用的是 UTC 时间而短信时间通常是本地时间。我直接在代码里加了“所有时间统一转成 UTC 换算到滴答清单所需格式”的一步。这里要特别强调“检查依赖版本”。AI 生成的 requirements.txt 里可能写的是 FastAPI 最新版本但你的服务器上如果已经装了旧版启动就会报错。建议在项目里用虚拟环境而不是直接丢到全局环境里。3.3 端到端联调curl 一下就知道通没通写完代码先不开手机端直接在电脑上模拟一条短信这是最快验证链路的方式curl -X POST http://localhost:8000/api/sms \ -H Content-Type: application/json \ -d { sender: 13800138000, content: 项目评审改到明天下午3点地点508会议室, date: 2026-05-18 10:24:00, sms_id: test-001 }如果一切正常滴答清单里会立刻出现一条任务标题大概是“13800138000项目评审改到明天下午3点地点508会议室”带“短信”标签提醒时间在10分钟后。第一次跑成功的时候说实话还挺激动的。但紧接着我又用同一个 sms_id 再发了一次请求返回 200 但没创建重复任务。这一步验证了幂等性非常重要。很多新手做到“能跑”就停了结果上线后被短信转发器自己的重试机制搞得任务泛滥。3.4 用对话迭代修 Bug把异常直接丢给 AI联调过程中遇到一个奇怪问题短信内容如果包含特殊字符比如、滴答清单建出来的任务标题会被截断。我一查日志发现是转发器发来的请求里没有正确做 URL 编码导致服务器解析 body 时把参数拆错了。这种问题让我自己查估计要翻半天文档。我的做法是把报错日志直接贴给 Gemini 3.0然后补一句“这个报文在服务端解析出来缺了后半截你帮我判断是 URL 编码的问题还是请求体解析的问题并给出修复方案。”它很快就指出短信转发器端用的是application/x-www-form-urlencoded格式而我的 FastAPI 服务声明的是 JSON 类型两边需求不匹配。最终我把服务端改成同时支持两种 content-type问题当场解决。AI 编程比较有价值的地方就在这里它不只是生成代码还能做“代码会诊”。只要你能把现象和日志描述清楚它通常能给出靠谱的排查方向。4. 这一路踩过的坑短信重复、Token失效、时区错乱4.1 短信重复推送导致的任务重复这个坑几乎人人都会踩。短信转发器为了保证消息不丢默认会做失败重发。如果服务器处理正常但网络抖动导致响应没回到手机端短信就会被再次推送。第一次我没做去重时一个验证码短信给我建了五个任务。解法就是我前面提到的 sms_id 去重。具体实现时我给 SQLite 的表加了唯一索引CREATE TABLE IF NOT EXISTS processed_sms ( sms_id TEXT PRIMARY KEY, processed_at TEXT DEFAULT (datetime(now)) );写入时用INSERT OR IGNORE如果返回的 rowcount 为 0说明以前处理过直接返回 200 即可。我对 Gemini 3.0 补充了一个新需求“加一个 processed_sms 表做去重用 INSERT OR IGNORE”它就自动把代码调整好了。这一步是接口幂等性的具体落地看似简单价值极高。4.2 滴答清单 Token 刷新和 OAuth2 细节滴答清单的 OpenAPI 用的是标准 OAuth2凭据分两段第一段拿 authorization code第二段换 access_token 和 refresh_token。access_token 有效期短但 refresh_token 有效期长。我用的是“刷新一次 token 后回存数据库”的方案。实际操作时Gemini 3.0 生成的刷新逻辑有一个隐患它假设 refresh_token 永远有效。但如果长期不用refresh_token 也会过期届时必须重新走一遍授权流程。我加了一个文件标记当刷新失败时除了报错还往手机推一条系统通知提醒我手动去补授权。这条逻辑是我自己加的AI 不会主动替你考虑“如果 refresh_token 也失效了怎么办”。另外滴答清单的 API 请求头必须写成Authorization: Bearer token少个空格都会 401。我调试时被这个坑了近半小时后来用--trace抓包才看出来。4.3 时区和时间格式问题滴答清单创建任务时dueDate 参数要求是 ISO 8601 格式的 UTC 时间。比如北京时间的2026-05-18 15:00:00要转成2026-05-18T07:00:00.000Z。这个转换如果做错任务提醒会差八个小时。我的解决方式很直接在代码里统一约定“外部输入一律视为本地时间程序里转换为 UTC”。这句话也被我写进了提示词“所有时间字段统一按 UTC 存储传给滴答清单前把格式转成 ISO 8601。”Gemini 3.0 对时区库的使用很熟练直接用了 Python 的 zoneinfo还自动生成了处理夏令时的逻辑。虽然国内用不上夏令时但放到海外环境也能跑。4.4 手机端权限和进程保活短信转发器在 Android 高版本上跑得稳不稳取决于两个权限短信读取权限和通知权限。前者是核心后者是进程被系统回收后重新唤醒的保障。我最初只在手机上给了短信权限结果偶尔出现“一条短信没被转发”的情况。排查后发现是系统杀掉了转发器的后台进程。后来我把转发器的电池优化策略改成“不限制”并开启了通知权限问题就基本消失了。这里想给一个忠告手机端工具不要追求什么都自动最好每隔几天打开一次 App 看看日志确认转发还正常。5. 常见问题排查速查表5.1 五个典型故障和定位思路我用一张表把这些天遇到的典型问题整理出来方便你直接对着查。现象可能原因定位方法短信收到但滴答清单没任务转发器未启动或权限被回收打开转发器查看日志确认 POST 请求是否发出任务创建了但内容为空请求体解析失败看服务端日志里原始 request body检查 content-type 是否匹配重复任务出现缺少幂等处理检查 processed_sms 表确认是否支持同 sms_id 去重接口返回 401access_token 过期或未刷新调通 refresh 逻辑检查环境变量里的凭据提醒时间少了8小时时区转换错误检查是否统一转为 UTC并按规定格式传 dueDate排查这类问题核心思路就一句话先确认数据流到哪一步断了。从短信转发器的日志开始看再到服务端日志再到滴答清单侧的任务列表逐段确认。千万别上来就查代码大概率是前面的环节问题。5.2 提示词微调的实测经验Gemini 3.0 在生成代码上表现很好但前提是提示词足够具体。我总结了几个能让它少出幺蛾子的表达方式直接给样例数据。比如把转发器真实的 JSON 报文贴进去模型生成的反序列化代码就会照着你的结构来而不是自己发明字段。明确失败时的行为。我在提示词里加了“如果调用滴答清单失败返回 502并打印完整响应”这个细节避免了服务端静默吞错。分步提需求而不是一口气全塞。第一轮只让它写接收短信的逻辑第二轮再让它加滴答清单调用第三轮加去重。每轮都基于上一轮的结果继续代码质量明显更高。把代码当产品迭代而不是一次性交付。生成后用真实 curl 请求测发现不对就贴日志回去继续问。整个项目我大概迭代了七八轮每次改动都很小基本没出现推翻重来的情况。6. 扩展想法这件事的门槛其实不在AI在“定义边界”6.1 把同一套模式复用到其他场景这次打通短信和滴答清单之后我意识到这套模式可以复制到很多地方。比如把邮件里带附件的通知转成任务、把公众号推送的关键内容转成任务、甚至把某个系统监控的 webhook 告警直接落到滴答清单里。核心思路都是一样的源系统 → 标准化事件 → 中间处理服务 → 滴答清单 OpenAPI。中间处理服务可以攒出很多花样。往大里说这其实就是“事件驱动”思想的个人版实践。滴答清单是我的任务收件箱短信、邮件、聊天记录都可以往里汇。AI 在这里的角色像是一个翻译官帮我把各种不兼容的接口协议变成我能看懂的清单条目。Gemini 3.0 对接口定义、幂等性、OAuth 这些概念的理解比我想象中扎实我只需要把控边界即可。6.2 给也想试 AI 编程的朋友几句实话最后说点掏心窝的话。AI 编程确实把开发门槛拉低了但没低到“完全不用动脑”。实际做过一遍你会发现AI 擅长的是把明确的需求转化成代码而不是替你想清楚需求。你如果连自己都想不清楚“短信来了之后怎么处理、重复怎么办、失败怎么办”那 AI 再强也帮不了你。我现在的习惯是拿到一个自动化需求先花 10 分钟梳理输入、处理、输出、异常这四件事再让 AI 写代码。顺序反过来的话你会陷入无穷无尽的改写循环甚至比手写还慢。再分享一个小技巧上线之前用带前缀的测试短信多跑几次比如标题统一加“测试”字样造假确认后手动清理掉能避免把测试数据混进真实清单里。这是很多人没提过的细节但对实际体验影响很大。