SMS MCP 差评短信提醒:地图和应用评论实测

SMS MCP 差评短信提醒实测:几个时刻拉地图和应用商店评论,按评论 ID 去重,定时任务带幂等键防重复扣费,再算每小时和每天查一次各要花多少钱。

手绘插图:黑底上一部很大的手机,锁屏中间弹出一条短信提醒,提醒里只有第一颗星是黄的;左边一条评论小票,旁边一枚黄色地图标,小票上两星的那一行划了黄线,一条虚线从这一行连到手机。

我们在 2026 年 11 月 14 日新加坡时间 00:16 到 03:30 之间,每隔约一小时拉一次 Joe's Pizza、洛杉矶 DMV 的 Google 地图评论和 DoorDash 的 App Store、Google Play 评论:地图和 Google Play 各 3 轮,App Store 4 轮。整个测试一共 21 次扣费调用,合计 $0.029167,其中 13 次是轮询,另外 8 次是 3 次地点搜索、1 个后来换掉的样本、幂等测试、MCP 测试、MyChart 对照和脚本试跑各 1 次。几轮之间只有 Google Play 出现了新评论;App Store 返回的「最新评论」比拉取时刻早 28.8~31.9 小时,我们用 Apple 自己公开的评论订阅源对照,最新一条完全相同;Joe's Pizza 第 1 轮返回的 20 条评论跨了 35.7 小时,相邻两条的间隔中位数 0.61 小时,中间也有一段 9.75 小时没有评论,之后两小时的两轮里没有新评论。所以差评短信多久查一次要按来源定:地图上的热闹门店每小时查一次,一个来源一个月的接口费约 $1.00;评论少的地点和应用商店每天查一次,一个月约 $0.042。

去重按评论 ID:几轮之间重叠的 297 条次评论,ID 全部逐字相同。定时任务走 REST 并带 Idempotency-Key,同一小时重发直接回放、不再扣费;短信接口没有幂等键,要靠本地待发短信表保证同一条评论只发一次。短信一侧,TrueDialog 在 11 月 10 日发布的 MCP 能从 Claude、ChatGPT 直接发短信,Twilio 自己的 MCP 只能查文档;短信部分我们没有真发,全部是配置示例。

示意插图:左边一间带遮阳篷的小店和一部手机,各自吐出一串带星星的评论卡片,飞进中间一个筛网;大多数满星卡片落进下面的灰色托盘,只有一两张一星、两星的卡片被染成青绿色;一条虚线从筛网连到右边柜台上的一部手机,手机屏幕上亮着一个青绿色的对话气泡。
这套提醒只做一件事:从源源不断的新评论里挑出 1~2 星的那几条,变成店主手机上的一条短信。

这件活:差评一出现,店主手机上就有一条短信

同样是 1~2 星评论,量差得很远:按我们的推算,DoorDash 两个商店一天约 94 条,Google 地图上的洛杉矶 DMV 一天不到 1 条。Google 地图、App Store、Google Play 都会给经营者发通知,但通知走的是邮件、应用内消息或者开发者后台。短信几乎每部手机都能收、锁屏就能看见,代价是要花钱、要注册号码、要守运营商的规矩。这里要做的活很窄:每小时或每天查一次指定商户和应用的最新评论,发现新的 1~2 星评论,就给负责人发一条短信,同一条评论只发一次、同一次查询只扣一次钱。

这件活拆开是三段。第一段是读评论:用 EveryInfra 的 google_maps_reviews/reviews、app_store/reviews、google_play/reviews 三项能力,按最新排序拿回最近 20~50 条评论。第二段是判断:和上一次看到的评论比,挑出新出现的那几条,再按星级筛。第三段是发短信:经短信类的 MCP 服务器(MCP 是让 AI 助手调用外部工具的开放协议,见 modelcontextprotocol.io)或者短信服务商的接口把提醒发出去。第一段、第二段我们都在 2026 年 11 月 14 日真调过;第三段需要短信账号、注册过的号码和收件人同意,我们没有真发,全部写成「配置示例」,引用的都是对方官网和文档原文。

样本挑了四个,覆盖热闹程度完全不同的两类对象。纽约时代广场附近的 Joe's Pizza Broadway 是一家客流很大的店,Google 地图上有 27,620 条评论;洛杉矶 Hope Street 的加州机动车管理局(DMV)办事处是公共服务窗口,有 2,321 条评论、平均 3.1 星;外卖应用 DoorDash 代表评论量很大的应用,同时在 App Store 和 Google Play 上拉;患者门户应用 MyChart 代表医疗场景,作为跨领域的对照只拉了一轮。这些商户和应用都是公开的,评论者的名字和头像我们一律不写进文章。

样本平台和能力公开信息(11 月 14 日读)每次拉几条用来回答什么
Joe's Pizza Broadway(纽约)google_maps_reviews/reviews27,620 条评论,4.4 星20热闹的店,每小时会不会有新评论
Los Angeles DMV(Hope St)google_maps_reviews/reviews2,321 条评论,3.1 星20公共服务窗口,差评多但评论少
DoorDash(App Store,美国区)app_store/reviews应用 ID 71997245150应用商店的「最新」有多新
DoorDash(Google Play)google_play/reviews包名 com.dd.doordash40同一个应用在两个商店差多少
MyChart(两个商店,对照)app_store/reviews、google_play/reviews应用 ID 382952264、包名 epic.mychart.android50 / 40医疗类应用的差评占比
流程动画,从左到右五站:定时器每小时触发一次;EveryInfra 读三项评论能力,请求头带按小时生成的幂等键;本地表按评论 ID 去重,见过的跳过;新评论里 1~2 星的写进待发短信表;短信 MCP 或短信接口发出,发前先把状态改成「发送中」。动画里一个青绿小点沿着五站走一圈,到第三站时灰色的旧评论被挡下,只有一张一星卡片继续往右走。

SMS MCP 现在有哪几种:能发短信的和只查文档的

Google 搜索联想里,「sms mcp」下面挂着「sms mcp server」「claude sms mcp」「sms api mcp」几个变体(Google 联想词,2026 年 11 月 14 日读)。三款都叫 MCP:一款能发短信,一款只能查文档,一款要在本机跑。我们按对方原文各找了一个代表:一家短信平台自己托管的 MCP 服务器、一家短信接口公司的文档检索 MCP、同一家公司实验室出的本地 MCP。

第一类是 TrueDialog。这家位于美国奥斯汀的企业短信平台在 2026 年 11 月 10 日发布了 TrueDialog MCP,新闻稿写明它让人和 AI 代理在 ChatGPT、Copilot、Claude、Gemini、Perplexity 等助手里发送短信和 RCS 消息、管理联系人,已经上了 ChatGPT 的插件目录和微软 Copilot 的连接器目录,其他助手经 tdmcp.com 接入(PR Newswire 新闻稿;产品页见 truedialog.com/features/mcp)。新闻稿还写了一句对算账有用的话:MCP 按 TrueDialog 的标准价格提供,不另收 MCP 费用。鉴权走 OAuth 2.1:客户端自动发现 auth.tdmcp.com 上的授权服务器,用户在浏览器里登录自己的 TrueDialog 账号,客户端只拿到短期令牌,不用粘贴任何密钥(tdmcp.com 的配置说明)。端点是 https://connect.tdmcp.com,同时接受加了 /mcp 的写法。

第二类是 Twilio 自己的 MCP 服务器。它在 2026 年 5 月 7 日以公开测试版发布,托管在 mcp.twilio.com/docs,不需要账号、不需要鉴权(Twilio 博客)。它只有 twilio__search 和 twilio__retrieve 两个工具,用来搜索和取回 1,800 多个接口的参数说明;文档写明这个服务器只读,不会替你执行接口调用(Twilio MCP 文档)。所以它能帮编程助手写出调用 Twilio 发短信的代码,自己发不了短信。文档把「可以直接调用接口、用 OAuth 鉴权的工具」列在「下一步」里。

