discord水群bot教程(2) 消息监控

前言

上一篇文章介绍了机器人的话术抓取以及双号互聊功能的实现,其实如果只需要无脑水群上篇文章介绍的代码就可以实现这个功能了

discord水群bot教程(1) 双号互聊 脚本

但是在实际使用中我们会发现有些项目方不想让机器人获利,所以他们会对频道内聊天的用户进行bot检测,随着时间推移项目方检测的手段也越来越多,比如@全体成员在指定时间内不要发言,或者@你让你回答一些简单的问题,又或者玩什么123木头人的游戏,总之在这个过程中你如果被逮到那么这个账号基本上就要被送出这个服务器了

所以接下来文章介绍的就是如何利用消息监控,让你避开一些项目方的突击检测

教程开始

项目环境配置等一些基础问题,请参考上篇文章的介绍,这里就不多做说明了

首先我们要监控项目方的检测手段,自然先要获取频道内的聊天消息,然后通过对聊天消息分析来判断是否有人在检查机器人,我们还是F12打开浏览器控制台,然后在网页版discord进入我们需要监控的频道,在浏览器控制台network内找到messages请求

post image

请求参数的介绍可以参考上篇文章,这里我们主要是分析接口返回的数据,我们切换到Preview

post image

可以看到我在频道内分别发送了一条普通消息,一条@指定用户的小,一条@所有人的消息,接下来我们就从请求返回值里来分析这3条消息的区别,首先先介绍下我们接下来需要用到的几个字段的含义

post image

这是一条普通消息,它没有@所有人所以它的mention_everyonefalse,它也没@某个用户,所以mentions是一个空数组,接着我们再看看@指定用户的消息返回体和@所有人的消息返回体

post image

这条@指定用户的消息大家可以发现,mentions数组里有一个用户对象,这个就是我们@的那个用户的信息,同时消息的内容content里我们@的用户那部分的文字转换成了<@!用户id>这样一个格式

post image

最后这条消息我们可以看到字段mention_everyone的值变成了true,这就代表这条消息是一个@所有人的消息

经过上面的分析,现在大家应该对区分消息类型有了一定了解,接下来我们就可以来实现我们监控脚本

const axios = require("axios");

const proxyHost = '127.0.0.1' // 代理ip
const proxyPort = '7890' // 代理端口号
const authorization = '' // 账号的authorization
const channel_id = '' //频道id
let monitorTime = new Date().getTime() // 监控时间,用于避免重新识别老消息
const monitor = () => {
    let header = {
        "Authorization": authorization,
        "Content-Type": "application/json",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
    }
    axios({
        method: 'GET',
        url: `https://discord.com/api/v9/channels/${channel_id}/messages?limit=50`,
        headers: header,
        proxy: (proxyHost && proxyPort)?{
            host: proxyHost,
            port: proxyPort
        }: null,
    }).then(res => {
        // 对聊天消息进行分析
        messageParse(res.data)
        startTime = new Date().getTime()
    }).catch(e => {
        console.log(e.message)
    })
}

setInterval(function () {// 监听器,每60s执行一次
    monitor()
},60*1000);

首先还是使用axios对messages接口进行调用,通过构建一个定时器来进行监听,当我们拿到聊天的数据也就是上面的res.data,我们把数据传给我们的分析函数messageParse

我这里对消息进行了下面几个识别

  • 识别@全员和@自己

  • 识别管理发言+发言内容包含关键字

  • 仅识别发言内容包含关键字

  • 仅识别管理发言

// 管理员用户的id
const mods = [
    '933625356789887006'
]
// 关键字
const keywords = [
    '停止说话','禁止发言','123木头人'
]

/**
 * 判断消息是否含关键字
 */
const isIncludeKeywords = (message) => {
    let flag = false
    keywords.forEach(keyword => {
        if(message.includes(keyword)){// 含关键字的消息
            flag = true
        }
    })
    return flag
}

// 消息信息解析
const messageParse = (data) => {
    // 优先级 @全员 > @自己 > mod发言+含关键字 > 含关键字 > mod发言
    data.forEach(item => {
        if(new Date(item.timestamp).getTime() < monitortTime){// 时间筛选,避免重新识别老消息
            return
        }
        if(item.mention_everyone){// @全体成员的消息
            console.log(`监听到一条@全员的消息:`)
            console.log('-------------------')
            console.log(`消息: ${item.content}`)
            console.log('-------------------')
            // 执行你自己的应对策略
        }else if(item.content.includes(account_id)){// @自己的消息
            console.log(`监听到一条@你的消息:`)
            console.log('-------------------')
            console.log(`消息: ${item.content}`)
            console.log('-------------------')
            // 执行你自己的应对策略
        }else if(mods.includes(item.author.id) && isIncludeKeywords(item.content)){// mod发言+含关键字
            console.log(`监听到一条mod发言+含关键字的消息:`)
            console.log('-------------------')
            console.log(`消息: ${item.content}`)
            console.log('-------------------')
            // 执行你自己的应对策略
        }else if(isIncludeKeywords(item.content)){
            console.log(`监听到含关键字的消息:`)
            console.log('-------------------')
            console.log(`消息: ${item.content}`)
            console.log('-------------------')
            // 执行你自己的应对策略
        }else if(mods.includes(item.author.id)){
            console.log(`监听到一条mod发言的消息:`)
            console.log('-------------------')
            console.log(`消息: ${item.content}`)
            console.log('-------------------')
            // 执行你自己的应对策略
        }
    })

}

可以看到我的消息处理中,首先对消息时间进行了筛选,我们只处理指定时间后的消息,monitortTime的值会随着每次请求结束而更新

然后我按照我的优先级进行消息的判断,如果符合判断条件就会执行你自己设置的应对策略,如:

  • 停止运行你的水群脚本

  • 对接你的话术库进行自动回复又或者接入ai回复进行自动回复

  • 接入你的消息推送,把消息推送到微信或者邮件,让你第一时间知道,然后亲自来进行处理

你也可以针对不同情况的紧急程度进行分级应对,这些将由你自己来决定了,这篇教程就到这了,完整代码稍后会上传到github,将按照class1 class2分支来区分

课程2代码地址

来自DFarm Club

-----------------------------------------分割线-----------------------------------------

答应大家的GUI版本已经上传github了,代码在main分支,打包好的exe放在Releases

功能基本上就是前两篇课程内介绍过的内容,不会使用可以参考课程内的代码实现

水群
水群
互聊
互聊
监听
监听