module CensorBear class Result attr_accessor :is_mod, :mod_words, :content def initialize(content, is_mod = false, mod_words = []) @is_mod = is_mod @mod_words = mod_words @content = content || '' end end class Censor QQ_REG = /(?:[加茄qQ企鹅号码\s]{1,}|[群号]{1,}|[叩叩]{1,}|[抠抠]{1,}|[扣扣]{1,})(?:[\u4e00-\u9eff]*)(?:[:,:]?)([\d\s]{6,})/ WX_REG = /(?:[加+微++➕薇?vV威卫星♥❤姓xX信]{2,}|weixin|weix)(?:[,❤️.\s]?)(?:[\u4e00-\u9eff]?)(?:[:,:]?)([\w\s]{6,})/ def initialize(content, type = 'ugc') @is_mod = false @mod_words = [] @content = content @type = type.to_s end def check_text return Result.new(@content) if @content.blank? return Result.new(@content) unless CensorBear::StopWord::FIELDS.include?(@type) if @content.match(QQ_REG) CensorBear.info(@content, @type, 'BANNED', 'qq_regex') raise NotPassedException end if @content.match(WX_REG) CensorBear.info(@content, @type, 'BANNED', 'wx_regex') raise NotPassedException end local_check # 用户相关类型直接禁止创建 raise NotPassedException if @is_mod && %w[username signature dialog nickname].include?(@type) Result.new(@content, @is_mod, @mod_words.uniq) end def local_check original_content = @content.dup stop_words = CensorBear::StopWord.where("#{@type} != 'IGNORE'") stop_words.each do |word| finder = Regexp.new(Regexp.escape(word.key)) action = word.send(@type.to_sym).upcase next unless finder.match(@content) @mod_words.push(word.key) case action when 'REPLACE' @content = @content.gsub(finder, word.replacement) CensorBear.info( original_content, @type, action, 'local_check', filtered_content: @content, mod_words: [word.key] ) when 'MOD' @is_mod = true CensorBear.info( original_content, @type, action, 'local_check', filtered_content: nil, mod_words: [word.key] ) when 'BANNED' @is_mod = true # 禁止的直接抛出异常 CensorBear.info( original_content, @type, action, 'local_check', filtered_content: nil, mod_words: [word.key] ) raise NotPassedException end end end def cloud_check() end private def tencent_check() end def aliyun_check() end end end