第三类是 Twilio 实验室的 @twilio-alpha/mcp。它在本机用 npx 启动,命令行里带上账号 SID 和 API Key,就能把 Twilio 的公开接口都变成 MCP 工具,其中包括发短信(GitHub 仓库 twilio-labs/mcp)。GitHub 上最后一次提交是 2025 年 7 月 7 日,npm 上的最新版本 0.7.0 也是同一天发布(npm 包页)。仓库 README 提醒,不要把社区写的 MCP 服务器和官方的放在一起跑,防止注入攻击借道拿到 Twilio 账号的工具。

项TrueDialog MCPTwilio MCP(公开测试)@twilio-alpha/mcp(实验室)
发布或最近更新2026-11-10 发布2026-05-07 公开测试最近提交 2025-07-07
运行在哪对方托管,connect.tdmcp.com对方托管,mcp.twilio.com/docs本机 npx 启动
鉴权OAuth 2.1,浏览器登录不需要命令行带 SID 和 API Key
能不能发短信能,send_sms不能,只查文档能,经接口工具
发前试运行execute=false 不发、不扣额度不适用文档没写
能不能读回复不能(只发不收)不适用经接口工具可以查
价格按 TrueDialog 套餐,MCP 不另收费免费按 Twilio 用量计费

微软 Learn 的连接器页列了十个工具和七条限制(Microsoft Learn:TrueDialog MCP 连接器)。十个工具里六个只读、四个会写,只有 send_sms 会真的发到手机上;send_sms 默认 execute=true,传 execute=false 是试运行,不发送、不消耗额度,但仍会生成一条群发记录;一次调用可以带多个收件人,所以一句话就可能发出很多条。已知限制里第一条是「只能发、不能收」:这个服务器读不到回复和会话。另外它不支持定时或循环群发,发送都是立即的、点对点的;退订和 10DLC、TCPA 的合规责任仍在账号所有人身上,force_opt_in 参数能发给已经退订的联系人,页面要求只在有合法依据时使用。

截图:微软 Learn 上 TrueDialog MCP 连接器页的「Known Issues and Limitations」一节,青绿框标出第一条「Outbound only」:这个服务器只发短信,读不到回复、收到的消息和会话,问它「对方回了什么」没有工具能回答。
连接器页写明 TrueDialog MCP 只发不收。差评提醒只需要发,这一条不影响;要做「店主回短信就自动回复评论」就得另接回调。 Microsoft Learn, TrueDialog MCP connector, 2026-11-14 读取

微软 Learn 页和 tdmcp.com 写的工具数不同。微软 Learn 页写十个工具,多了一个 report_issue(把问题报告发到 TrueDialog 的支持邮箱);tdmcp.com 的工具一节写的是九个工具、六个只读三个写,没有 report_issue。微软 Learn 页还提到一组可选的 inbox_* 收件箱工具,用于对话式短信会话,send_sms 在这组工具开启时对应 inbox_sms_send;tdmcp.com 说明这类工具按部署开启,connect.tdmcp.com 目前只公布那九个。我们没有 TrueDialog 账号,没能连上去数 tools/list,所以两处原文都写出来,以你连上以后实际看到的工具表为准。

差评提醒只要三样:能发、能试运行、能限定发件号码。TrueDialog MCP 三样都有,它缺的是读回复,对单向提醒没有影响。Twilio 自己的 MCP 现在只能帮你写代码;如果你已经在用 Twilio,可以让定时脚本调用它的 Messages 接口,AI 助手只负责写摘要。

评论这一侧:平台自己的通知做到了哪一步

动手写轮询之前,先看平台自己给经营者的通知能不能直接用。只有 Google 商家资料给了新评论的实时推送,而且只给认领了商户的人;Apple 的通知清单里没有「新评论」这一项;Google Play 的接口只给最近一周的评论。

Google 商家资料(Google Business Profile)的帮助页写明,经营者可以在「客户动态」里打开新评论和新照片的提醒,渠道是邮件、搜索页和地图应用(Google Business Profile 帮助:管理通知)。开发者还可以用 My Business Notifications API 把新评论、评论更新等事件推到 Cloud Pub/Sub 主题,再由自己的服务订阅(实时通知设置,页面 2026-08-28 更新;NotificationSetting 参考)。前提是你拥有这个商户的商家资料,并且在 Google Cloud 里配好 Pub/Sub 和 OAuth;取评论全文还要再调 accounts.locations.reviews.list(评论数据教程)。

App Store Connect 的用户通知一共七类,和评论有关的只有「Developer Response」:当用户修改了你已经回复过的评论时发邮件(App Store Connect 帮助:用户通知)。新评论本身不在清单里。要拿评论全文,开发者可以调 App Store Connect API 的 Customer Reviews 接口,按地区、星级筛选,按时间排序(Apple 文档:Customer Reviews),但前提是这个应用在你的开发者账号下。

Google Play 开发者接口里的「回复评论」接口能列出评论、回复评论,每页默认 10 条、最多 100 条;文档写明只能取到最近一周内新写或修改过的评论,而且只包括带文字的评论,只打分不写字的取不到;读取配额是每小时 200 次(Google Play Developer API:Reply to Reviews)。更早的评论要去 Play 管理中心下载 CSV。

平台官方推送新评论官方读评论接口只限自己的商户或应用和本文做法的关系
Google 地图有:邮件、地图应用,或 Pub/Sub 推送Business Profile API,取全部评论是自己的店优先用官方推送;竞品、加盟店、没认领的店只能轮询
Google 地图(地点接口)无Places API 每个地点最多 5 条否5 条不够判断新增,见 BL-70
App Store无新评论提醒,只提醒「已回复的评论被修改」App Store Connect API是自己的应用也要轮询
Google Play无只给最近一周、只给带文字的是只打分的差评官方接口看不到

如果你要盯的地点不归自己账号管,例如区域经理盯加盟店、代运营公司盯客户的店,官方推送用不上。在 App Store 上,连自己的应用都没有新评论推送。Reddit 上 r/smallbusiness 有人问怎样监测不是自己商户的 Google 评论,回帖里的结论是 Google 只让你监测自己的商户(Reddit r/smallbusiness 讨论)。地图地点接口每个地点最多返回 5 条评论(Places API Place Details 文档),用来判断「有没有新评论」太少。

几个时刻实测:新评论多久出现一次

我们在新加坡时间 00:16–00:20、01:19–01:20、02:19–02:20 这三个时刻拉了全部四个样本,03:20 又拉了一次 App Store,参数每次完全相同。这段时间相当于纽约时间 11 月 13 日上午 11 点到下午 2 点、洛杉矶时间上午 8 点到 11 点,正是这些店和窗口开门营业的时段。每一轮都按 sort=newest 取最新的 20~50 条,记下每条评论的 ID、星级和 posted_at,再和前几轮比,算出「新出现」的条数和其中的 1~2 星条数。表中每一行是一次成功的真实调用,每次扣 $0.001389。

样本轮次(新加坡时间)返回条数新出现新的里 1~2 星和前几轮重叠
Joe's Pizza(地图)1 · 00:1920———
Joe's Pizza(地图)2 · 01:19200020
Joe's Pizza(地图)3 · 02:19200020
洛杉矶 DMV(地图)1 · 00:2020———
洛杉矶 DMV(地图)2 · 01:19200020
洛杉矶 DMV(地图)3 · 02:19200020
DoorDash(App Store)1 · 00:1650———
DoorDash(App Store)2 · 01:20500050
DoorDash(App Store)3 · 02:20500050
DoorDash(App Store)4 · 03:20500050
DoorDash(Google Play)1 · 00:1740———
DoorDash(Google Play)2 · 01:20407533
DoorDash(Google Play)3 · 02:20406434
横向堆叠条形图,每个样本去重后全部评论的星级分布,按 100% 堆叠,块内是条数。Joe's Pizza(地图)20 条:1 星 1、2 星 1、3 星 4、4 星 4、5 星 10;洛杉矶 DMV(地图)20 条:1 星 5、2 星 1、3 星 2、4 星 4、5 星 8;DoorDash(App Store)50 条:1 星 20、2 星 7、3 星 4、4 星 1、5 星 18;DoorDash(Google Play)53 条:1 星 24、2 星 5、3 星 2、4 星 3、5 星 19;MyChart(App Store)50 条:1 星 11、2 星 4、3 星 4、4 星 1、5 星 30;MyChart(Google Play)40 条:1 星 10、2 星 3、3 星 0、4 星 2、5 星 25。1 星、2 星用青绿色。结论:DoorDash 两个商店的 1 星都比 5 星多,Joe's Pizza 一半是 5 星。

