Lifecycle 状态回调接口

本文档描述了消息生命周期状态回调接口的数据结构和字段说明。系统会在消息状态发生变化时,通过 HTTP POST 方式将状态信息回调到客户配置的 URL。

回调方式

  • 请求方法: POST
  • Content-Type: application/json
  • 成功响应: HTTP 200 或 204 状态码
  • 失败重试: 如果客户未返回成功状态码,系统会自动进行重试

数据结构

1. 外层结构 (ReportLifecycles)

{ "total": 1, "rows": [ { // ReportLifecycle 对象数组 } ] }
              
              {
  "total": 1,
  "rows": [
    {
      // ReportLifecycle 对象数组
    }
  ]
}

            
此代码块在浮窗中显示
字段名 类型 说明 是否必返
total int64 总记录数
rows array 生命周期状态数据数组

2. ReportLifecycle 对象

rows 数组中的每个元素结构如下:

字段名 类型 说明 是否必返
message_id string 消息 ID
to string 接收方号码
server string 服务类型
channel string 渠道类型
itime int64 回调时间戳(秒)
custom_args map[string]any 自定义参数(发送时传入的参数)
status object 状态详情对象

3. Status 对象

状态详细信息对象:

字段名 类型 说明 是否必返
message_status string 消息状态,如: sentsent_faildelivereddelivered_failverified
status_data object 状态数据对象,详见下方
billing object 计费信息对象,详见下方
error_code int 错误码,0 表示无错误
error_detail object 错误详情对象,详见下方
kwai_extra object 快手专用扩展信息,详见下方

注意:以下字段为内部统计使用,不会回调给客户:

  • analysis - 内部统计分析字段

4. StatusData 对象

状态相关的基础数据:

字段名 类型 说明 是否必返
msg_time int64 消息创建时间戳(秒)
message_id string 消息 ID
current_send_channel string 当前发送渠道名称
template_key string 模板配置 Key
business_id string 业务 ID

注意:以下字段为敏感信息或内部字段,已被过滤,不会回调给客户:

  • message_content - 消息内容(敏感信息)
  • parts - 消息分片数(内部字段)
  • msg_type - 消息类型(内部字段)
  • protocol_type - 协议类型(内部字段)
  • supplier_ids - 供应商 ID(敏感信息)

5. Billing 对象

计费信息(仅在有计费数据时返回):

字段名 类型 说明 是否必返
cost float64 费用金额(保留 4 位小数)
currency string 币种,固定为 "USD"

注意:以下字段为内部计费字段,不会回调给客户:

  • cost10000 - 内部计费字段(万分之一单位)
  • sender_cost10000 - 发送方成本(万分之一单位)

6. ErrorDetail 对象

错误详情(仅在发生错误时返回):

字段名 类型 说明 是否必返
message string 错误消息描述
channel_code string 渠道返回的原始错误码
channel_message string 渠道返回的原始错误消息

7. KwaiExtra 对象

快手客户专用扩展信息(仅在送达状态且为快手客户时返回):

字段名 类型 说明 是否必返
delivered_time int64 送达时间戳(毫秒)
parts int 计费条数
duration int64 接听时长(秒),仅语音消息有此字段

消息状态说明

常见的消息状态值:

状态值 说明
sent 已发送到渠道
sent_fail 发送失败
delivered 已送达到用户终端
delivered_fail 送达失败
verified 用户已验证(如 OTP 验证码被使用)

回调示例

示例 1:消息成功送达

{ "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": "delivered", "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": "123456789",
      "to": "+8613800138000",
      "server": "sms",
      "channel": "sms",
      "itime": 1701234567,
      "custom_args": {
        "order_id": "ORDER123",
        "user_id": "USER456"
      },
      "status": {
        "message_status": "delivered",
        "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
      }
    }
  ]
}

            
此代码块在浮窗中显示

示例 2:消息发送失败

{ "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", "channel_code": "INVALID_NUMBER", "channel_message": "The phone number format is invalid" } } } ] }
              
              {
  "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",
          "channel_code": "INVALID_NUMBER",
          "channel_message": "The phone number format is invalid"
        }
      }
    }
  ]
}

            
此代码块在浮窗中显示

示例 3:消息送达失败(带计费信息)

