上一篇文章介绍了机器人的话术抓取以及双号互聊功能的实现,其实如果只需要无脑水群上篇文章介绍的代码就可以实现这个功能了
但是在实际使用中我们会发现有些项目方不想让机器人获利,所以他们会对频道内聊天的用户进行bot检测,随着时间推移项目方检测的手段也越来越多,比如@全体成员在指定时间内不要发言,或者@你让你回答一些简单的问题,又或者玩什么123木头人的游戏,总之在这个过程中你如果被逮到那么这个账号基本上就要被送出这个服务器了
所以接下来文章介绍的就是如何利用消息监控,让你避开一些项目方的突击检测
项目环境配置等一些基础问题,请参考上篇文章的介绍,这里就不多做说明了
首先我们要监控项目方的检测手段,自然先要获取频道内的聊天消息,然后通过对聊天消息分析来判断是否有人在检查机器人,我们还是F12打开浏览器控制台,然后在网页版discord进入我们需要监控的频道,在浏览器控制台network内找到messages请求
请求参数的介绍可以参考上篇文章,这里我们主要是分析接口返回的数据,我们切换到Preview
可以看到我在频道内分别发送了一条普通消息,一条@指定用户的小,一条@所有人的消息,接下来我们就从请求返回值里来分析这3条消息的区别,首先先介绍下我们接下来需要用到的几个字段的含义
这是一条普通消息,它没有@所有人所以它的mention_everyone
是false
,它也没@某个用户,所以mentions
是一个空数组,接着我们再看看@指定用户的消息返回体和@所有人的消息返回体
这条@指定用户的消息大家可以发现,mentions
数组里有一个用户对象,这个就是我们@的那个用户的信息,同时消息的内容content
里我们@的用户那部分的文字转换成了<@!用户id>这样一个格式
最后这条消息我们可以看到字段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
的值会随着每次请求结束而更新
然后我按照我的优先级进行消息的判断,如果符合判断条件就会执行你自己设置的应对策略,如:
你也可以针对不同情况的紧急程度进行分级应对,这些将由你自己来决定了,这篇教程就到这了,完整代码稍后会上传到github,将按照class1 class2分支来区分
来自DFarm Club
-----------------------------------------分割线-----------------------------------------
答应大家的GUI版本已经上传github了,代码在main分支,打包好的exe放在Releases
功能基本上就是前两篇课程内介绍过的内容,不会使用可以参考课程内的代码实现