Joe's Pizza 第 1 轮返回的 20 条评论从 2026 年 11 月 12 日排到 2026 年 11 月 13 日,跨度 35.7 小时,相邻两条的间隔中位数 0.61 小时,按这个速度一天大约 12.8 条;但这 20 条里也有两段长空档,一段 7.7 小时、一段 9.75 小时。之后两轮返回的 20 条和第 1 轮完全相同,也就是说,在我们拉取的这 2 小时里没有新评论。对差评提醒来说,每小时查一次,多数时候拿回的是同一批评论。

洛杉矶 DMV 更安静。20 条评论从 2026 年 10 月 20 日排到 11 月 12 日,跨度 551 小时,平均每天 0.8 条,相邻两条的间隔中位数 14.6 小时,最长一段 117.8 小时;三轮返回完全相同。这类地点每天查一次就够了,查得再勤也只是重复付钱。

App Store 一侧的 DoorDash 4 轮返回的 50 条完全相同,最新一条始终是 2026-11-12T11:26:35Z(新加坡时间 11 月 12 日 19:26)发布的那条,离拉取时刻从 28.8 小时变成 31.9 小时。为了分清这是平台的节奏还是我们这边的延迟,我们在新加坡时间 01:21 另外读了 Apple 自己公开的评论订阅源:itunes.apple.com 上 DoorDash 美国区按最新排序的 customerreviews RSS,第一条的 updated 是 2026-11-12T04:26:35-07:00、1 星,换算成 UTC 和接口返回的最新一条是同一时刻、同一星级。也就是说,Apple 自己公开的「最新评论」列表在那个时刻也停在一天多以前,轮询频率改变不了它。MyChart 的 App Store 评论最新一条也在新加坡时间 11 月 12 日 19:35,和 DoorDash 只差 9 分钟。

Google Play 一侧,DoorDash 第 2 轮(2026 年 11 月 14 日 01:20)的 40 条里有 7 条是新的,其中 5 条是 1 星;第 3 轮的 40 条里 34 条是前两轮见过的 ID,另外 6 条是新 ID,其中 1 星 3 条、2 星 1 条。返回按最新排序,这两轮的新评论都排在列表最前面,在之前见过的那些评论之前,所以它们是这一小时里新进入「最新」列表的评论。四个来源里,只有 Google Play 在每一轮之间都有新评论。

散点图,横轴是新加坡时间 11月12日 到 11月14日 凌晨,纵轴四行:Joe's Pizza(地图)、洛杉矶 DMV(地图)、DoorDash(Google Play)、DoorDash(App Store)。每个点是一条评论的发布时间,灰点是第 1 轮已返回的,青绿点是之后几轮才出现的;竖虚线是 Joe's Pizza 的三次拉取时刻。Joe's Pizza 的点散布在 11月12日 到 11月13日 晚上,中间有两段空白;DMV 在 11月12日 以后只有一个点;App Store 的点全部在 11月12日 19:26 以前;Google Play 有一小串青绿点落在 11月13日 0 点前后,是第 2 轮新出现的 7 条。第 3 轮新出现的 6 条没有画进图。结论:几轮拉取之间,只有 Google Play 出现了新评论。
堆叠横条图,每轮返回里新评论和已见过评论各几条。Joe's Pizza(地图) 第 2 轮:新 0 条、已见过 20 条;Joe's Pizza(地图) 第 3 轮:新 0 条、已见过 20 条;洛杉矶 DMV(地图) 第 2 轮:新 0 条、已见过 20 条;洛杉矶 DMV(地图) 第 3 轮:新 0 条、已见过 20 条;DoorDash(App Store) 第 2 轮:新 0 条、已见过 50 条;DoorDash(App Store) 第 3 轮:新 0 条、已见过 50 条;DoorDash(App Store) 第 4 轮:新 0 条、已见过 50 条;DoorDash(Google Play) 第 2 轮:新 7 条、已见过 33 条;DoorDash(Google Play) 第 3 轮:新 6 条、已见过 34 条。 结论:同样拉最新的 20~50 条,绝大多数轮次全是重复,只有 Google Play 每轮有新 ID。

几轮之间重叠的评论一共 297 条次(20+20+20+20+50+50+50+33+34),评论 ID 全部逐字相同,没有一条「同作者、同时间、同正文却换了 ID」的情况;Google Play 里唯一一对「正文相同、ID 不同」的,是两位不同的用户都只写了一个词「expensive」。所以按评论 ID 去重在这四个来源上都站得住。时间戳不适合当去重依据有两个原因:评论会被作者修改,Google Play 的开发者文档就把「新写或修改过的评论」放在一起返回;评论也会晚到,站内 BL-79 记录过一条 posted_at 早于上一轮调用、上一轮却没有返回的评论,按「发布时间晚于上次看到的最新时间」判断就会漏发。

只有 Google Play 在几小时里出现了新评论,地图上的两个地点和 App Store 都没有,所以下一节的「每天新评论」改用单次返回里相邻评论 posted_at 的差来估算,属于估算。

样本参与计算的评论时间跨度相邻间隔中位数最长空档
Joe's Pizza(地图)2035.7 小时0.61 小时9.75 小时
洛杉矶 DMV(地图)20551.2 小时14.63 小时117.81 小时
DoorDash(App Store)5011.7 小时0.11 小时2.33 小时
DoorDash(Google Play)4715.2 小时0.20 小时2.45 小时
MyChart(App Store)5039.6 小时0.35 小时7.12 小时
MyChart(Google Play)4016.9 小时0.29 小时1.32 小时

DoorDash(Google Play)一行按前两轮返回的 47 条算。最长空档这一列提醒的是:即使是间隔中位数不到一小时的来源,也会有几个小时一条新评论都没有,所以「这一小时没有新评论」本身不是异常。

来源类型实测几轮里的新评论建议频率理由
地图上的热闹门店2 小时里 0 条;单次返回推算每天约 12.8 条营业时间每小时一次评论一阵一阵来,空档可达 9.75 小时
地图上评论少的窗口0 条;推算每天 0.8 条每天一次每天不到一条评论,查得再勤也是同一批
App Store3 小时里 0 条每天一次「最新」比拉取时刻早 28.8~31.9 小时,和 Apple 公开订阅源一致
Google Play每轮 6~7 条每天一到两次,或按小时汇总每轮都有新评论,但一半是 1~2 星,逐条发量太大

两把幂等键:同一小时不重复扣费,同一条评论不重复发短信

轮询最容易出的两种事故,一种是同一次查询被重发了几遍、扣了几遍钱,另一种是同一条差评给店主发了好几条短信。两种事故的原因相同:脚本超时重试、定时任务重叠、进程中途崩溃重启,客户端在重发的那一刻不知道第一次到底成功没有。解决办法也相同:给「一次逻辑上的动作」起一个稳定的名字,服务端或者本地表看到同一个名字就只做一次。

数据这一侧,EveryInfra 的 POST /api/v1/social 接受 Idempotency-Key 请求头,长度 1~255 个可见 ASCII 字符;24 小时内用同一把键发同样的请求,直接返回第一次成功的响应,不再运行、不再扣费,响应体带 replayed: true,响应头带 Idempotent-Replayed: true;同一把键换了参数会回 409 idempotency_conflict(EveryInfra llms-full.txt 的 Retries and idempotency 一节;同样的头和错误码也在 openapi.json 里)。我们把键设成「来源名 + UTC 小时」,例如 alert:gmaps:la-dmv-hope-st:2026111316:同一个小时里不管脚本重跑几次,都只扣一次;到了下一个小时,键自动换新,照常读新评论。定时任务和任何会自动重试的调用都走这条 REST 路径,各种重试情形的实测见 API 幂等键实测(BL-115)。