{ "total": 1, "rows": [ { "message_id": "123456791", "to": "+8613800138002", "server": "sms", "channel": "sms", "itime": 1701234570, "custom_args": { "campaign": "new_year_promo" }, "status": { "message_status": "delivered_fail", "status_data": { "msg_time": 1701234562, "message_id": "123456791", "current_send_channel": "CHANNEL_C", "template_key": "marketing", "business_id": "1001" }, "billing": { "cost": 0.0045, "currency": "USD" }, "error_code": 5002, "error_detail": { "message": "Phone number unreachable", "channel_code": "UNREACHABLE", "channel_message": "Subscriber absent" } } } ] }
              
              {
  "total": 1,
  "rows": [
    {
      "message_id": "123456791",
      "to": "+8613800138002",
      "server": "sms",
      "channel": "sms",
      "itime": 1701234570,
      "custom_args": {
        "campaign": "new_year_promo"
      },
      "status": {
        "message_status": "delivered_fail",
        "status_data": {
          "msg_time": 1701234562,
          "message_id": "123456791",
          "current_send_channel": "CHANNEL_C",
          "template_key": "marketing",
          "business_id": "1001"
        },
        "billing": {
          "cost": 0.0045,
          "currency": "USD"
        },
        "error_code": 5002,
        "error_detail": {
          "message": "Phone number unreachable",
          "channel_code": "UNREACHABLE",
          "channel_message": "Subscriber absent"
        }
      }
    }
  ]
}

            
此代码块在浮窗中显示

示例 4:快手客户语音消息送达

{ "total": 1, "rows": [ { "message_id": "123456792", "to": "+8613800138003", "server": "voice", "channel": "voice", "itime": 1701234575, "status": { "message_status": "delivered", "status_data": { "msg_time": 1701234565, "message_id": "123456792", "current_send_channel": "VOICE_CHANNEL_A", "template_key": "voice_verify", "business_id": "2001" }, "billing": { "cost": 0.012, "currency": "USD" }, "error_code": 0, "kwai_extra": { "delivered_time": 1701234575000, "parts": 1, "duration": 45 } } } ] }
              
              {
  "total": 1,
  "rows": [
    {
      "message_id": "123456792",
      "to": "+8613800138003",
      "server": "voice",
      "channel": "voice",
      "itime": 1701234575,
      "status": {
        "message_status": "delivered",
        "status_data": {
          "msg_time": 1701234565,
          "message_id": "123456792",
          "current_send_channel": "VOICE_CHANNEL_A",
          "template_key": "voice_verify",
          "business_id": "2001"
        },
        "billing": {
          "cost": 0.012,
          "currency": "USD"
        },
        "error_code": 0,
        "kwai_extra": {
          "delivered_time": 1701234575000,
          "parts": 1,
          "duration": 45
        }
      }
    }
  ]
}

            
此代码块在浮窗中显示

注意事项

  1. 字段返回规则

    • 所有标记为 omitempty 的字段,在值为空或零值时不会出现在返回的 JSON 中
    • 敏感信息和内部字段已在回调前被过滤或清空
  2. 安全性

    • 消息内容(message_content)不会回调给客户
    • 供应商 ID(supplier_ids)等敏感信息已被过滤
    • 内部计费字段(cost10000sender_cost10000)不会回调
  3. 接收要求

    • 客户的回调接口必须在5 秒内返回响应
    • 必须返回 HTTP 200 或 204 状态码表示接收成功
    • 如果返回其他状态码或超时,系统将进行自动重试
  4. 重试机制

    • 回调失败后会自动进行重试
    • 重试间隔逐步增加
    • 重试期间数据会保存在 Redis 中
  5. 时间戳说明

    • itime:回调发生的时间戳,单位为秒
    • msg_time:消息创建的时间戳,单位为秒
    • delivered_time:快手专用字段,送达时间戳,单位为毫秒
  6. 自定义参数

    • custom_args 字段会原样返回发送消息时传入的自定义参数
    • 如果发送时未传入自定义参数,此字段不会出现在回调数据中

错误码参考

常见错误码说明(具体错误码请参考错误码文档):

错误码 说明
0 无错误,操作成功
4001 号码格式错误
4002 号码不存在
5001 渠道拒绝
5002 用户不可达
6001 网络超时

更详细的错误码说明请参考单独的错误码文档。

更新日志

  • 2024-01: 初始版本
  • 添加了 kwai_extra 字段支持快手客户
  • 过滤敏感信息字段,增强安全性
icon
联系销售