IM安全通(内容审核)

更新时间: 2023/06/29 09:02:38

网易云信 IM 安全通(内容安全审核)服务,融合了网易易盾的内容审核能力,支持对文本消息、图片消息、自定义消息、用户头像和用户资料等类型的内容安全检测,实现全流程的审-查-禁功能,降低人力投入。

功能介绍

开通安全通功能并配置安全通检测规则后,指定类型的消息经过相关的接口调用和配置后,都会先经由安全通进行内容安全检测,之后才会转发给接收端的用户。安全通支持如下几种消息类型的内容审核。

API 关键字 说明
text 文本消息
image 图片消息
audio 音频消息
video 视频消息
avchat 音视频通话事件消息
notification 通知消息
tip 提醒消息
custom 自定义消息

技术原理

针对不同的内容类型,安全通提供两套内容审核方案:

审核方案
说明
实时(同步)内容审核 主要针对文本内容。由云信服务端进行内容提交、过滤和投递,客户端会收到内容审核结果,且云信服务器会同时抄送审核结果给应用服务器。客户端上需根据内容审核结果自行实现相关业务处理。
异步内容审核 主要针对音频、视频。由云信服务端先行投递消息,违规内容由云信服务端删除。内容审核结果抄送至应用服务器,后者根据审核结果对消息进行处理(如撤回)。客户端不会收到内容审核结果

若您需要云信服务器将审核结果抄送到您的应用服务器,即上图中的流程 6,请先开通易盾异步反垃圾抄送

实现流程

graph LR
    %% 定义样式类
    classDef default fill:#337EFF,stroke:#337EFF,stroke-width:1px,color:#FFFFFF;

    开通安全通 --> 配置安全通检测规则 --> 实现安全通审核 --> 获取审核结果 --> 处理安全审核结果

步骤1:开通安全通并配置安全通检测规则

  1. 开通安全通,具体步骤请参见开通能力
  2. 在控制台首页选择对应的应用,在左侧导航栏选择 产品功能 > IM 即时通讯,顶部选择安全通页签,单击子功能配置

IM安全通.png

  1. 配置内容安全抄送地址。

    接收 IM 内容审核结果的抄送地址与 IM、音视频通话 2.0 的消息抄送地址相同,若您此前从未开通抄送功能、未配置抄送地址,请单击前往配置,配置抄送地址。

    如果您已经开通了抄送功能,此处默认使用同一个抄送地址。

    内容安全抄送地址.png

  2. 配置内容安全范围。

    单击具体审核类型的配置选择需要的模块。

    IM内容安全配置.png

    配置内容审核模块.png

  3. 配置内容安全疑似处理规则。

    单击具体业务的配置进行过审内容和疑似处理配置。

    疑似处理配置.png

步骤2:配置关键词名单

您可以配置关键词名单,对文本消息中的敏感词进行检测。

  1. 在网易云信控制台的IM 安全通配置 页面底部,单击更多安全配置

    IM安全通更多安全配置.png

  2. 在易盾智能审核平台左侧导航栏选择策略配置 > 关键词名单,将需要检测的敏感词添加到关键词清单中。

    易盾控制台.png

步骤3:实现安全通审核

开通安全通服务后,调用发送消息方法时传入相关参数(NIMAntiSpamOption)可实现消息内容过安全通审核。消息会根据检测规则进行内容安全检测。

通过 1 对 1 UIKit 实现安全通审核的示例代码如下:

  override public func willSend(_ message: NIMMessage) {
    super.willSend(message)
    // 构造反垃圾对象
    let antiSpamOption = NIMAntiSpamOption()
    antiSpamOption.yidunEnabled = true
    message.antiSpamOption = antiSpamOption
  }

步骤4:获取审核结果

匹配消息体命中敏感词后,可通过 IMMessage#getYidunAntiSpamRes 字段通知客户端结果,该字段需要通过 observeMsgStatus 回调获取。