我们在新加坡时间 00:35:02 和 00:35:10 用同一把键对 DMV 发了两次同样的请求。第一次 HTTP 200,返回 10 条评论,扣 $0.001389;第二次 HTTP 200,响应头 idempotent-replayed: true,响应体 replayed: true,返回的 10 条评论和第一次相同。我们再用 MCP 工具 everyinfra_list_requests 查了账户的请求记录:第一次那条有扣费记录,第二次没有新的扣费记录。

截图:EveryInfra 接口第二次用同一把幂等键请求 google_maps_reviews/reviews 的真实返回,请求头写着 Idempotency-Key: bl146:gm:dmv-hope-st:2026111400,新加坡时间 00:35:10、HTTP 200;青绿框标出两处:响应头 idempotent-replayed: true、响应体 replayed: true。评论者名字已隐去,正文截短。
同一把键第二次请求直接回放第一次的响应,账户请求记录里只有一次扣费。 EveryInfra 接口真实返回,2026-11-14 00:35 SGT

短信这一侧情况不同。Twilio Messages 资源的接口文档(Twilio Message resource,11 月 14 日读)里,创建消息的参数没有幂等键:同一条短信 POST 两次,就是两条短信、两笔费用。TrueDialog 的 send_sms 在连接器页和 tdmcp.com 上也没有写幂等参数,只有试运行开关。所以「同一条评论只发一次」只能在自己这边保证。

我们用的办法是本地一张「待发短信表」,主键是「来源 + 评论 ID」。新评论进来先 INSERT OR IGNORE,主键冲突说明这条已经排过队,直接跳过;发送前先把状态改成 sending 并提交,发完再改成 sent。进程如果恰好在发送途中崩溃,这一条会停在 sending,下次运行不会自动再发,留给人看一眼。宁可漏发一条、让人工补,也不要给店主连发三条一样的短信:短信重复会让人对提醒失去信任,也会多付钱。

风险发生在哪我们的防法实测或依据
同一次查询扣两次钱数据接口超时重试、定时任务重叠REST 请求带 Idempotency-Key = 来源 + UTC 小时第二次回放,账户记录里没有新扣费
同一条评论提醒两次两次轮询返回了同一条评论本地表按评论 ID 去重297 条次重叠,ID 全部一致
同一条短信发两次短信接口没有幂等键,发送中途崩溃待发表 + 先改 sending 再发Twilio 文档创建参数里没有幂等键
查询失败被当成「没有新评论」接口返回可重试错误,脚本照常往下走重试 3 次仍失败就抛错,这一轮记为未检查,下一轮补llms-full.txt 的错误码说明:retryable、retry_after
查询没结果也扣钱since 设成当天、当天没有新评论空结果不扣费DMV since=2026-11-13 返回 0 条,$0

一次查询失败不等于没有新评论:失败的那一轮记成未检查,seen 表不写任何东西,下一轮用新的幂等键照常查,错过的评论会在下一次返回的最新 20 条里出现。下面的脚本按这个规则写。

python
# review_alert.py: run once an hour. DRY_RUN=1 prints the texts instead of sending them.
import hashlib, json, os, sqlite3, time, urllib.error, urllib.request
from datetime import datetime, timezone

API, KEY = "https://api.everyinfra.com/api/v1/social", os.environ["EVERYINFRA_API_KEY"]
DRY_RUN = os.environ.get("DRY_RUN") == "1"
LINK_BASE = os.environ.get("ALERT_LINK_BASE", "https://example.com")   # your own page that shows the review
DB = sqlite3.connect("review_alert.db")
DB.executescript("""
CREATE TABLE IF NOT EXISTS seen   (source TEXT, review_id TEXT, rating INT, posted_at TEXT, first_seen TEXT,
                                   PRIMARY KEY (source, review_id));
CREATE TABLE IF NOT EXISTS outbox (source TEXT, review_id TEXT, stars INT, status TEXT, created TEXT,
                                   PRIMARY KEY (source, review_id));""")
SOURCES = {"gmaps:la-dmv-hope-st": {"platform": "google_maps_reviews", "action": "reviews", "params": {
    "url": "https://www.google.com/maps/search/?api=1&query=Los%20Angeles%20DMV&query_place_id=ChIJAQOgfwrIwoARag3eO_IQ0oE",
    "sort": "newest", "limit": 20}}}
SHORT_NAME = {"gmaps:la-dmv-hope-st": "LA DMV Hope St"}             # ASCII only: keeps each text GSM-7

def call(source, body):
    key = f"alert:{source}:{datetime.now(timezone.utc):%Y%m%d%H}"      # same hour, same Idempotency-Key
    req = urllib.request.Request(API, json.dumps(body).encode(), method="POST", headers={
        "Authorization": f"Bearer {KEY}", "Content-Type": "application/json", "Idempotency-Key": key})
    for _ in range(3):
        try:
            with urllib.request.urlopen(req, timeout=100) as r:
                return json.load(r)
        except urllib.error.HTTPError as e:
            err = json.load(e).get("error", {})
            if e.code in (429, 502, 503, 504) or err.get("retryable"):
                time.sleep(int(err.get("retry_after") or 20)); continue   # same key on retry: charged once
            raise
    raise RuntimeError(f"{source}: no result after 3 tries")             # a failed check is not "no new reviews"

def review_key(r):   # review id first; fallback hash uses each platform's author field
    author = r.get("reviewer_name") or r.get("author_name") or r.get("author")
    return r.get("id") or hashlib.sha256(f"{author}|{r.get('posted_at')}|{r.get('text')}".encode()).hexdigest()

def link(source, rid=""):
    return f"{LINK_BASE}/r/{hashlib.sha256(f'{source}|{rid}'.encode()).hexdigest()[:6]}"

def run():
    now = datetime.now(timezone.utc).isoformat(timespec="seconds")
    for source, body in SOURCES.items():
        try:
            rows = call(source, body).get("results", [])
        except RuntimeError as e:                    # mark this hour "not checked"; seen stays as it was
            print(e); continue
        for r in rows:
            stars, rid = r.get("rating") or r.get("score"), review_key(r)
            if DB.execute("INSERT OR IGNORE INTO seen VALUES (?,?,?,?,?)",
                          (source, rid, stars, r.get("posted_at"), now)).rowcount == 0:
                continue                                                # seen before
            if stars is not None and stars <= 2:
                DB.execute("INSERT OR IGNORE INTO outbox VALUES (?,?,?,?,?)", (source, rid, stars, "pending", now))
        DB.commit()

def flush(send):     # one text per source per run; mark "sending" first so a crash never resends
    for (source,) in DB.execute("SELECT DISTINCT source FROM outbox WHERE status='pending'").fetchall():
        rows = DB.execute("SELECT review_id, stars FROM outbox WHERE source=? AND status='pending'", (source,)).fetchall()
        if len(rows) == 1:
            body = f"{rows[0][1]}-star review: {SHORT_NAME[source]} {link(source, rows[0][0])}"
        else:
            body = f"{len(rows)} new 1-2 star reviews: {SHORT_NAME[source]} {link(source)}"
        body.encode("ascii")                                            # raises if a non-GSM character slips in
        DB.execute("UPDATE outbox SET status='sending' WHERE source=? AND status='pending'", (source,)); DB.commit()
        send(body)
        DB.execute("UPDATE outbox SET status='sent' WHERE source=? AND status='sending'", (source,)); DB.commit()

def send_sms(body):
    raise NotImplementedError("connect your SMS provider here (Twilio Messages API or TrueDialog)")

if __name__ == "__main__":
    run(); flush(print if DRY_RUN else send_sms)

脚本的数据接口部分在新加坡时间 00:37:20 和 00:37:31 真跑过两次:第一次读回 DMV 的 20 条评论,全部是新的,其中 6 条 1~2 星进了待发短信表,扣 $0.001389;第二次在同一个 UTC 小时里,用的是同一把幂等键,接口直接回放,脚本读到 0 条新评论,待发表没有增加,账户请求记录里也没有第二笔扣费。上面这版加了 DRY_RUN 开关、按来源每小时合并成一条的 flush() 和纯 ASCII 的短信模板,我们把第 1 轮的 DMV 返回原样喂给它离线跑了两次(不调接口):第一次打印出一条 6 new 1-2 star reviews: LA DMV Hope St https://example.com/r/2ff3c3,67 个字符;第二次没有输出。send_sms() 留空,接你自己的短信服务商。

