### 离线接口获取地址 http://as.dun.163.com/v4/image/callback/results (http://as.dun.163.com/v4/image/callback/results) ### 接口描述 通过resultType字段区分机审和人审结果。 1.在线检测接口结果中嫌疑的数据,会进行离线分析和人工审核,这些数据的离线结果需要客户通过该接口进行定时获取。获取离线处理的数据后,下次调用,不会再次返回之前获取过的离线数据。 2.异步检测,离线接口获取异步检测结果,如果使用主动回调方式请文本在线提交接口使用v4.1版本及以上,增加reultType字段区分机审和人审结果。异步检测结果默认保留4小时,超过4小时不获取会失效。 3.接口对请求频率做了限制,请求频率过快服务器会拒绝处理,最快请求频率是10s20次,接口一次最多返回200个结果,建议30秒获取一次。建议您使用POST请 求, 且仅接受 application/x-www-form-urlencoded 编码格式。 V3图片人工审核结果接口文档请点此下载查看 (https://nos.netease.com/cloud-website-bucket/8ccf115cbbaf8dd774b3942c127ddcd0.pdf) v4图片人工审核结果接口文档请点此下载查看 (/help/documents/545683627761545216) ### 接口请求频率 小于10s/20次,请求频率过快服务器会拒绝处理。 ### 请求参数 该接口参数与请求公共参数一致,详细见 请求公共参数 (/help/documents/150429219582824448) 参数名称 | 类型 | 是否必选 | 最大长度 | 描述 version | String | Y | 4 | 接口版本v4.1 ### 响应结果 响应字段如下,响应通用字段已省略,详细见 响应通用字段 (/help/documents/150429240227188736): 参数名称 | 类型 | 描述 code | Number | 接口调用状态,200:正常,其他值:调用出错,返回码见 响应返回码 (/help/documents/150429283139112960) msg | String | 结果说明,如果接口调用出错,那么返回错误描述,成功返回 ok result | 数组 | 图片人工审核结果,antispam数组数据结构 antispam 数组数据结构 参数名称 | 类型 | 描述 name | String | 图片名称(或图片标识) taskId | String | 在线接口检测返回的数据请求标识,可以根据该标识查询数据最新结果 action | Number | 建议动作,2:建议删除,0:建议通过 resultType | Number | 结果方式 1:机审结果,2:人审结果 censorSource | Number | 审核来源,0:易盾人审,1:客户人审,2:易盾机审 版本支持v4及以上 censorRound | Number | 审核轮数,1:第1轮人审,2:第2轮人审,3:第3轮人审,4:第4轮人审,5:第5轮人审,未设置审核模式默认返回0 censorTime | Number | 人工审核完成时间,毫秒单位时间戳(13位) hidden | Boolean | 否 hiddenFormat | String | 否 frameSize | Number | 长图、gif图片拆帧后的分帧数,默认为1 labels | json数组 | 分类信息 censorLabels | json数据 | 支持在智能审核系统自定义标签分类信息 overAllMarkDesc | String | 整体审核备注 detailMarks | Object[] | 细节标注 labels 数据结构 参数名称 | 类型 | 描述 label | Number | 分类信息,100:色情,110:性感低俗,200:广告,210:二维码,260:广告法,300:暴恐,400:违禁,500:涉政,800:恶心类,900:其他,1100:涉价值观 subLabels | json数组 | 细分类信息,可能包含多个,可能为空 level | Number | 分类级别,0:正常,1:不确定,2:确定 rate | Number | 置信度分数,0-1之间取值,1为置信度最高,0为置信度最低。若level为正常,置信度越大,说明正常的可能性越高。若level为不确定或确定,置信度越大,说明垃圾的可能性越高 subLabels 数据结构 参数名称 | 类型 | 描述 subLabel | Number | 细分类,详细编码请参考下方对应细分类编码 对照表 rate | Number | 置信度分数,0-1之间取值,1为置信度最高,0为置信度最低 details | json对象 | 命中详情说明hitInfos:命中详细信息,针对subLabel的补充说明 details 数据结构 参数名称 | 类型 | 描述 hitInfos | json数组 | 针对命中sublabel的补充说明 anticheatInfo | String | 命中反作弊相关策略,hitType为反垃圾命中类型,1:数据异常 2:行为模型 3:设备模型 4:业务类型 5:校验异常 6:模拟器 7:越狱或root 8:浏览器异常 9:ip异常 10:易盾黑名单 11:自定义黑名单 12:自定义白名单 imageTagInfos | json数组 | 命中标签详细信息,对于返回的hintInfo的解释说明,可能为空 imageListInfos | json数组 | 自定义图片/关键词名单信息,命中自定义添加的图片或关键词名单时返回 hitLocationInfos | json数组 | 命中详情位置信息,当前人脸、logo、关键词支持位置信息返回 imageTagInfos 数据结构 参数名称 | 类型 | 描述 tagName | String | hinInfo中可返回的图片中包含的可识别内容 tagGroup | String | tagName对应的分组名称,用于对tageName的解释 imageListInfos 数据结构 参数名称 | 类型 | 描述 type | Number | type为1时为自定义图片名单,type为2时为自定义敏感词名单 url | String | 该图片命中自定义图片名单对应原始添加的根源图片url hitCount | Number | 历史针对该数据源图片命中所有次数 word | String | 该图片命中的自定义敏感词 entity | String | 图片检测命中的自定义名单内容 releaseTime | Number | 名单解封时间,时间戳单位毫秒 tagName | String | 自定义名单标识 tagGroup | String | 自定义名单分组标识 hitLocationInfos 数据结构 参数名称 | 类型 | 描述 hitInfo | String | 命中详情 x1 | Number | 位置信息,对应目标矩形左上角横坐标相对坐标 y1 | Number | 位置信息,对应目标矩形左上角纵坐标相对坐标 x2 | Number | 位置信息,对应目标矩形右下角横坐标相对坐标 y2 | Number | 位置信息,对应目标矩形右下角纵坐标相对坐标 [md-attention] #### 自定义细分类 易盾支持sublabel自定义细分类过检并返回,如有需求,可联系您的专属安全策略经理添加。 detailMarka数据结构 参数名称 | 类型 | 描述 position | Object[] | 标注标签列表 censorLabels | Object[] | 标注备注 desc | String | 标注备注描述 position数据结构 参数名称 | 类型 | 描述 x | folat | 位置信息,对应目标矩形左上角横坐标相对坐标 y | float | 位置信息,对应目标矩形左上角纵坐标相对坐标 censorLabels 数据结构 |code|String|标签标识| |desc|String|标签描述| ### OCR结果 OCR功能需额外付费开启,如有需要请联系您的专属商务,未开通状态下此数组返回为空 OCR 数组数据结构 参数名称 | 类型 | 描述 name | String | 图片名称(或图片标识) height | Integer | 图片高度,单位像素 width | Integer | 图片宽度,单位像素 frameSize | Number | 长图、gif图片拆帧后的分帧数,默认为1 taskId | String | 本次请求数据标识,可以根据该标识查询数据最新结果 details | json数组 | OCR详细信息 details 数据结构 参数名称 | 类型 | 描述 content | String | 该图片中所有的文字信息集合 lineContents | json数组 | 行信息 lineContents 数据结构 参数名称 | 类型 | 描述 lineContent | String | 每行的文字信息 polygon | json数组 | 行信息坐标,左上角原点顺时针返回四个点的相对坐标信息 以下为polygon坐标信息返回示意图: polygon坐标信息返回示意图 (https://nos.netease.com/cloud-website-bucket/f3a67a237f57ea56479f4d2bdcca2d7d.png) 以图中两行OCR信息返回为例,每行polygon坐标信息包含4个相对坐标点返回,分别为从左上角原点开始,顺时针依次返回1-4四点的原点坐标,每点坐标从左至右为至图片左上角的x轴和y轴的距离。 ### 人脸检测结果 人脸检测结果需额外付费开启,如有需要请联系您的专属商务,未开通状态下此数组返回为空 face 数组数据结构 参数名称 | 类型 | 描述 name | String | 图片名称(或图片标识) taskId | String | 本次请求数据标识,可以根据该标识查询数据最新结果 details | json数组 | 人脸检测详细信息 details 数据结构 参数名称 | 类型 | 描述 faceNumber | Number | 该图片中包含的人脸个数 faceContents | json数组 | 人脸详细信息 faceContents 数据结构 参数名称 | 类型 | 描述 name | String | 人脸名字,不可识别则为空 gender | String | 人脸性别,值为男(male)、女(female);不可识别则为空 age | Integer | 人脸年龄,值为具体年龄(age);不可识别则为空 type | String | 人脸类型,包含卡通脸(cartoon)、普通(normal) category | String | 人物分类,包含名人(star)、普通(normal) beautyScore | float | 人脸颜值分数,1分制。比如0.87,则代表颜值超过了约87%的人。审美因人而异,结果仅供参考 expression | String | 人脸情绪:neutral(扮酷),happy(微笑),sad(悲伤),surprise(惊讶),fear(害怕),anger(生气),disgust(不喜欢) maskType | String | mask(有遮挡),normal(无遮挡)。判断人脸是否有遮挡,可以用于判断用户是否佩戴口罩墨镜纱巾等综合性遮挡场景 x1 | Number | 人脸位置信息,对应人脸矩形左上角横坐标相对坐标 y1 | Number | 人脸位置信息,对应人脸矩形左上角纵坐标相对坐标 x2 | Number | 人脸位置信息,对应人脸矩形右下角横坐标相对坐标 y2 | Number | 人脸位置信息,对应人脸矩形右下角纵坐标相对坐标 ### 图片质量检测结果 图片质量检测结果需额外付费开启,如有需要请联系您的专属商务,未开通状态下此数组返回为空 quality 数组数据结构 参数名称 | 类型 | 描述 name | String | 图片名称(或图片标识) taskId | String | 本次请求数据标识,可以根据该标识查询数据最新结果 details | json数组 | 质量检测详细信息 details数组结构 参数名称 | 类型 | 描述 MetaInfo | json数组 | 图片基本信息 aestheticsRate | Float | 美观度分数,0-1,分数越高美观度越高,建议0.5分以上可认为美观度较好,0.3分以下可认为美观度较差,具体视业务场景而定 sharpnessRate | Float | 清晰度分数,0-1,分数越高清晰度越高,建议0.5分以上可认为清晰度较好,0.3分以下可认为清晰度较差,具体视业务场景而定 BoarderInfo | json数组 | 图片边框信息 backgroundInfo | json数组 | 图片背景信息 MetaInfo数组结构 参数名称 | 类型 | 描述 byteSize | Long | 图片大小,单位byte format | String | 图片格式 height | Integer | 图片高度,单位像素 width | Integer | 图片宽度,单位像素 BoarderInfo数组结构 参数名称 | 类型 | 描述 hit | Boolean | 图片是否包含边框(任一边包含边框均视为包含)ture:包含边框;false:不包含边框 top | Boolean | 图片顶部是否包含边框,ture:包含边框;false:不包含边框 right | Boolean | 图片右侧是否包含边框,ture:包含边框;false:不包含边框 bottom | Boolean | 图片底部是否包含边框,ture:包含边框;false:不包含边框 left | Boolean | 图片左侧是否包含边框,ture:包含边框;false:不包含边框 backgroundInfo数组结构 参数名称 | 类型 | 描述 pureBackground | Boolean | 纯色背景检测,ture:背景纯色;false:背景复杂 ### logo检测结果 logo检测支持对图片中包含的通识logo进行识别,检测结果返回需额外付费开启,如有需要请联系您的专属商务,未开通状态下此数组返回为空 logo数组数据结构 参数名称 | 类型 | 描述 name | String | 图片名称(或图片标识) taskId | String | 本次请求数据标识,可以根据该标识查询数据最新结果 details | json数组 | logo检测详细信息 details数组结构 参数名称 | 类型 | 描述 logoName | String | logo名字,不可识别则为空 x1 | Number | logo位置信息,对应logo矩形左上角横坐标相对坐标 y1 | Number | logo位置信息,对应logo矩形左上角纵坐标相对坐标 x2 | Number | logo位置信息,对应logo矩形右下角横坐标相对坐标 y2 | Number | logo位置信息,对应logo矩形右下角纵坐标相对坐标 ### 场景检测结果 场景检测支持对图片中场景进行识别,检测结果返回需额外付费开启,如有需要请联系您的专属商务,未开通状态下此数组返回为空 scene数组数据结构 参数名称 | 类型 | 描述 name | String | 图片名称(或图片标识) taskId | String | 本次请求数据标识,可以根据该标识查询数据最新结果 details | json数组 | 场景检测详细信息 details数组结构 参数名称 | 类型 | 描述 sceneName | String | 场景名字,不可识别则为空.目前识别场景包含游戏画面(game)、卡通动漫(cartoon)、海滩湖泊(sea)、泳池(pool)、健身场所(gym)、绘画作品(painting) rate | Number | 置信度分数,0-1之间取值,1为置信度最高,0为置信度最低。 ### 响应示例 输出结果: 注:分类信息,100:色情,110:性感低俗,200:广告,210:二维码,300:暴恐,400:违禁,500:涉政 异步检测机审结果 Code (json): { "code":200, "msg":"ok", "result":[ { "face":{ "name":"test", "details":[ ], "taskId":"ef7d0a358c8f40859feaef94ac5f403f" }, "antispam":{ "censorType":0, "name":"test", "action":0, "resultType":1, "taskId":"ef7d0a358c8f40859feaef94ac5f403f", "status":0, "frameSize":1, "labels":[ { "subLabels":[ ], "level":0, "rate":0.992339, "label":500 }, { "subLabels":[ ], "level":0, "rate":1, "label":300 }, { "subLabels":[ ], "level":0, "rate":0.99995315, "label":100 }, { "subLabels":[ ], "level":0, "rate":1, "label":400 }, { "subLabels":[ ], "level":0, "rate":0.9999373, "label":110 }, { "subLabels":[ ], "level":0, "rate":0.95000094, "label":800 }, { "subLabels":[ ], "level":0, "rate":0.9960562, "label":200 }, { "subLabels":[ ], "level":0, "rate":1, "label":210 }, { "subLabels":[ ], "level":0, "rate":1, "label":900 } ] }, "userRisk":{ "name":"test", "taskId":"ef7d0a358c8f40859feaef94ac5f403f" }, "logo":{ "name":"test", "details":[ ], "taskId":"ef7d0a358c8f40859feaef94ac5f403f" }, "ocr":{ "name":"test", "width":565, "frameSize":1, "details":[ ], "taskId":"ef7d0a358c8f40859feaef94ac5f403f", "height":464 }, "quality":{ "name":"test", "details":[ { "sharpnessRate":0.6398, "metaInfo":{ "byteSize":776131, "width":565, "format":"png", "height":464 }, "aestheticsRate":0.4093, "boarderInfo":{ "hit":false, "top":false, "left":false, "bottom":false, "right":false }, "backgroundInfo":{ "pureBackground":false } } ], "taskId":"ef7d0a358c8f40859feaef94ac5f403f" }, "scene":{ "name":"test", "details":[ ], "taskId":"ef7d0a358c8f40859feaef94ac5f403f" } } ] } 人审结果 Code: { "code":200, "msg":"ok", "result":[ { "antispam":{ "name":"test", "taskId":"ef7d0a358c8f40859feaef94ac5f403f", "action":2, "censorTime":1629439129895, "censorSource":1, "censorRound":1, "resultType":2, "labels":[ { "label":800, "level":2, "rate":1 }, { "label":500, "level":0, "rate":1 }, { "label":300, "level":0, "rate":1 }, { "label":100, "level":0, "rate":1 }, { "label":400, "level":0, "rate":1 }, { "label":110, "level":0, "rate":1 }, { "label":200, "level":0, "rate":1 }, { "label":210, "level":0, "rate":1 }, { "label":900, "level":0, "rate":1 } ], "censorLabels":[ ] } } ] } ## 图片回调方式获取 回调方式以数据为维度,由客户设置回调地址;当机器检测结果发生变化,或者人工进行审核后,会触发主动回调,调用客户提供的回调接口返回审核结果。 ### 回调接入说明 接入回调方式很简单,只需要在调用在线检测接口请求参数中指定了回调通知参数callbackUrl(即一个http(s)协议接口的URL)。主动推送接口需要支持http协议,支持POST方法,传输数据编码采用utf-8。 业务类型 | 回调参数名称 | 类型 | 最大长度 | 描述 图片 | callbackUrl | String | 256 | 图片在线检测参数中添加callbackUrl字段 ### 回调状态 您服务端接收到我们回调的结果后,返回的HTTP状态码为200时,表示推送成功,其他的HTTP状态码均视为您接收失败,我们将每隔10分钟推送一次,如果一直失败,持续一天后不再推送;我们主动推送数据接口超时时间设置为2s,为了保证顺利接收数据,客户需保证接收接口性能稳定并且保证幂等性。 ### 请求公共参数 参数名称 | 类型 | 是否必传 | 描述 secretId | String | Y | 产品秘钥 id ,由易盾反垃圾云服务分配,产品标识 businessId | String | Y | 业务id ,由易盾反垃圾云服务分配,业务标识 signature | String | Y | 请求签名,用来验证此次请求的合法性,具体算法见 接口鉴权 (#_9) callbackData | String | Y | 主动推送推送数据,格式为json字符串 secretId,businessId,signature参数用来给数据接收接口做签名鉴权用 ### 接口鉴权 回调结果可以通过业务开通时易盾分配的密钥信息字段进行接口鉴权,鉴权粒度是否要精确到业务级别,用户可以根据需要自行决定 Code (java): /** * 通过HttpServletRequest做签名验证 * * @param request * @return */ public static boolean verifySignature(HttpServletRequest request) { String secretId = request.getParameter("secretId"); String businessId = request.getParameter("businessId"); String signature = request.getParameter("signature"); if (StringUtils.isEmpty(secretId) || StringUtils.isEmpty(signature)) { // 签名参数为空,直接返回失败 return false; } Map params = Maps.newHashMap(); for (String paramName : request.getParameterMap().keySet()) { if (!"signature".equals(paramName)) { params.put(paramName, request.getParameter(paramName)); } } // SECRETKEY:产品私有密钥 SECRETID:产品密钥ID BUSINESSID:业务ID,开通服务时,易盾会提供相关密钥信息 String serverSignature = getSignature(SECRETKEY, params); return signature.equals(serverSignature) && SECRETID.equals(secretId) && BUSINESSID.equals(businessId); } Code (java): /** * 生成签名信息 * @param secretKey 产品私钥 * @param params 接口请求参数名和参数值map,不包括signature参数名 * @return * @throws UnsupportedEncodingException */ public static String genSignature(String secretKey, Map params) throws UnsupportedEncodingException { // 1. 参数名按照ASCII码表升序排序 String[] keys = params.keySet().toArray(new String[0]); Arrays.sort(keys); // 2. 按照排序拼接参数名与参数值 StringBuffer paramBuffer = new StringBuffer(); for (String key : keys) { paramBuffer.append(key).append(params.get(key) == null ? "" : params.get(key)); } // 3. 将secretKey拼接到最后 paramBuffer.append(secretKey); // 4. MD5是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32个十六进制字符。 return DigestUtils.md5Hex(paramBuffer.toString().getBytes("UTF-8")); } ### 图片回调数据结构 callbackData为Json字符串,数据结构如下: 异步检测机审结果 Code: { "antispam":{ "taskId":"d8609b31e0794fccbb58616f98d1d0d1", "status":0, "action":0, "censorType":0, "name":"test", "labels":[ { "label":500, "level":0, "rate":0.9696668, "subLabels":[ ] }, { "label":300, "level":0, "rate":1, "subLabels":[ ] }, { "label":100, "level":0, "rate":0.99995315, "subLabels":[ ] }, { "label":400, "level":0, "rate":1, "subLabels":[ ] }, { "label":110, "level":0, "rate":0.9999373, "subLabels":[ ] }, { "label":800, "level":0, "rate":0.99939084, "subLabels":[ ] }, { "label":200, "level":0, "rate":0.9960562, "subLabels":[ ] }, { "label":210, "level":0, "rate":1, "subLabels":[ ] }, { "label":900, "level":0, "rate":1, "subLabels":[ ] } ], "resultType":1 }, "ocr":{ "taskId":"d8609b31e0794fccbb58616f98d1d0d1", "name":"test", "height":464, "width":565, "details":[ ] }, "face":{ "taskId":"d8609b31e0794fccbb58616f98d1d0d1", "name":"test", "details":[ ] }, "quality":{ "taskId":"d8609b31e0794fccbb58616f98d1d0d1", "name":"test", "details":[ { "aestheticsRate":0.4093, "sharpnessRate":0.6398, "metaInfo":{ "byteSize":776131, "height":464, "width":565, "format":"png" }, "boarderInfo":{ "hit":false, "top":false, "right":false, "bottom":false, "left":false }, "backgroundInfo":{ "pureBackground":false } } ] }, "logo":{ "taskId":"d8609b31e0794fccbb58616f98d1d0d1", "name":"test", "details":[ ] }, "scene":{ "taskId":"d8609b31e0794fccbb58616f98d1d0d1", "name":"test", "details":[ ] }, "userRisk":{ "taskId":"d8609b31e0794fccbb58616f98d1d0d1", "name":"test" } } 人审结果 Code (json): { "antispam":{ "name":"test", "taskId":"35fcb52938694674900b832d064b4a70", "action":0, "censorTime":1619577951222, "censorSource":0, "censorRound":1, "resultType":2, "labels":[ { "label":500, "level":0, "rate":1 }, { "label":300, "level":0, "rate":1 }, { "label":100, "level":0, "rate":1 }, { "label":400, "level":0, "rate":1 }, { "label":110, "level":0, "rate":1 }, { "label":800, "level":0, "rate":1 }, { "label":200, "level":0, "rate":1 }, { "label":210, "level":0, "rate":1 }, { "label":900, "level":0, "rate":1 } ], "censorLabels":[ ] } }