# SMS Hub · 验证码取码接口（Agent 指南）

本服务把 iPhone 收到的验证码短信实时中转到云端（上报由手机端自动完成，取码方无需关心）。
取码只需要下面这一个接口。

- Base URL: https://sms.kukukala.com
- 认证 token（ACCESS_TOKEN）由服务管理员另行提供，本页不含任何秘密。

## 取码：POST /sms-access

```bash
curl -s -X POST https://sms.kukukala.com/sms-access \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cellphone":"13671171287","received_later_than":"2026-08-22T04:35:34Z"}'
```

请求体（JSON）：

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cellphone | string | 是 | 收信手机号，纯数字，可带 `+` 前缀 |
| received_later_than | string/number | 是 | 时间下限：只返回**入库时间晚于**该时刻的最新一条（严格 `>`，毫秒精度）。推荐 `date -u +%Y-%m-%dT%H:%M:%SZ` 生成 UTC ISO 8601；也接受带时区偏移的 ISO 8601 或 Unix 时间戳（10 位秒 / 13 位毫秒） |

响应（200）：

```json
{"found":true,"code":"486413","received_at":"2026-08-22T04:35:34.583Z","body":"【腾讯科技】您本次的腾讯统一身份验证码是486413 ，请在5分钟内完成验证。"}
{"found":false,"code":null}
```

- `code`：提取好的验证码（字符串；短信里没有可识别数字时为 null）
- `body`：短信原文（已解密），可用来确认这条短信确实来自目标服务
- `received_at`：入库时间（UTC，≈短信实际接收时间，转发延迟通常数秒）

## 标准取码流程

1. `T=$(date -u +%Y-%m-%dT%H:%M:%SZ)` —— **先记时间**
2. 触发目标服务发码（在网页/App 上点"发送验证码"）
3. 每 5 秒调一次 /sms-access，`received_later_than` 用 T
4. `found:true` → 直接用 `code`；约 2 分钟取不到则放弃

关键：**先取 T 再触发发码**，否则可能拿到上一条旧验证码。

## 轮询脚本模板

```bash
PHONE=13671171287
T=$(date -u +%Y-%m-%dT%H:%M:%SZ)
# ... 此处触发目标服务发送验证码 ...
for i in $(seq 1 24); do
  resp=$(curl -s -X POST https://sms.kukukala.com/sms-access \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"cellphone\":\"$PHONE\",\"received_later_than\":\"$T\"}")
  code=$(echo "$resp" | python3 -c 'import json,sys;print(json.load(sys.stdin).get("code") or "")')
  [ -n "$code" ] && { echo "$code"; exit 0; }
  sleep 5
done
echo "超时未取到验证码" >&2; exit 1
```

## 错误响应

| HTTP | body | 含义 |
|---|---|---|
| 401 | `{"error":"invalid_token"}` | token 缺失/错误 |
| 400 | `{"error":"invalid_request","field":"..."}` | 字段非法，`field` 指明具体字段 |
| 500 | `{"error":"internal"}` | 服务端故障，可重试 |

## 其他说明

- 短信记录保留 7 天，过期自动删除；历史旧码查不到是正常的
- `found:true` 但 `code` 为 null 时，读 `body` 原文人工辨码
- 入库时间由服务器统一打（UTC 毫秒精度），与查询阈值同格式同时区，比较可靠