1~2 星占多少,一天会发几条短信

短信量取决于两件事:新评论来得多快,其中多少是 1~2 星。表中的评论按 ID 去重后合在一起算;「每天新评论」按每个样本最新几十条评论的 posted_at 跨度推算,是估算;「每天 1~2 星」是两列相乘。两个 MyChart 样本只拉了一轮,数字只来自那一次返回。

样本去重后条数1~2 星占比按发布时间推算每天新评论推算每天 1~2 星
Joe's Pizza(地图)20210.0%12.81.3
洛杉矶 DMV(地图)20630.0%0.80.2
DoorDash(App Store)502754.0%100.954.5
DoorDash(Google Play)532954.7%72.439.6
MyChart(App Store)501530.0%29.78.9
MyChart(Google Play)401332.5%55.418.0
横向条形图,去重后的评论里 1~2 星的占比。Joe's Pizza(地图) 10.0%(2/20);洛杉矶 DMV(地图) 30.0%(6/20);DoorDash(App Store) 54.0%(27/50);DoorDash(Google Play) 54.7%(29/53);MyChart(App Store) 30.0%(15/50);MyChart(Google Play) 32.5%(13/40)。 DoorDash(App Store)一根用青绿标出。结论:同一条规则,外卖应用的最新评论里一半左右是差评,热门披萨店只有十分之一。

单看一轮的占比会不会偏?下表是每一轮返回里 1~2 星的占比。地图两个地点和 App Store 每轮返回的是同一批评论,占比自然不变;Google Play 每轮都有新评论,占比从 50.0% 升到 60.0%,第 3 轮新出现的 6 条里有 4 条是 1~2 星。样本只有三轮,这个上升只说明「一小时里进来的几条差评就能让占比动 7.5 个百分点」,不说明 DoorDash 的口碑在变差。

样本第 1 轮第 2 轮第 3 轮第 4 轮
Joe's Pizza(地图)2/20,10.0%2/20,10.0%2/20,10.0%—
洛杉矶 DMV(地图)6/20,30.0%6/20,30.0%6/20,30.0%—
DoorDash(App Store)27/50,54.0%27/50,54.0%27/50,54.0%27/50,54.0%
DoorDash(Google Play)20/40,50.0%21/40,52.5%24/40,60.0%—

星级分布(见上方 fig-02)比占比多说明一件事:评论是两头多、中间少。DoorDash 两个商店 1 星都比 5 星多(App Store 20 对 18,Google Play 24 对 19),每个商店 3、4 星加起来都只有 5 条;MyChart 两个商店 5 星都占六成(30/50、25/40),差评集中在 1 星。Joe's Pizza 一半是 5 星,1 星、2 星各 1 条。对提醒规则来说,这意味着阈值设在「≤2 星」还是「=1 星」,在 DoorDash 上只差 12 条(7+5),在 Joe's Pizza 上只差 1 条:先按 1~2 星设,量太大再收紧到 1 星,效果有限。

Joe's Pizza 去重后 20 条里只有 2 条是 1~2 星,推算一天约 1.3 条差评,逐条发短信可以接受。DMV 的差评占比是 30.0%,但评论本身很少,推算下来一天只有 0.2 条。DoorDash 两个商店的最新评论里一半左右是 1~2 星,推算两个商店加起来一天约 94 条(54.5 + 39.6)。

对这种量级的应用,逐条短信没人看得过来。可以换成两种规则之一。一种是「每小时最多一条」:这一小时有差评,就发一条类似「过去一小时 12 条 1~2 星」的短信,链接指向完整列表,上面脚本的 flush() 就是按来源每小时合并成一条。另一种是「超过平时才发」:先用一周的 DRY_RUN=1 数出每小时差评条数的中位数,只有当某一小时的差评数超过中位数的两倍时才发短信,这通常意味着出了故障或者发版出了问题。两种规则都不改变接口费,只改变短信量。

横向分组条形图,对数刻度每格 10 倍,每月短信条数。Joe's Pizza(地图)逐条发约 39 条,每小时最多一条也是 39 条;洛杉矶 DMV(地图)两种都是约 6 条;DoorDash 两个商店逐条发约 2,823 条,改成营业时间每小时最多一条后最多 390 条,青绿标出。结论:评论少的店两种规则一样,大应用必须合并。

Google 地图上将近一半的评论只有星级没有正文:Joe's Pizza 和 DMV 都是 20 条里 9 条。应用商店的评论在我们拉到的样本里都带正文。

review alert sms 的账:每天查 24 次和查 1 次

数据这一侧的价格很简单。目录里 google_maps_reviews/reviews、app_store/reviews、google_play/reviews、yelp/reviews 四项能力都是每次调用 $0.001389,一次最多拿回 100、500、200、10 条,按次计费,不按条数计费;返回空结果不扣费(目录 2026 年 11 月 14 日读取,见 价格页)。本次实测一共 21 次扣费调用,账户请求记录里的扣费合计 $0.029167,等于 21 × $0.00138889;同键回放和两次空结果都没有扣费。

方案每天调用次数每天接口费30 天接口费适合谁
1 个来源,每天 1 次1$0.0014$0.042评论少的地点,例如 DMV 这类窗口
1 个来源,每小时 1 次24$0.0333$1.00评论多、要当天处理的门店
3 个来源,每天 1 次3$0.0042$0.125一个应用盯两个商店加一个地点
3 个来源,每小时 1 次72$0.1000$3.00连锁门店的值班提醒
3 个来源,营业时间每小时(9:00–21:00,13 次)39$0.0542$1.63夜里不发短信的店
横向条形图,每月接口费。1 个来源每天查 1 次 $0.042;1 个来源每小时查 1 次 $1.00;3 个来源每天 1 次 $0.125;3 个来源每小时 1 次 $3.00;作为参考,Twilio 美国本地号码月租 $1.15。结论:每小时查一个来源一个月的接口费低于一个短信号码的月租。

按样本把「每天查 1 次」和「每天查 24 次」放在一起看,差别在于能多看到什么。下表的「每次能看到的新评论」用上一节的推算速度乘以两次检查之间的小时数,封顶为一次返回的条数;超过封顶说明两次检查之间进来的评论比一次能拿回的多,会漏。

样本(每次拉几条)每天 1 次:30 天接口费每天 1 次:每次的新评论每天 24 次:30 天接口费每天 24 次:每次的新评论
Joe's Pizza(20)$0.042约 12.8,未超 20$1.00约 0.5
洛杉矶 DMV(20)$0.042约 0.8$1.00约 0.03
DoorDash App Store(50)$0.042约 100.9,超过 50$1.00约 4.2
DoorDash Google Play(40)$0.042约 72.4,超过 40$1.00约 3.0

对 DMV,每天查 24 次多花的 $0.96 换来的几乎全是重复;对 DoorDash 两个商店,每天查 1 次会漏掉一半以上的新评论,要么每小时查,要么每天查但把 limit 提到 200 以上(App Store 一次最多 500 条,Google Play 最多 200 条),费用都一样是每次 $0.001389。

总账的大头在短信一侧的固定费用:3 个来源每小时查一次,一个月接口费 $3.00。Twilio 的美国价格页写明,普通 10 位号码发一条短信每段 $0.0083,另加运营商收的通道费,例如 AT&T 每段 $0.0035、T-Mobile 每段 $0.0045;最终状态为「失败」的消息每条收 $0.001 的处理费(Twilio 美国短信价格,页面写「价格截至 2026 年 11 月」)。号码月租从 $1.15 起(Twilio 号码价格)。再加上 10DLC 的一次性品牌注册 $4.50 和每个用途 $15 的审核费,以及按用途收的月费。按这些价目算,一条单段短信大约 $0.0118~$0.0128,钱主要花在号码、登记和月费上。

