回调配置说明
本节介绍如何配置 EngageLab OTP 的回调地址,以及相关的安全校验机制,确保回调数据的可靠性与安全性。
回调地址配置与校验
配置回调地址后,EngageLab OTP 会自动向该地址发送一次 HTTP POST 请求,用于校验接口的可用性。您的服务需在 3 秒内返回 HTTP 200 状态码,否则系统会认为该地址不可用。
注意:
为确保能够正常接收回调数据,请将 119.8.170.74 和 114.119.180.30 加入您的服务器防火墙白名单。
请求示例
假设您的回调地址为 https://example.engagelabotp.callback.com,系统会发送如下请求:
curl -X POST https://example.engagelabotp.callback.com -d ''
响应要求
您的服务只需返回 HTTP 200 状态码,无需返回任何内容。例如:
HTTP/1.1 200 OK
Content-Length: 0
注意:
回调地址校验仅判断 HTTP 状态码,不要求返回具体报文内容。请确保您的服务接口能在 3 秒内正确响应 200。
回调安全机制
为保障回调数据的安全性和来源可信,EngageLab OTP 支持多种安全校验方式。
用户名与密钥校验(可选)
- 可选配置。如果设置了用户名,必须同时设置密钥。
- 配置后,EngageLab 在每次回调请求的 HTTP Header 中添加
X-CALLBACK-ID字段,格式如下:
X-CALLBACK-ID: timestamp={timestamp};nonce={nonce};username={username};signature={signature}
- 其中:
timestamp:回调发送的时间戳nonce:随机数username:您配置的用户名signature:签名信息,计算方法如下
签名计算方式(Python 示例)
import hashlib, hmac
def verify(username, secret, timestamp, nonce, signature):
return signature == hmac.new(
key=secret.encode(),
msg=f'{timestamp}{nonce}{username}'.encode(),
digestmod=hashlib.sha256
).hexdigest()
- 服务端可用上述方式校验回调请求的合法性。
Authorization 鉴权(可选)
- 如果您的回调接口需要鉴权(如 Basic Auth、Bearer Token 等),可在配置时填写 Authorization 信息。
- EngageLab 在请求时会自动携带该 Authorization 字段,便于您的服务校验请求身份。
回调事件说明
消息状态
消息状态用于追踪每一条消息在生命周期中的状态变化。用于实时了解消息的发送、送达、验证等各个环节的进展,便于统计分析、异常处理和用户体验优化。
| 事件标识 | 说明 |
|---|---|
| plan | 消息计划发送,进入待发送队列 |
| target_valid | 目标号码有效 |
| target_invalid | 目标号码无效 |
| sent | 消息成功发送 |
| sent_failed | 消息发送失败 |
| delivered | 消息送达用户设备 |
| delivered_failed | 消息已发送,但未能送达用户设备 |
| verified | 用户已成功完成 OTP 验证 |
| verified_failed | 用户验证失败 |
| verified_timeout | 用户未在规定时间内完成验证,已超时 |
回调数据结构
外层结构
{
"total": 1,
"rows": [
{
// ReportLifecycle 对象
}
]
}
| 字段名 | 类型 | 说明 |
|---|---|---|
| total | int | 本次回调包含的数据条数 |
| rows | array | 生命周期状态数据数组 |
ReportLifecycle 对象
| 字段名 | 类型 | 说明 |
|---|---|---|
| message_id | string | 消息唯一 ID |
| to | string | 接收方号码 |
| server | string | 服务类型(如 otp) |
| channel | string | 渠道类型 |
| itime | int64 | 回调时间戳(秒) |
| custom_args | object | 自定义参数(如有传入则回传) |
| status | object | 状态详情对象 |
status 对象
| 字段名 | 类型 | 说明 |
|---|---|---|
| message_status | string | 消息当前状态(见下表) |
| status_data | object | 状态数据对象 |
| billing | object | 计费信息对象(有计费时返回) |
| error_code | int | 错误码,0 表示无错误 |
| error_detail | object | 错误详情(发生错误时返回) |
status_data 对象
| 字段名 | 类型 | 说明 |
|---|---|---|
| msg_time | int64 | 消息创建时间戳(秒) |
| message_id | string | 消息 ID |
| current_send_channel | string | 当前发送渠道名称 |
| template_key | string | 模板配置 Key |
| business_id | string | 业务 ID |
billing 对象(有计费时返回)
| 字段名 | 类型 | 说明 |
|---|---|---|
| cost | float64 | 费用金额 |
| currency | string | 币种,固定为 "USD" |
一般仅 sent 阶段的消息包含计费信息。
error_detail 对象(发生错误时返回)
| 字段名 | 类型 | 说明 |
|---|---|---|
| message | string | 错误消息描述 |
示例:消息发送成功
{
"total": 1,
"rows": [
{
"message_id": "123456789",
"to": "+8613800138000",
"server": "sms",
"channel": "sms",
"itime": 1701234567,
"custom_args": {
"order_id": "ORDER123",
"user_id": "USER456"
},
"status": {
"message_status": "sent",
"status_data": {
"msg_time": 1701234560,
"message_id": "123456789",
"current_send_channel": "CHANNEL_A",
"template_key": "verify_code",
"business_id": "1001"
},
"billing": {
"cost": 0.005,
"currency": "USD"
},
"error_code": 0
}
}
]
}
示例:消息发送失败
{
"total": 1,
"rows": [
{
"message_id": "123456790",
"to": "+8613800138001",
"server": "sms",
"channel": "sms",
"itime": 1701234568,
"status": {
"message_status": "sent_fail",
"status_data": {
"msg_time": 1701234561,
"message_id": "123456790",
"current_send_channel": "CHANNEL_B",
"template_key": "verify_code",
"business_id": "1001"
},
"error_code": 4001,
"error_detail": {
"message": "Invalid phone number"
}
}
}
]
}
消息通知
消息通知是指系统级的业务事件或告警。用于提醒业务方关注服务运行状态、余额、模板审核等重要信息,便于及时处理和风险预警。
| 事件标识 | 说明 |
|---|---|
| insufficient_verification_rate | 验证率低于设定阈值 |
| insufficient_balance | 账户余额不足 |
| template_audit_result | 模板审核结果的通知 |
示例
{
"total": 1,
"rows": [{
"server": "otp",
"itime": 1712458844,
"notification": {
"event": "insufficient_balance",
"notification_data": {
"business_id": "1744569418236633088",
"remain_balance": -0.005, // 当前余额;
"balance_threshold": 2 // 告警阈值;
}
}
}]
}
消息响应
消息响应主要指与用户或外部系统交互时的回调响应事件。
| 事件标识 | 说明 |
|---|---|
| uplink_message | 用户通过短信等方式回复的上行消息内容 |
示例
{
"total": 1,
"rows": [
{
"server": "otp",
"itime": 1741083306,
"message_id": "0",
"business_id": "0",
"response": {
"event": "uplink_message",
"response_data": {
"message_sid": "SM1234567890",
"account_sid": "AC1234567890",
"from": "+1234567890",
"to": "+0987654321",
"body": "Hello, it's time to struggle!"
}
}
}
]
}
系统事件
系统事件涵盖与账号、模板、API 调用等相关的操作行为。便于对账号登录、密钥变更、API 调用等关键操作进行监控、审计和自动化处理。
| 事件标识 | 说明 |
|---|---|
| account_login | 账号登录相关操作通知 |
| key_manage | 密钥变更、管理等相关操作通知 |
| msg_history | 消息历史查询相关操作通知 |
| template_manage | 模板新增、修改、删除等操作通知 |
| api_call | API 接口调用相关操作通知 |
回调数据结构
外层结构
{
"total": 1,
"rows": [
{
// 系统事件对象
}
]
}
| 字段 | 类型 | 说明 |
|---|---|---|
| total | int64 | 本次回调包含的事件总数 |
| rows | array | 系统事件对象数组 |
系统事件对象
| 字段 | 类型 | 说明 |
|---|---|---|
| server | string | 固定为 "otp" |
| itime | int64 | 事件发生时间戳(秒) |
| system_event | object | 系统事件内容 |
system_event 对象
| 字段 | 类型 | 说明 |
|---|---|---|
| event | string | 事件类型 |
| data | object | 事件数据 |
data 对象
| 字段 | 类型 | 说明 |
|---|---|---|
| business_id | string | 业务 ID |
| org_id | string | 组织 ID |
| operator | object | 操作者信息 |
operator 对象
| 字段 | 类型 | 说明 |
|---|---|---|
| string | 操作者邮箱(如有) | |
| api_key | string | API Key(如有) |
| ip_address | string | 操作 IP |
请求结构
{
"total": 1,
"rows": [
{
"server": "otp",
"itime": 1694012345,
"system_event": {
"event": "account_login",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"api_key": "api-xxxx",
"ip_address": "1.2.3.4"
},
"account_login": {
"action": "login_success"
}
}
}
}
]
}
账号登录事件
| 字段 | 类型 | 说明 |
|---|---|---|
| action | string | 成功登录/登录失败/登出 |
| fail_reason | string | 登录失败原因,仅 login_failed 时返回 |
示例
{
"event": "account_login",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"account_login": {
"action": "login_success"
}
}
}
模板管理事件
| 字段 | 类型 | 说明 |
|---|---|---|
| action | string | 创建模板/更新模板/删除模板 |
| template_id | string | 模板 ID |
| template_name | string | 模板名称 |
示例
{
"event": "template_manage",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"template_manage": {
"action": "update template",
"template_id": "tmpl-456",
"template_name": "Verification Code"
}
}
}
密钥管理事件
| 字段 | 类型 | 说明 |
|---|---|---|
| action | string | 新建密钥/更新密钥/删除密钥/查看密钥 |
| api_key | string | API Key |
| description | string | 描述(可选) |
示例
{
"event": "key_manage",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"key_manage": {
"action": "create",
"api_key": "apikey-789",
"description": "新建密钥"
}
}
}
API 调用事件
| 字段 | 类型 | 说明 |
|---|---|---|
| api_path | string | 接口路径 |
| method | string | HTTP 方法 |
示例
{
"event": "api_call",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"api_key": "apikey-789",
"ip_address": "1.2.3.4"
},
"api_call": {
"api_path": "/api/v1/messages/send",
"method": "POST"
}
}
}