只有被安全通拦截的消息才会有yidunAntiSpamRes返回。对于疑似消息根据云信控制台设置的策略来判断,如果疑似消息被拦截会有yidunAntiSpamRes返回,如果疑似消息放行则没有yidunAntiSpamRes返回。

返回的审核结果 yidunAntiSpamRes 为 JSON 字符串格式,请自行解析或者反转成 JSON 对象使用。yidunAntiSpamRes 字段定义如下:

名称类型说明
code Integer状态码:
  • 200:易盾内容审核结果返回正常
  • 404:易盾反回的内容审核结果为空,该情况下 yidunAntiSpamRes 中无 code 以外的字段
  • 414:易盾返回的内容审核结果过长,该情况下 yidunAntiSpamRes 中无 ext 字段
type String内容审核类型
  • text:文本
  • image:图片
version String易盾内容审核的接口版本
taskId String审核任务的 ID
suggestion Integer 建议处理方式
  • 0:通过
  • 1:嫌疑,建议人工复审
  • 2:不通过
status Integer内容审核请求结果
  • 0:成功
  • 1:失败
ext String内容审核结果,对应易盾的 result 字段,result 字段详情参见易盾文档(注:本链接仅以“单次同步文本检测的 result 字段说明”为例)
语音、视频消息进行安全通反垃圾时,是异步检测的,并且检测结果是通过 IM 抄送通知开发者服务器。虽然命中后云信会自动删除服务器上的文件,但是在检测结果出来之前,消息可能已经被投递到接收方。因此如果开发者收到命中抄送后,请通过 IM 服务端接口进行消息撤回

安全通重要参数

参数 类型 说明
yidunAntiSpamExt 易盾反垃圾扩展字段 透传给易盾的反垃圾增强版的检测参数,具体请参见易盾的反垃圾增强版用户可扩展参数,格式为json,长度限制1024 反作弊相关的email、phone、token、extension,抄送到yidunAntiCheating。其他用户增值信息,抄送到yidunAntiSpamExt。
yidunAntiSpamRes 易盾反垃圾结果 易盾反垃圾触发时返回的结果字段,格式为json
yidunAntiCheating 易盾反作弊字段 透传给易盾的反作弊检测参数,格式为json,长度限制1024 ,具体请参见文本防刷版开发文档反作弊相关的email、phone、token、extension,抄送到yidunAntiCheating。其他用户增值信息,抄送到yidunAntiSpamExt。

示例代码

重写发送完成方法

override public func send(_ message: NIMMessage, didCompleteWithError error: Error?) {
    super.send(message, didCompleteWithError: error)
    if let yidunAntiSpamExt = message.yidunAntiSpamRes {
      // 易盾审核
      let jsonData = yidunAntiSpamExt.data(using: .utf8)!
      do {
        if let dictionary = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
          if dictionary.keys.contains("suggestion"), let suggestion = dictionary["suggestion"] as? Int {
            if suggestion != 0 {
              // 不通过
              if let extString = dictionary["ext"] as? String,
                 let extObjectData = extString.data(using: .utf8),
                 let extObject = try? JSONSerialization.jsonObject(with: extObjectData, options: []) as? [String: Any],
                 let antispam = extObject["antispam"] as? [String: Any],
                 let labels = antispam["labels"] as? [[String: Any]],
                 let subLabels = labels.first?["subLabels"] as? [[String: Any]],
                 let details = subLabels.first?["details"] as? [String: Any],
                 let keywords = details["keywords"] as? [[String: Any]],
                 let keyword = keywords.first?["word"] as? String {
                if keyword.count > 0 {
                  sendSalutionMsg(type: 3, antiSpamMessage: message)
                  return
                }
              }

              sendSalutionMsg(type: 4, antiSpamMessage: message)

            } else {}
          }
        }
      } catch {
        print(error.localizedDescription)
      }
    }
  }

步骤5:处理安全审核结果

当消息体命中敏感词后,在客户端页面展示类似下图的消息通知。

消息系统2.png