项TwilioTrueDialog
每条短信每段 $0.0083,另加运营商通道费套餐内(小企业版含 5,000 条)
号码美国本地号码 $1.15/月起长号码 $9.99/月
10DLC品牌 $4.50 一次,每个用途 $15 审核,另收月费价格页写明提供自动 10DLC 注册
最低月费无,按用量$119/月,年度合同
用 MCP 发短信自己的 MCP 只查文档,不能发能发,MCP 不另收费

TrueDialog 是按月订阅的套餐制。价格页列了四档:小企业版每月 $119,含 5,000 条,超出每条 $0.024;专业版每月 $425,含 25,000 条;企业版每月 $900,含 60,000 条;定制版每月 $1,000 起,都是年度合同;运营商的通道费另算,长号码每月 $9.99,短号码每月 $799(TrueDialog 价格页,11 月 14 日读)。新闻稿说 MCP 不另收费,所以通过 Claude 发短信的成本就是这些套餐价。按我们的推算,Joe's Pizza 这类门店一个月约 39 条提醒,在小企业版 5,000 条的额度里占不到 1%;已经用 TrueDialog 做营销短信的商家,提醒可以挂在现有账号上。

一家店一个月数据接口费短信条数(估算)短信费(Twilio,按每条 $0.0128 估)号码月租合计(不含 10DLC 登记和月费)
Joe's Pizza 这类热闹门店,每小时查$1.00约 39$0.50$1.15$2.65
DMV 这类窗口,每天查 1 次$0.042约 6$0.08$1.15$1.27
DoorDash 这类大应用,两个商店每小时查,逐条发$2.00约 2,823$36.13$1.15$39.28

表中短信条数按上一节的「每天 1~2 星条数」乘 30 估算,是量级。大应用逐条发,一个月约 2,823 条;改成营业时间每小时最多一条,最多 390 条,短信费按同样单价约 $4.99。

合规:10DLC 注册、退订,以及 11 月 25 日生效的 FCC 新规

在美国用普通 10 位号码(行业里叫 10DLC)给手机发应用程序产生的短信,要先在 The Campaign Registry 登记品牌和用途。Twilio 的帮助中心列的费用是:低量标准品牌注册一次性 $4.50,每个用途登记的审核费 $15,之后还有按用途收的月费(Twilio 帮助中心:A2P 10DLC 费用)。TrueDialog 的价格页写明它有自动 10DLC 注册,团队会协助完成 10DLC 和短号码的登记(TrueDialog 价格页)。

退订是第二件事。美国无线通信行业协会 CTIA 的《消息原则与最佳实践》把「STOP」定为标准的退订关键词,要求发送方支持多种退订方式(CTIA Messaging Principles and Best Practices,2023 年 5 月版)。TrueDialog 的新闻稿写退订会被自动执行(PR Newswire 新闻稿)。

第三件事是美国联邦通信委员会(FCC)刚改过的撤回同意规则。FCC 在 2026 年 9 月 30 日通过了修订(据 Kelley Drye 的解读,原文见下文联邦公报),联邦公报 2026 年 10 月 26 日刊出,生效日期是 2026 年 11 月 25 日(Federal Register 2026-21821)。公报摘要写了三点:发送方可以把一次撤回理解为只针对它所指向的那一类信息性消息;发送方可以指定一种专门的撤回方式;金融机构发欺诈提醒的豁免条件放宽。FCC 9 月 9 日公布的情况说明也在网上(FCC 情况说明 PDF)。这些条文涉及「收件人怎么退订、退订后哪些消息必须停」,具体到你的业务适用哪一条,请找律师确认;我们只把规则原文和日期摆出来。

事项要做什么费用或日期出处
10DLC 品牌登记在 The Campaign Registry 登记发送方品牌低量标准品牌一次性 $4.50Twilio 帮助中心
用途登记审核每个用途审核一次每个 $15,之后按用途收月费Twilio 帮助中心
最短计费期用途登记按 3 个月起付(政治类除外)页面 2026-09-16 更新Bandwidth 支持中心
退订关键词支持 STOP,并接受多种退订方式不涉及费用CTIA 2023 年 5 月版
FCC 撤回同意新规对照退订范围和指定退订方式2026-10-26 刊登,2026-11-25 生效联邦公报 2026-21821

短信里写什么:160 个字符,别把评论原文整段转发

美国的普通短信按 160 个字符一段计费,超过就拆成两段、付两段的钱(Twilio 美国价格页的常见问题写明按段计费,Twilio 美国短信价格)。Twilio 的字符上限说明写明,消息里只要出现一个表情符号、一个汉字或者一个「智能引号」这类 GSM-7 以外的字符,整条就改用 UCS-2 编码,一段只能放 70 个字符(Twilio:How long can a message be?)。所以提醒里只放三样:几星、哪个地点或应用、一条能点开的链接,全部用英文和 ASCII 字符,上面脚本的模板就是这样写的。

放进短信示例字符数说明
星级1-star6用英文写;星形符号「★」不在 GSM-7 里,会让整条变成 UCS-2,一段只剩 70 个字符
地点或应用LA DMV Hope St14用内部简称,不写评论者名字
链接https://example.com/r/2ff3c328指向自己的系统,打开后再看全文
合计(单条,含分隔符)1-star review: LA DMV Hope St https://example.com/r/2ff3c358一段 160 个字符以内,按一段计费
合计(每小时汇总)6 new 1-2 star reviews: LA DMV Hope St https://example.com/r/2ff3c367离线试跑实际打印的那一条
不放评论原文、员工外貌和窗口号、患者能被认出的细节—隐私和误伤同事的风险

我们在 DMV 的 20 条评论里看到,6 条 1~2 星评论里有 2 条描述了能认出是谁的工作人员(一条写保安,一条写某个窗口号的职员),用词也很重。把这样的原文整段转发到十几个员工的手机上,等于把对某位同事的指控群发了一遍。医疗场景另有先例:美国卫生与公众服务部民权办公室(HHS OCR)公布过诊所在回复网上差评时泄露患者信息的和解案。2023 年 6 月 5 日公布的一起,新泽西一家精神科诊所在回复 Google 差评时披露了四名患者的信息,和解金额 $30,000(HHS:Manasa Health Center 和解;金额见 HHS 2023 年度报告);2022 年 12 月 14 日的一起是牙科诊所在社交媒体回复评论时披露患者信息(HHS:New Vision Dental 和解;全部和解列表见 HHS 决议协议页)。这两起的起因都是回复评论时披露了患者信息。短信提醒本身不是回复评论,具体怎么处理,请按你们机构的隐私制度和法务意见办。

美国联邦贸易委员会(FTC)的《消费者评论和推荐规则》§465.7 禁止用没有依据的法律威胁、恐吓、虚假指控等手段压制评论,也禁止按评论好坏选择性地隐藏(16 CFR Part 465,§465.7 Review suppression;FTC 的问答见 Consumer Reviews and Testimonials Rule Q&A)。

跨领域:社区诊所和公共服务窗口的评价提醒

把同一套做法搬到社区诊所、医院门诊、车管所、社保窗口这类地方,技术上几乎不用改,改的是「谁收短信、短信里写什么、多久看一次」。这里只讲数据方法,不涉及任何医疗判断,也不构成法律或医疗建议。我们用的两个对照样本,一个是洛杉矶 Hope Street 的 DMV 办事处,一个是很多美国医疗机构给患者用的 MyChart 应用。

DMV 这个样本的特点是「评论少、差评多」。11 月 14 日新加坡时间 00:20 那一轮,最新 20 条评论里 1 星 5 条、2 星 1 条,1~2 星占 30%;这 20 条的 posted_at 从 2026 年 10 月 20 日排到 11 月 12 日,平均每天不到 1 条。其中 2026 年 11 月 1 日以来的有 10 条,这 10 条里 5 条只打了分、没写字。这类地点每小时查一次没有意义,每天查一次就能覆盖,钱也只有每天 $0.001389。提醒脚本要能处理空正文:上面的模板不放正文,空正文不会把短信弄乱。

