接口受理成功不等于手机收到 调用预警通知API提交一条告警后,接口返回code=2仅代表平台受理成功,短信进入运营商网关后还要经过网关路由、落地网元投递、终端上行多个环节,这期间可能出现延迟、被拦截,或因号码停机、关机而无法接收。语音呼叫也…
接口受理成功不等于手机收到
调用预警通知API提交一条告警后,接口返回code=2仅代表平台受理成功,短信进入运营商网关后还要经过网关路由、落地网元投递、终端上行多个环节,这期间可能出现延迟、被拦截,或因号码停机、关机而无法接收。语音呼叫也可能无人接听、被拒接,或者接通后通话时间极短,对方根本没听清内容。很多团队只看接口返回的code就认为告警已经发出,直到事后复盘、业务方投诉时才发现负责人压根没收到电话和短信,故障已经扩大了一两个小时。要判断告警是否真正触达,必须依赖状态回执。互亿无线预警通知API为每条短信提供毫秒级状态回执,支持30余种状态码,帮助运维人员确认送达情况并定位失败原因。
本文说明回执的产生时机、常见状态码含义,以及在自己的系统中接收、解析并处理回执的工程做法,让告警从"发出去"变成"被看到"。
回执状态码体系
回执随短信生命周期逐步更新,从网关受理到终端投递会返回不同状态。常见状态如下:
| 状态码 | 含义 | 后续动作 |
|---|---|---|
| DELIVRD | 已送达手机终端 | 记录留档,关闭通知任务 |
| DELIVERED | 终端成功接收 | 记录留档,无需处理 |
| UNDELIV | 无法送达 | 触发换通道或重发 |
| EXPIRED | 超时未送达 | 检查号码有效性 |
| REJECTD | 被网关拒绝 | 检查内容或签名 |
| UNKNOWN | 状态暂未确定 | 等待下一次回执 |
语音通道的回执关注呼叫结果,包括振铃中、接听、未接、拒接以及通话时长等字段。通话时长可以作为告警是否被注意到的参考:如果一通语音电话响了很久没人接,说明负责人可能在休息或没带手机;如果接听后通话只有几秒,可能对方没听清就挂断了。结合这些字段,就能判断要不要重呼、要不要升级通知到备班。
接收回执的两种方式
- 回调推送:在控制台配置回执回调地址,平台在状态变更时主动向你的服务POST推送,适合实时处理与自动闭环,延迟低。
- 主动查询:凭提交时返回的smsid调用回执查询接口,适合事后对账、补单,或回调地址暂时不可用后的补偿查询。
解析回执字段
回调推送的请求体通常包含smsid、mobile、状态码、回执时间等字段。用Python接收并落库的示例:
from flask import Flask, request
app = Flask(__name__)
@app.route("/sms/report", methods=["POST"])
def report():
body = request.form
save_report(body.get("smsid"), body.get("mobile"), body.get("status"))
return "0"
def save_report(smsid, mobile, status):
print(f"回执: smsid={smsid} mobile={mobile} status={status}")
回执处理的工程实践
回执到达后,建议按以下逻辑处理:
- 以smsid为主键更新本地告警记录,避免重复处理同一回执造成状态回退。
- 状态为已送达时,关闭本次告警的通知任务,不再继续重发,避免打扰。
- 状态为无法送达或被拒时,自动切换语音或闪信通道重发。
- 语音未接时,利用未接自动重呼一次的机制,重呼仍失败后升级通知到备班人员。
需要注意,回执是异步到达的,提交接口的响应不应阻塞等待回执,可在提交后立即返回,由回调异步更新状态。对于P0、P1告警,可结合5秒首发失败自动换通道策略:短信回执迟迟不返回已送达时,系统主动发起语音呼叫,避免被动等待运营商投递。
一个回执排查的真实案例
某团队曾反映告警短信"时灵时不灵",复盘时调出回执发现:大部分告警回执是DELIVRD,只有少数几条是UNDELIV,而这几条恰好都发给了同一个已经离职但未更新通讯录的号码。把号码从值班列表中移除后,问题消失。这个案例说明,光看发送成功不够,还要逐号码看回执,才能发现通讯录里的失效联系人。互亿无线控制台可按日期导出回执记录,方便做这类排查。
互亿无线提供毫秒级回执与30余种状态码,注册后可在控制台配置回调地址并查看历史回执记录。注册免费试用,用测试条数跑通一条告警从提交到送达回执的完整链路。




