16.11 声网视频审核结果回调

POST /tieup/api/v1/webhooks/shengwang/video-moderation
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

说明:该接口只接收声网视频审核结果回调,不混入普通 RTC 频道事件。声网视频审核回调不需要服务端验签或解密,服务端收到后先解析表单字段 callbackData,再进行 URL 解码和 JSON 解码。解析结果为违规时,服务端会保存违规信息和 event_type=12 审核事件;第一次只发送警告,第二次复用正常完成流程入账、写 event_type=8 结束事件、解散声网频道并通过融云系统消息通知双方。正常或无法确认的结果只写入专用回调文件日志,不写入审核数据库、事件表或上传记录,也不投递截图任务。违规截图由异步任务使用七牛服务端抓取,原 snapshot_url 不变,事件表只保存不含域名的七牛对象 Key。

请求头:

参数 类型 必填 说明
Content-Type string 是 固定为 application/x-www-form-urlencoded,声网实际可能附带 charset=UTF-8

请求参数:

参数 类型 必填 说明
signature string 否 声网表单回调携带的签名字段;服务端不使用该字段验签
callbackData string 是 URL 编码后的审核 JSON 字符串,服务端先 URL 解码再 JSON 解码
businessId string 否 声网业务标识,原始回调日志保留
secretId string 否 声网回调标识,原始回调日志保留;不作为服务端解密密钥

callbackData 解码后的常用字段:

字段 类型 说明
antispam.taskId string 审核任务 ID,用于回调幂等
antispam.status integer 审核处理状态
antispam.suggestion integer/string 审核建议;0 通常表示正常
antispam.label integer/string 审核标签;0 通常表示正常
antispam.riskDescription string 风险描述,例如 正常
antispam.name string(JSON) 二层 JSON 字符串,解码后包含预约、房间、频道和用户信息
antispam.name.reservation_id string 视频预约单号
antispam.name.room_id string 视频通话房间号
antispam.name.cname string 声网频道名
antispam.name.uid integer/string 声网 UID
antispam.name.role string 违规侧:fan 或 artist

请求体示例(原始 form-urlencoded):

signature=2f0fb37cdadce79a6467a4f44a535b9f&callbackData=%7B%22antispam%22%3A%7B%22taskId%22%3A%22idvch5smvjvatkasrugn12ij0030an28%22%2C%22status%22%3A2%2C%22suggestion%22%3A0%2C%22censorType%22%3A0%2C%22name%22%3A%22%7B%5C%22room_id%5C%22%3A%5C%22VR202608201624097443453178%5C%22%2C%5C%22reservation_id%5C%22%3A%5C%22VC202608201624093741897120%5C%22%2C%5C%22role%5C%22%3A%5C%22fan%5C%22%2C%5C%22uid%5C%22%3A%5C%221793922844%5C%22%2C%5C%22cname%5C%22%3A%5C%22sw_vc_vc202608201624093741897120%5C%22%7D%22%2C%22riskDescription%22%3A%22%E6%AD%A3%E5%B8%B8%22%7D%7D&businessId=c90afef3e56133117567fb523458aa6c&secretId=4f6bf56e3eff098ee59b95f15fa515e6

callbackData 解码后的示例:

{
  "antispam": {
    "taskId": "idvch5smvjvatkasrugn12ij0030an28",
    "status": 2,
    "suggestion": 0,
    "label": 0,
    "riskDescription": "正常",
    "name": "{\"room_id\":\"VR202608201624097443453178\",\"reservation_id\":\"VC202608201624093741897120\",\"role\":\"fan\",\"uid\":\"1793922844\",\"cname\":\"sw_vc_vc202608201624093741897120\"}"
  }
}

响应字段:

字段 类型 说明
code integer 响应码,成功为 200
message string 响应提示
data.ack boolean 是否确认接收回调;视频审核回调解析失败或未知结果也会确认接收并只记录日志
data.verified boolean 为兼容既有响应保留,视频审核回调固定为 true,不代表执行了签名校验
data.verification_mode string 固定为 not_required,表示该视频审核回调不需要验签或解密
data.persisted boolean 是否写入视频审核违规日志;正常结果为 false
data.moderation_no string 视频审核违规日志编号;正常结果不返回
data.violation_sequence integer 同一预约整场违规次数;只处理 1 次警告和 2 次结束通话,第三次及以后回调返回跳过
data.ended boolean 本次回调是否结束通话
data.status string 本地处理结果:warning、success、skipped 或 failed
data.booking_no string 关联预约单号,未定位时可能为空

