内容审核实践 | 即时通讯 IM 场景 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
如果想在 V2EX 获得更好的推广效果,欢迎了解 PRO 会员机制:
pro/about
CloudStorage

内容审核实践 | 即时通讯 IM 场景

  •  
  •   CloudStorage 2021 年 9 月 27 日 1670 次点击
    这是一个创建于 1671 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一、概述

    一些用户使用即时通信 IM 产品开发实现自己的聊天业务,但对于聊天之间的消息无法很好的去管控内容是否违规。

    基于数据万象 CI,对象存储 COS 推出的内容审核功能,可以帮助用户实现 IM 消息的审核服务,在发送出来的消息是违规内容时,不允许发送(先审后发)。

    整体流程可看下图:

    内容审核的处理主要在步骤 6 、7 、8 。

    步骤 6:发送审核请求对消息内容进行审核。 步骤 7:返回处理结果。 步骤 8:根据结果判断是否发送消息或是否撤回、删除消息。

    实际聊天效果如下图:

    二、准备工作

    (一)即时通信 IM 简单 DEMO

    [ Demo 入门] 一分钟跑通 Demo: https://cloud.tencent.com/document/product/269/36838 IM SDK 地址: https://cloud.tencent.com/document/product/269/36887

    按照文档说明登陆、 获取 SDKAppID 及密钥信息、 创建应用、 下载 DEMO 源码、 配置密钥、 编译运行(部分平台需要)

    本文例子使用 Web&H5,修改 GenerateTestUserSig.js 文件配置密钥后,无需编译,可直接访问 dist/index.html, 如: http://127.0.0.1/timSdkH5Demo/dist/index.html 替换服务器地址后可以直接访问,timSdkH5Demo 为代码目录,可按需修改。 访问后显示如下页面,可下拉选择用户登陆,两个用户登陆不同账号即可实现聊天功能。

    (二) IM 配置项

    登录 即时通信 IM 控制台回调配置
    回调 URL 配置 >> 编辑:填写回调 URL 后确认保存。具体回调参数及说明可访问 第三方回调简介 。

    事件回调配置 >> 编辑:选择需要的回调事件,以“单聊消息”为例,选中 “发单聊消息之前回调”,会在发送消息前请求回调 URL,一系列判断后返回回调结果。

    注意:回调 URL 需公网可见。

    这一步需要保证的就是,即时通信 IM 可实现消息发送、即时通信 IM 控制台回调配置完成,且在发送消息时触发回调 URL 的请求,回调接口能够接收到请求数据。强调:回调 URL 接口需公网可见。

    三、文字消息审核具体配置

    目前准备工作已经做好了,接下来需要考虑的有以下几点:

    消息发送时回调接口接收请求参数,确认参数的准确性。

    根据不同参数获取到不同消息内容,如:聊天文本、图片地址等。

    对消息内容进行审核,不同的消息类型会调用不同的审核接口,接下来的内容会对不同的消息类型(文本和图片)进行举例说明。

    根据审核结果给出不同的返回结果,达到消息是否允许发送的效果。

    Ps: 下面举例说明部分会以 Step n 来对应上面各点。

    以下举例说明都是以审核 IM 消息内容为前提,如需审核其他内容,可见各审核文档的详细介绍。

    举例说明:

    开发工具:SCF 云函数 https://console.cloud.tencent.com/scf (不一定非要云函数,服务公网可见即可,否则回调请求失败) 语言:PHP/7.2.2 通信 IM SDK 以及 Demo 源码: 地址: https://cloud.tencent.com/document/product/269/36887 本文档例子使用 Web&H5: https://github.com/tencentyun/TIMSDK/tree/master/H5 对象存储 SDK 文档: PHP SDK 地址: https://cloud.tencent.com/document/product/436/12266 (其他语言可见页面左侧栏对应标签) IM 配置项: 单聊消息 >> 发单聊消息之前回调 举例消息类型: 文本、图片 

    Step 1 回调请求参数

    第三方回调简介: https://cloud.tencent.com/document/product/269/1522

    回调参数列表: https://cloud.tencent.com/document/product/269/1523

    消息格式描述: https://cloud.tencent.com/document/product/269/2720

    IM 发送消息后会请求回调 URL,本例中对 SdkAppid 参数做了简单身份验证,如需要其他复杂验证可自行判断。

    <?php include_once 'commonFunc.php'; // 自定义公用函数,如发送 POST 、GET 请求或做出 Response 响应等函数的封装 include_once 'imMsg.php'; // 自定义消息审核类,对文本和图片做出审核请求并对审核结果做出是否违规判断 include_once 'cos-php-sdk-v5-master/vendor/autoload.php'; // COS 内容审核 SDK 引入,本例使用 PHP 的 SDK $cOntent= file_get_contents('php://input'); // 获取 POST JSON 数据 字符串 $post = json_decode($content, true); // POST JSON 数据 数组 // 对 SdkAppid 做出简单身份验证 if(!isset($_GET['SdkAppid']) || $_GET['SdkAppid'] != ImMsg::SDK_APPID) { imcallback_return(false); // 接口返回结果数据 } ** * 函数内列出两种回调结果 * $send true 允许消息发送; false 禁止消息发送 */ function imcallback_return($send = true) { $retSuccess = array( 'ErrorCode' => 0, // 0 为允许发言 'ErrorInfo' => '', 'ActionStatus' => 'OK' );; $retErr = array( 'ErrorCode' => 1, // 1 为拒绝发言 'ErrorInfo' => 'err', 'ActionStatus' => 'FAIL' ); $ret = $send === true ? $retSuccess : $retErr; ob_clean(); echo json_encode($ret); } 

    回调请求示例:

    POST /?SdkAppid=123456&CallbackCommand=C2C.CallbackBeforeSendMsg&cOntenttype=json&ClientIP&OptPlatform HTTP/1.1 Host: www.example.com 文本类型: { "MsgBody": [ { "MsgType": "TIMTextElem", // TIMTextElem 表示消息类型为文本 "MsgContent": { "Text": "asdad" // 文本内容 } } ], "CallbackCommand": "C2C.CallbackBeforeSendMsg", // C2C.CallbackBeforeSendMsg 发单聊消息之前回调 "From_Account": "user1", "To_Account": "user0", "MsgRandom": 123, "MsgSeq": 1234567, "MsgTime": 1629439393, "MsgKey": "1234567_123456_123456789", "OnlineOnlyFlag": 0 } 图片类型: { "MsgBody": [ { "MsgType": "TIMImageElem", // TIMImageElem 表示消息类型为图片 "MsgContent": { "UUID": "123456-user1-abcdefghd", "ImageFormat": 3, "ImageInfoArray": [ { "Type": 1, //原图 "Size": 43599, "Width": 1156, "Height": 582, "URL": "https://cos.ap-shanghai.myqcloud.com/6244-shanghai-007-shared-01-1256635546/2690-1400560394/e078-user1/582eef3bb1e6439cd842ae0bd6a16cae-101935?imageMogr2/" }, { "Type": 2, //大图 "Size": 0, "Width": 0, "Height": 0, "URL": "https://cos.ap-shanghai.myqcloud.com/6244-shanghai-007-shared-01-1256635546/2690-1400560394/e078-user1/582eef3bb1e6439cd842ae0bd6a16cae-101935?imageMogr2/" }, { "Type": 3, //缩量图 "Size": 0, "Width": 394, "Height": 198, "URL": "https://cos.ap-shanghai.myqcloud.com/6244-shanghai-007-shared-01-1256635546/2690-1400560394/e078-user1/582eef3bb1e6439cd842ae0bd6a16cae-101935?imageMogr2/&imageView2/3/w/198/h/198" } ] } } ], "CallbackCommand": "C2C.CallbackBeforeSendMsg", "From_Account": "user1", "To_Account": "user0", "MsgRandom": 123, "MsgSeq": 1234567, "MsgTime": 1629357746, "MsgKey": "1234567_123456_123456789", "OnlineOnlyFlag": 0 } 

    回调应答示例:

    HTTP/1.1 200 OK Server: nginx/1.7.10 Date: Fri, 09 Oct 2015 02:59:55 GMT Content-Length: 75 { "ActionStatus": "OK", "ErrorInfo": "", "ErrorCode": 0 // 1 为拒绝发言; 0 为允许发言 } 

    即时通信 IM 回调 App 后台的超时时间为 2 秒,且没有重试。如果回调超时,后续处理逻辑与没有配置回调时相同(例如,假设“发送群消息之前回调”超时,消息会正常下发)。

    为确保回调成功率,第三方 App 应当尽可能加快回调处理速度,例如先发送回调应答,然后再处理具体业务逻辑。

    Step 2 获取消息内容

    回调类型 回调命令字
    发单聊消息之前回调 C2C.CallbackBeforeSendMsg
    发单聊消息之后回调 C2C.CallbackAfterSendMsg

    其他回调命令及相关参数见 回调命令列表。

    MsgType 的值 类型
    TIMTextElem 文本消息
    TIMImageElem 图像消息

    其他消息类别 MsgType 描述及相关参数见 消息格式描述。

    本例中简单获取了文本内容及图片地址 URL 。

    $flag = false; switch($_GET['CallbackCommand']) { case 'C2C.CallbackBeforeSendMsg': { // 对发单聊消息之前回调进行封装 $flag = ImMsg::cmdC2cMsgBefore($post); break; } default: { break; } } imcallback_return($flag); ImMsg::cmdC2cMsgBefore public static function cmdC2cMsgBefore($allData) { $data = $allData['MsgBody']; $flag = true; foreach($data as $msgItem) { if($msgItem['MsgType'] == 'TIMTextElem') { // 文本类型审核 // $msgItem['MsgContent']['Text'] 文本内容 $flag = self::textDetect($msgItem['MsgContent']['Text']); } else if($msgItem['MsgType'] == 'TIMImageElem') { // 图片类型审核 // $msgItem['MsgContent']['ImageInfoArray'][0]['URL'] 图片 URL 地址,原图、大图、缩略图三选一 $flag = self::imgDetect($msgItem['MsgContent']['ImageInfoArray'][0]['URL']); } } return $flag; } 

    走到这一步,已经获取到了消息内容,即: 文本内容:$msgItem['MsgContent']['Text']

    图片地址:$msgItem['MsgContent']['ImageInfoArray'][0]['URL']

    接下来对消息内容发送审核请求并获取审核结果。

    Step 3 对消息内容进行审核,获取审核结果

    文本审核: https://cloud.tencent.com/document/product/460/56285

    图片审核: https://cloud.tencent.com/document/product/460/37318

    其他类型的审核可见页面左侧标签相关文档说明。

    关于审核,为了开发者更方便、更快速地使用数据万象的基础图片处理和媒体处理功能,以及 CDN 的云闪图片分发功能,我们提供了 SDK,开发者可根据具体需求进行选择,详情请参见对应的快速入门文档。对象存储的 SDK 也集成了数据万象的数据处理功能,若您需要使用其他语言的 SDK,例如 C++ 、Javascript 等,请参见 COS SDK 概览。

    图片审核

    关于图片审核的图片限制说明,请参见 规则与限制。

    使用 COS PHP SDK 请求示例 ( sample/getObjectSensitiveContentRecognitin.php ),IM 消息审核使用图片链接审核方式即可。

    <?php require dirname(__FILE__) . '/../vendor/autoload.php'; $secretId = "SECRETID"; //"云 API 密钥 SecretId"; $secretKey = "SECRETKEY"; //"云 API 密钥 SecretKey"; $region = "ap-beijing"; //设置一个默认的存储桶地域 $cosClient = new Qcloud\Cos\Client( array( 'region' => $region, 'schema' => 'https', //协议头部,默认为 http 'credentials' => array( 'secretId' => $secretId, 'secretKey' => $secretKey))); try { //图片链接审核 $imgUrl = 'https://test.jpg'; $result = $cosClient->getObjectSensitiveContentRecognition(array( 'Bucket' => 'examplebucket-125000000', //格式:BucketName-APPID 'Key' => '/', // 链接图片资源路径写 / 即可 'DetectType' => 'porn,ads',//可选四种参数:porn,politics,terrorist,ads,可使用多种规则,注意规则间不要加空格 'DetectUrl' => $imgUrl, // 'Interval' => 5, // 审核 gif 时使用 截帧的间隔 // 'MaxFrames' => 5, // 针对 GIF 动图审核的最大截帧数量,需大于 0 。 // 'BizType' => '', // 审核策略 )); // 请求成功 print_r($result); } catch (\Exception $e) { // 请求失败 echo($e); } 

    响应结果:

    GuzzleHttp\Command\Result Object ( [RequestId] => asdjahsfkjshfkjsdhfkjshfksjhfj= [PornInfo] => Array ( [0] => Array ( [Code] => 0 [Msg] => OK [HitFlag] => 0 [Score] => 0 [Label] => ) ) [AdsInfo] => Array ( [0] => Array ( [Code] => 0 [Msg] => OK [HitFlag] => 0 [Score] => 0 [Label] => ) ) [Key] => / [Bucket] => examplebucket-125000000 [Location] => examplebucket-125000000.cos.ap-guangzhou.myqcloud.com// ) 

    文本审核

    使用 COS PHP SDK 请求示例 ( sample/detectText.php ),IM 消息审核使用文本内容审核方式即可。

    <?php require dirname(__FILE__) . '/../vendor/autoload.php'; $secretId = "SECRETID"; //"云 API 密钥 SecretId"; $secretKey = "SECRETKEY"; //"云 API 密钥 SecretKey"; $region = "ap-beijing"; //设置一个默认的存储桶地域 $cosClient = new Qcloud\Cos\Client( array( 'region' => $region, 'schema' => 'https', //协议头部,默认为 http 'credentials'=> array( 'secretId' => $secretId , 'secretKey' => $secretKey))); try { // start --------------- 文本内容审核 ----------------- // $cOntent= '敏感信息'; $result = $cosClient->detectText(array( 'Bucket' => 'examplebucket-125000000', //格式:BucketName-APPID 'Input' => array( 'Content' => base64_encode($content) // 文本需 base64_encode ), 'Conf' => array( 'DetectType' => 'Porn,Terrorism,Politics,Ads', //Porn,Terrorism,Politics,Ads,Illegal,Abuse 类型 'BizType' => '', ), )); // 请求成功 print_r($result); // end --------------- 文本内容审核 ----------------- // } catch (\Exception $e) { // 请求失败 echo($e); } 

    响应结果:

    GuzzleHttp\Command\Result Object ( [RequestId] => asdjsajfaslofjsdofjsoifjsf= [ContentType] => application/xml [ContentLength] => 1237 [JobsDetail] => Array ( [Code] => Success [Message] => Array ( ) [JobId] => asjhdkjahfkjashfkjsdfhkjs [State] => Success [CreationTime] => 2021-09-09T20:04:05+08:00 [Content] => 57qm54Ku [Result] => 1 [SectionCount] => 1 [PornInfo] => Array ( [HitFlag] => 1 [Count] => 1 ) [TerrorismInfo] => Array ( [HitFlag] => 0 [Count] => 0 ) [PoliticsInfo] => Array ( [HitFlag] => 0 [Count] => 0 ) [AdsInfo] => Array ( [HitFlag] => 0 [Count] => 0 ) [Section] => Array ( [0] => Array ( [StartByte] => 0 [PornInfo] => Array ( [Code] => 0 [HitFlag] => 1 [Score] => 97 [Keywords] => 敏感词 ) [TerrorismInfo] => Array ( [Code] => 0 [HitFlag] => 0 [Score] => 0 [Keywords] => ) [PoliticsInfo] => Array ( [Code] => 0 [HitFlag] => 0 [Score] => 0 [Keywords] => ) [AdsInfo] => Array ( [Code] => 0 [HitFlag] => 0 [Score] => 0 [Keywords] => ) ) ) ) [Bucket] => examplebucket-125000000 [Location] => examplebucket-125000000.ci.ap-guangzhou.myqcloud.com/text/auditing ) 

    Step 4 回调请求返回结果

    走到这一步,说明已经对消息内容进行了审核并作出了是否违规的判断,接下来就是返回是否违规的结果即可。

    在 Step 1 回调应答示例中也提到了,ErrorCode=1 拒绝发言,ErrorCode=0 允许发言。

    HTTP/1.1 200 OK Server: nginx/1.7.10 Date: Fri, 09 Oct 2015 02:59:55 GMT Content-Length: 75 { "ActionStatus": "", "ErrorInfo": "", "ErrorCode": 0 // 1 为拒绝发言; 0 为允许发言 } 

    在用户侧效果为:

    具体参数及含义或其他应答方式可见 第三方回调简介 或同页面左侧其他文档页。

    至此,IM 发送消息、IM 请求回调、消息内容审核、回调应答、消息发送结果,所有步骤均已完成。

    四、写在最后

    随着各种网络安全法律法规和战略规划相继出台,监管部门对网络内容安全监管将日趋严格,对消息监管也日趋严格。对于聊天之间的消息如何把控也成为了重要的问题?对象存储本次推出的内容审核功能,可以帮助用户实现 IM 消息的审核服务,对于违规内容进行审核把控,为您的网络安全保驾护航。

    jerryjhou
        1
    jerryjhou  
       2021 年 10 月 3 日 via Android
    人类迷惑行为之...
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2694 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 46ms UTC 12:46 PVG 20:46 LAX 05:46 JFK 08:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86