您可以通过 IM 自定义消息 实现该功能,实现方法如下:

  // 发送打招呼消息:本地消息
  func sendSalutionMsg(type: Int, antiSpamMessage: NIMMessage?) {
    let message = NIMMessage()
    if let antiSpamMessage = antiSpamMessage {
      message.timestamp = antiSpamMessage.timestamp + 1
    }
    let object = NIMCustomObject()
    let attachment = CustomAttachment()
    // 本地消息不回走到 CustomAttachment的解析,所以需要手动 cellHeight 以及 customType ,否则不会刷新。发送消息不需要
    attachment.cellHeight = 50 + 20
    switch type {
    case 1:
      // audio
      attachment.type = OneOnOneChatCustomMessageType.TRY_AUDIO_CALL_MESSAGE_TYPE
      attachment.customType = OneOnOneChatCustomMessageType.TRY_AUDIO_CALL_MESSAGE_TYPE
    case 2:
      // video
      attachment.type = OneOnOneChatCustomMessageType.TRY_VIDEO_CALL_MESSAGE_TYPE
      attachment.customType = OneOnOneChatCustomMessageType.TRY_VIDEO_CALL_MESSAGE_TYPE
    case 3:
      // 三方消息违规
      attachment.type = OneOnOneChatCustomMessageType.PRIVACY_RISK_MESSAGE_TYPE
      attachment.customType = OneOnOneChatCustomMessageType.PRIVACY_RISK_MESSAGE_TYPE
    case 4:
      // 通用违规消息
      attachment.type = OneOnOneChatCustomMessageType.COMMON_RISK_MESSAGE_TYPE
      attachment.customType = OneOnOneChatCustomMessageType.COMMON_RISK_MESSAGE_TYPE
    default:
      attachment.type = OneOnOneChatCustomMessageType.ACCOST_MESSAGE_TIPS_TYPE
      attachment.customType = OneOnOneChatCustomMessageType.ACCOST_MESSAGE_TIPS_TYPE
      attachment.cellHeight = 30 + 20
    }
    object.attachment = attachment
    message.messageObject = object
    let setting = NIMMessageSetting()
    setting.shouldBeCounted = false
    message.setting = setting
    viewmodel.repo.saveMessageToDB(message, viewmodel.session) { error in
      print("send custom message error : ", error?.localizedDescription as Any)
    }
  }
  //注:customType 需要有对应的注册:如下所示

  registerCellDic[String(OneOnOneChatCustomMessageType.ACCOST_MESSAGE_TIPS_TYPE)] = NEOneOnOneTextSalutuionCell.self
    registerCellDic[String(OneOnOneChatCustomMessageType.PRIVACY_RISK_MESSAGE_TYPE)] = NEOneOnOneTextThirdPrivacyCell.self
    registerCellDic[String(OneOnOneChatCustomMessageType.TRY_AUDIO_CALL_MESSAGE_TYPE)] = NEOneOnOneAudioSalutuionCell.self
    registerCellDic[String(OneOnOneChatCustomMessageType.TRY_VIDEO_CALL_MESSAGE_TYPE)] = NEOneOnOneVideoSalutuionCell.self
    registerCellDic[String(OneOnOneChatCustomMessageType.COMMON_RISK_MESSAGE_TYPE)] = NEOneOnOneTextNonComplianceCell.self
    registerCellDic[String(SEND_GIFT_TYPE_SEND)] = NEOneOnOneRewardRightCell.self
    registerCellDic[String(SEND_GIFT_TYPE_RECV)] = NEOneOnOneRewardLeftCell.self
    registerCellDic[String(OneOnOneChatCustomMessageType.OFFICIAL_GIFT_TYPE)] = NEOneOnOneOfficialCell.self

注:上述的cell 都是基于NEChatBaseCell 的自定义UI

此文档是否对你有帮助?
有帮助
去反馈
  • 功能介绍
  • 技术原理
  • 实现流程
  • 步骤1:开通安全通并配置安全通检测规则
  • 步骤2:配置关键词名单
  • 步骤3:实现安全通审核
  • 步骤4:获取审核结果
  • 步骤5:处理安全审核结果