响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "ack": true,
    "verified": true,
    "verification_mode": "not_required",
    "moderation_no": "VM2026070412000012345678",
    "status": "success",
    "booking_no": "VC202607040001",
    "ended_at": "2026-07-04 12:03:20"
  }
}

融云系统消息:

正常审核结果只写入回调文件日志,不写入 tieup_video_call_moderation_log,也不创建系统消息。违规结果按同一预约整场累计:第一次给双方发送警告,第二次结束通话。系统消息统一使用 business_type=feedback、source_type=video_call_violation,通过融云自定义类型 Tieup:SysMsg 触达。

第一次违规时,违规方收到“本次通话你涉嫌违规,再次违规将结束通话”,另一方收到“本次通话对方涉嫌违规,再次违规将结束通话”;payload 的 action=video_call_moderation_warning。

第二次违规时,违规方收到“本次通话你涉嫌违规,通话已结束”,另一方收到“本次通话对方涉嫌违规,通话已结束”;payload 的 action=force_leave_video_call,APP 收到后立即调用声网 SDK 退出频道。

{
  "business_type": "feedback",
  "source_type": "video_call_violation",
  "source_no": "VC202607040001",
  "payload": {
    "action": "force_leave_video_call",
    "reason_code": "porn",
    "reason_label": "涉黄",
    "booking_no": "VC202607040001",
    "room_no": "VR202607040001",
    "channel_name": "sw_vc_VC202607040001",
    "violation_side": "fan",
    "violation_sequence": 2,
    "ended_by": "moderation"
  }
}

处理规则:

  • 正常结果不写入审核日志;违规日志按 booking_no 记录 violation_sequence,同一 taskId 重复回调按唯一事件幂等。
  • 第一次违规只发送双方警告,不改变预约、房间或收入状态。
  • 第二次违规会发送双方结束通知并强制中断声网频道;本地预约仍在通话中时更新为 4=已完成并正常入账,已结束或已完成时保持本地状态不变但仍继续重试声网强制中断。
  • 第二次违规在预约仍为 3=通话中 时复用正常完成流程,更新 tieup_video_call_booking.status=4、ended_at、actual_duration_seconds,更新房间 room_status=5、ended_at,并按预约完整糖果金额入账;本地已结束或已完成时不重复结算。
  • 同一预约最多保存两条违规业务记录和四条违规系统消息:第一次写入 event_type=12 并发送双方警告,第二次写入 event_type=12、正常结束 event_type=8 并发送双方结束通知;第三次及以后只保留原始回调文件日志,返回 reason=violation_limit_reached,不新增业务记录、消息或踢人调用。
  • 审核截图转存状态使用 snapshot_transfer_status(0=待转存,1=成功,2=失败,3=跳过);成功后 tieup_video_call_event.moderation_snapshot_path 只保存七牛对象 Key,tieup_upload_record 以 business_module=video_call_moderation、business_id=moderation_no 留存统一上传记录。自动转存最多重试 12 次,指定 moderation_no 的人工补偿可继续重试。
  • 原始回调排查日志文件为 runtime/logs/tieup-shengwang-video-moderation-callback-YYYY-MM-DD.log。Windows PowerShell 可执行 Get-Content .\\runtime\\logs\\tieup-shengwang-video-moderation-callback-$(Get-Date -Format 'yyyy-MM-dd').log -Wait,Docker 可执行 docker compose exec app sh -lc 'tail -f /opt/www/runtime/logs/tieup-shengwang-video-moderation-callback-$(date +%F).log';日志保留完整 raw_body,结构化解码字段会脱敏签名、secretId 和证据 URL 参数,日志启用前的历史请求无法恢复原始 body。
  • 声网频道解散使用频道管理的加入权限封禁规则;调用失败不回滚本地状态,记录 dissolve_status=2 后由 video-moderation-repair 补偿重试。
  • 警告或结束系统消息通知失败分别记录 notify_status=2/4,由 video-moderation-repair 按违规序号补偿,不会把首次警告补偿成结束通知。