Table of Contents
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按违规序号补偿,不会把首次警告补偿成结束通知。