MyChart 这个样本说明了应用评论和地点评论的不同。App Store 一侧 50 条里 1 星 11 条、2 星 4 条,占 30%;Google Play 一侧 40 条里 1 星 10 条、2 星 3 条,占 32.5%。两个商店的应用评论都带正文,Google Play 那 13 条低星评论平均 96 个字符,App Store 的低星评论常带一个标题。我们按关键词粗分了一下 App Store 的 15 条低星(一条可以命中多类):6 条提到消息或预约,2 条提到登录或验证码,2 条提到更新。这种分类适合放进每天的汇总里,交给负责患者体验的人,不适合拆成一条条短信发给一线员工。

公共服务机构做这件事,可以对照两份现成的框架。美国医疗研究与质量局(AHRQ)把 CAHPS 系列调查定义为患者报告的就医体验测量,并在说明页里分开「患者体验」和「患者满意度」两个概念,还专门提到开放式的文字评论对发现安全问题很有用(AHRQ:什么是患者体验;CAHPS 总页见 ahrq.gov/cahps,CMS 的介绍页见 CMS:CAHPS)。联邦政府的服务窗口则有 OMB 通函 A-11 第 280 节,要求被指定的高影响服务提供方部署办完事后的反馈问卷、按季度向 OMB 报告反馈,并把收到的反馈用于改进和「服务补救」(A-11 Section 280 说明)。网上评论和这些问卷不同:它不抽样、不匿名验证,也没有标准题目,所以只适合当「早一点发现问题」的信号,不能拿来替代正式的体验调查。

具体到流程,诊所和窗口可以把提醒分成两档。第一档是短信,只发给值班负责人,内容只有星级、地点和链接,不放评论原文,也不放能推出患者身份或病情的词;第二档是每天一份汇总,按主题(排队、预约、态度、系统故障)分类,交给质量或体验负责人。点名员工的差评先交给主管核实。

档发给谁内容频率
第一档:短信当班负责人一人星级、地点、链接;不放原文和能推出患者身份的词新的 1~2 星评论出现后,下一次检查时发
第二档:每日汇总质量或患者体验负责人按排队、预约、态度、系统故障分类的条数和摘要每天一次
点名员工的差评主管原文和链接,不进群发出现时

用 MCP 把两边接起来(配置示例)

只要定时脚本就能跑完整个流程;接 AI 助手的价值在于「看懂差评、写一句给店主的摘要、决定要不要升级给区域经理」。下面是在 Claude 里同时接两个远程 MCP 服务器的做法:EveryInfra 负责查能力、对账和读脚本整理好的新评论,TrueDialog 负责发短信。EveryInfra 一侧我们真调过 tools/list 和 tools/call;TrueDialog 一侧我们没有账号,按 tdmcp.com 和 Claude 帮助中心的原文写成配置示例。

在 Claude 桌面应用或 claude.ai 里,按 Claude 帮助中心的说明打开「自定义连接器」,填名称和地址就能添加远程 MCP 服务器;连接从 Anthropic 的云端发起,所以服务器必须能从公网访问(Claude 帮助中心:自定义连接器)。TrueDialog 填 https://connect.tdmcp.com/,点连接后在浏览器里登录 TrueDialog;EveryInfra 填 https://api.everyinfra.com/mcp,按 MCP 接入页 带上自己的 Key。在 Claude Code 里,远程 HTTP 服务器用 claude mcp add --transport http 添加(Claude Code MCP 文档),定时跑可以用非交互的 claude -p(Claude Code 编程方式运行)。

json
{
  "mcpServers": {
    "everyinfra": {
      "type": "http",
      "url": "https://api.everyinfra.com/mcp",
      "headers": { "Authorization": "Bearer ${EVERYINFRA_API_KEY}" }
    },
    "truedialog": {
      "type": "http",
      "url": "https://connect.tdmcp.com/"
    }
  }
}

我们在新加坡时间 00:29 真调了 EveryInfra 的 tools/list:返回 12 个工具,读评论用的是 everyinfra_call_api,它的注解是 readOnlyHint: false、destructiveHint: true、openWorldHint: true,因为它会扣费;everyinfra_list_capabilities、everyinfra_get_job、everyinfra_list_requests 都标为只读。everyinfra_call_api 的参数是 platform、action、params、mode 四个。每小时跑的定时任务交给上面的脚本走 REST 带 Idempotency-Key,AI 助手只读脚本整理好的新评论、写摘要、决定要不要升级。00:35 和 00:36 我们经 MCP 调了两次 google_play/reviews:第一次把 MyChart 的包名写成 com.epic.mychart.android,返回 0 条,没有扣费,原因 empty_result_refunded;改成正确的 epic.mychart.android 后返回 40 条,扣 $0.001389。

工具来自只读在这套提醒里做什么
everyinfra_list_capabilitiesEveryInfra是查能力、参数和价格,不扣费
everyinfra_call_apiEveryInfra否(会扣费)临时查一个地点;每小时的定时任务走 REST 带 Idempotency-Key
everyinfra_list_requestsEveryInfra是对账:看哪次调用扣了费
send_smsTrueDialog否(会发短信)发提醒;execute=false 只试运行(配置示例,未实测)
text
每天 9:00–21:00 每小时运行一次:
1. 读 review_alert.db 里 outbox 表状态为 pending 的新差评(由定时脚本写入)。
2. 每个来源合成一条英文短信,不超过 60 个字符,不写评论者名字、不写员工外貌和窗口号,只用 ASCII 字符。
3. 先用 truedialog 的 send_sms,execute=false 试运行一遍,把将要发的内容列给我看;我回复「发」再 execute=true。
4. 同一来源同一小时只发一条。

第 3 步的「先试运行、人确认再发」对应连接器页那句「send_sms 默认真发」。TrueDialog 新闻稿说开发者可以只给代理只读工具;如果你要无人值守地每小时发,就要接受由代理直接调用 send_sms,这时收件人名单要固定写在提示里,不让模型自己去搜联系人。

和站内另外几篇的区别

站内另外几篇没有写短信渠道和每小时的成本:BL-88 写的是三家小店用 Claude Duet 每天早上出一份差评早报,结论是小店近 90 天只有 4~8 天有新评论,所以每天看一次就够。BL-79 写的是 Claude Managed Agents 每晚巡检 Google、Yelp、Tripadvisor 三个平台,发现过一条 posted_at 早于上一轮调用、上一轮却没有返回的评论,说明只按时间判新会漏。BL-70 比较了抓 Google 地图评论的几条路,包括 Places API 5 条的上限。BL-115 把幂等键的各种重试情形测全了。工具选择的另一面见 数据接口和工具路由。

行业动向

日期事件对差评短信提醒的影响出处
2026-11-10TrueDialog 发布 TrueDialog MCP在助手里加连接器就能发短信;号码注册和退订仍要在短信平台办PR Newswire
2026-10-28TikTok 推出餐厅指南 Must Eat餐厅多了一个要盯的评论来源TikTok
2026-10-26FCC 撤回同意新规刊登,2026-11-25 生效退订流程要对照新规再看一遍联邦公报
2026-09-16Bandwidth 更新 10DLC 费用页短信用途登记按 3 个月起付Bandwidth
2026-07-28MCP 规范发布新版本远程 MCP 服务器更接近无状态接口MCP 更新日志

2026 年 10 月 28 日,TikTok 在纽约、洛杉矶和旧金山湾区推出餐厅指南 Must Eat,用户可以在应用里给餐厅打分写评论(TikTok 官方介绍;The Verge 报道)。餐厅要盯的评论来源又多了一个,提醒脚本的 SOURCES 表要留出扩展的位置。

MCP 规范在 2026 年 7 月 28 日发布了新版本,去掉了会话和初始化握手,远程服务器更接近无状态的普通接口(MCP 规范更新日志;GitHub 发布页)。tdmcp.com 把自己描述为无状态、不保存凭据的转接层,和这次规范的方向一致。

边界:做不到或要注意的

