基于 Gloria 实现多说垃圾评论主动式过滤

更新: 疑似官方在安全性方面的更新, 本文的代码已于2016/11/16失效. 新的代码发布在基于 Gloria 实现多说垃圾评论主动式过滤 v2.

之前在JavaScript 字符串字母大小写组合生成这篇文章已经提到, 多说评论框服务近几个月来一直面临被评论机器人刷垃圾评论的问题. 官方的垃圾评论过滤机制毫无作用, 这几个月来的五百多条垃圾评论全是我手动删除的, 不胜其扰.

本文实现了一种用 Gloria 实现多说评论框主动式垃圾评论过滤的方法, 在继续文章之前, 需要你在Gloria.Pub安装 Gloria 的最新版本并查看教程学习 Gloria 的基本用法.

复制并编辑下方代码中的 DOMAIN 值为你的多说域名, 建立 Gloria 任务, 在 Gloria 运行的时候就可以主动将指定 User-Agent 的新评论列为垃圾评论(你可以通过修改 spamFilter 的 if 条件来定制自己的过滤策略).

const DOMAIN = 'xxx.duoshuo.com'

function spamFilter(response) {  
  let ps = response.map(x => {
    if (x.role_name === '游客'
    && ['Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)', 'Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)'].includes(x.agent)) {
      return (nonce) => fetch(`http://${ DOMAIN }/api/posts/spam.json`, {
        method: 'POST'
      , body: (() => {
          let params = new URLSearchParams()
          params.set('post_id', x.post_id)
          params.set('nonce', nonce)
          return params
        })()
      })
    }
  }).filter(x => !!x)

  if (ps.length > 0) {
    return fetch(`http://${ DOMAIN }/admin/`)
    .then(res => res.text())
    .then(html => {
      let [, nonce] = html.match(/window.DUOSHUO.nonce = '([\w\d]+)'/)
      return Promise.all(ps.map(f => f(nonce)))
    })
  }
}

Promise.all([  
  importScripts('gloria-utils')
, fetch(`http://${ DOMAIN }/api/posts/list.json?related[]=thread&limit=30`).then(res => res.json())
])
.then(args => {
  const [, { response }] = args
  let result = spamFilter(response)
  if (result instanceof Promise) {
    return result.then(() => args).catch(() => args)
  }
  return args
})
.then(([{ underscoreString: { stripTags }}, { response }]) => response
  .filter(x => x.role_name !== '管理员')
  .map(x => ({
    title: x.author.name
  , message: stripTags(x.message).trim()
  , id: x.post_id
  , iconUrl: x.author.avatar_url || 'http://static.duoshuo.com/images/noavatar_default.png'
  , url: x.thread.url
  }))
)
.then(commit)

以上代码由指定站点的多说评论提醒修改而来.