限制影响怎么办
短信只证明发出不知道负责人看没看到让负责人回复关键词,用短信平台的回调记下来
App Store「最新」列表本身有延迟应用商店的差评要一天多以后才出现在列表里应用评论每天查一次
since=当天 会漏晚到的评论昨天写、今天才出现的评论被过滤since 设成昨天,按评论 ID 去重
样本小、时段短每天几条短信只是量级先用 DRY_RUN=1 跑一周

样本小,结论有边界。我们只测了 2 个地点和 2 个应用(外加 MyChart 一轮对照),跨了约 3 个小时,正好是美国东部的上午到中午。新评论的速度和差评占比会随店、随时段、随促销和事故变化,文中的每天几条短信只能当量级参考。要给自己的店定频率,先用 DRY_RUN=1 跑一周,看待发表每天进几条。

常见问题

Claude 能直接发短信吗?SMS MCP 怎么接?

Claude 本身不发短信,要接一个能发短信的 MCP 服务器。按 tdmcp.com 的说明,在 Claude 的「自定义连接器」里填 https://connect.tdmcp.com/ 并登录 TrueDialog 账号即可;Twilio 自己的 MCP 只能查文档,发不了短信。问题来自 Google 联想词「claude sms mcp」(Google 联想词,2026 年 11 月 14 日读)。

Google 商家资料自带新评论通知,还需要 review alert sms 吗?

自己认领的店可以先用 Google 的邮件和地图应用通知,或用 Pub/Sub 推送自建提醒;需要短信、需要合并多家店、需要盯不归自己账号管的地点时,才需要轮询加短信。问题来自 Google 联想词「google business review notifications」(11 月 14 日读)。

收到一条写着 review alert 的短信,怎么分辨是不是诈骗?

自建的提醒应该固定从一个登记过的号码发出,内容只有星级、地点和一条指向你们自己系统的链接,从不要求登录密码或付款。陌生号码发来「你有新差评,点此登录处理」之类的短信,按钓鱼处理。问题来自 Google 联想词「review alert sms scam」(11 月 14 日读)。

App Store Connect 有没有新评论通知?

按 App Store Connect 帮助页的通知清单,没有。和评论有关的只有「Developer Response」:你回复过的评论被用户修改时发邮件。新评论要靠轮询 Customer Reviews 接口或评论数据。问题来自 Google 联想词「app store connect review notifications」(11 月 14 日读)。

店主回短信,能自动回复那条评论吗?

用 TrueDialog MCP 做不到:微软 Learn 连接器页的已知限制第一条就是只发不收,读不到回复和会话。要做这件事,得用短信平台的入站回调把回复接回自己的系统,再由人或程序去平台上回复评论。问题来自 Google 联想词「review alert sms auto reply」(11 月 14 日读)。

能监测不是自己商户的 Google 评论吗?

Google 的官方通知和 Business Profile API 只对你管理的商户开放,Reddit r/smallbusiness 的讨论帖里回帖也是这个结论。公开地点的评论可以用 google_maps_reviews/reviews 读,按评论 ID 去重后自己做提醒。问题来自 Reddit r/smallbusiness 帖子。

上手步骤

第一步,在 EveryInfra 控制台建一把 API Key,放进环境变量 EVERYINFRA_API_KEY;免费目录 GET /api/v1/social/catalog 列着每项能力的参数、允许值和 price_usd,按 快速上手 跑通第一条请求。第二步,用 google_maps_reviews/search 找到要盯的地点,复制返回里带 query_place_id 的网址;应用就记下 App Store 的数字 ID 和 Google Play 的包名,各平台能力见 Google 地图评论接口、App Store 接口、Google Play 接口,Yelp 商户可以加 yelp/reviews。第三步,把上面的脚本放进 cron,DRY_RUN=1 先跑一周,看待发表里每天进几条。第四步,再接短信:把 send_sms() 换成 Twilio 的 Messages 接口,或者用 TrueDialog 的 MCP 或接口,先试运行、再真发。价格按 价格页 和目录为准,失败和空结果不扣费的对账方法见 失败退款对账。

参考资料

  1. Model Context Protocol, Specification 2026-07-28,2026-11-14 读取
  2. TrueDialog MCP, tdmcp.com (setup, tools, security),2026-11-14 读取
  3. PR Newswire, TrueDialog Launches MCP for ChatGPT, Copilot and Other AI Assistants, 2026-11-10,2026-11-14 读取
  4. TrueDialog, MCP feature page,2026-11-14 读取
  5. Twilio Blog, Introducing Twilio MCP and skills, 2026-05-07,2026-11-14 读取
  6. Twilio Docs, Twilio MCP server,2026-11-14 读取
  7. GitHub, twilio-labs/mcp,2026-11-14 读取
  8. npm registry, @twilio-alpha/mcp,2026-11-14 读取
  9. Microsoft Learn, TrueDialog MCP connector,2026-11-14 读取
  10. Google Business Profile Help, manage notifications,2026-11-14 读取
  11. Google for Developers, Business Profile real-time notifications setup,2026-11-14 读取
  12. Google for Developers, My Business Notifications API: NotificationSetting,2026-11-14 读取
  13. Google for Developers, Business Profile review data,2026-11-14 读取
  14. Apple, App Store Connect Help: user notifications,2026-11-14 读取
  15. Apple Developer Documentation, App Store Connect API: Customer Reviews,2026-11-14 读取
  16. Google for Developers, Google Play Developer API: Reply to Reviews,2026-11-14 读取
  17. Reddit r/smallbusiness, Google reviews monitoring thread,2026-11-14 读取
  18. Google for Developers, Places API Place Details,2026-11-14 读取
  19. EveryInfra, llms-full.txt (Retries and idempotency),2026-11-14 读取
  20. EveryInfra, OpenAPI specification,2026-11-14 读取
  21. Twilio Docs, Message resource,2026-11-14 读取
  22. Twilio, SMS pricing for the United States,2026-11-14 读取
  23. Twilio, phone number pricing,2026-11-14 读取
  24. TrueDialog, pricing,2026-11-14 读取
  25. Twilio Help Center, A2P 10DLC pricing and fees,2026-11-14 读取
  26. CTIA, Messaging Principles and Best Practices, May 2023 (PDF),2026-11-14 读取
  27. Kelley Drye, FCC revises TCPA consent revocation rules,2026-11-14 读取
  28. Federal Register 2026-21821, consent revocation rule, published 2026-10-26,2026-11-14 读取
  29. FCC, fact sheet DOC-424844A1, 2026-09-09 (PDF),2026-11-14 读取
  30. Bandwidth Support, 10DLC fees (updated 2026-09-16),2026-11-14 读取
  31. Twilio Docs, How long can a message be?,2026-11-14 读取
  32. HHS OCR, Manasa Health Center settlement, 2023-06-05,2026-11-14 读取
  33. HHS OCR, 2023 report to Congress on HIPAA compliance (PDF),2026-11-14 读取
  34. HHS OCR, New Vision Dental settlement, 2022-12-14,2026-11-14 读取
  35. HHS OCR, resolution agreements,2026-11-14 读取
  36. eCFR, 16 CFR Part 465 (Consumer Reviews and Testimonials),2026-11-14 读取
  37. FTC, Consumer Reviews and Testimonials Rule: Q&A,2026-11-14 读取
  38. AHRQ, What Is Patient Experience?,2026-11-14 读取
  39. AHRQ, CAHPS,2026-11-14 读取
  40. CMS, Consumer Assessment of Healthcare Providers & Systems,2026-11-14 读取
  41. Performance.gov, A-11 Section 280 explainer,2026-11-14 读取
  42. Claude Help Center, custom connectors using remote MCP,2026-11-14 读取
  43. Claude Code Docs, MCP,2026-11-14 读取
  44. Claude Code Docs, run Claude Code programmatically,2026-11-14 读取
  45. TikTok, Must Eat announcement, 2026-10-28,2026-11-14 读取
  46. The Verge, TikTok Must Eat restaurant guide,2026-11-14 读取
  47. Model Context Protocol, specification changelog,2026-11-14 读取
  48. GitHub, modelcontextprotocol releases,2026-11-14 读取

引用编号 BL-146

自有访问统计常开;Google Analytics 仅在你点「同意分析」后启用。 隐私政策