QQbat机器
基于go-cqhttp与JavaScript 语言实现,因为不想老打开学习通看课表,觉得比较麻烦,于是决定做一个QQ机器人来给我推送消息,挂在服务器上,推送课表,定时消息,处理群聊
1 功能如下
序号 | 模式 (私聊模式) | 模式 (群聊模式) |
1. | 重置模式: (y) | 撤回消息 |
2. | 天气模式: (t) | 看视频 |
3. | 聊天模式:(chat) | 通知助手 |
4. | 图片模式: (img) | 禁言功能 |
5. | 今日新闻: (f) | (待开发) |
6. | 定时消息推送:(h 例 12,4,xxxx,早早早) | |
7. | 学习通课表提送功能 (w 第三周发送3) | |
8. | 看小视频(v) |
2首先下载go-cqhttp
下载对应版本
1.window运行
双击go-cqhttp_*.exe,根据提示生成运行脚本
双击运行脚本
2.生成bat
3.配置 config.yml
进入配置qq账号密码
uin: xxxxxxxx # QQ账号
password: xxxxxx # 密码为空时使用扫码登录
4. 选择通信方式为 0 3
- http: # HTTP 通信设置
address: 0.0.0.0:5000 # HTTP监听地址
timeout: 5 # 反向 HTTP 超时时间, 单位秒,<5 时将被忽略
long-polling: # 长轮询拓展
enabled: false # 是否开启
max-queue-size: 2000 # 消息队列大小,0 表示不限制队列大小,谨慎使用
middlewares:
<<: *default # 引用默认中间件
post: # 反向HTTP POST地址列表
# 反向WS设置
- ws-reverse:
# 反向WS Universal 地址
# 注意 设置了此项地址后下面两项将会被忽略
universal: ws://127.0.0.1:5700
# 反向WS API 地址
api: ws://your_websocket_api.server
# 反向WS Event 地址
event: ws://your_websocket_event.server
# 重连间隔 单位毫秒
reconnect-interval: 3000
middlewares:
<<: *default # 引用默认中间件
3.开启服务
双击go-cqhttp.bat
./go-cqhttp enter运行
4.api接口请访问
https://docs.go-cqhttp.org/里面有api接口,有很多功能
实现功能
1.首先是要跟go-cqhttp传输消息,这里我们用ws监听上报的消息(相当于ws服务端,端口为5700,跟我们)
const {WebSocketServer} = require("ws")
const receive = require("./receive")
const SendMessage = require("./send")
const ws = new WebSocketServer({port: 5700});
exports.wsclint = () => {
ws.on('connection', (socket) => {
console.log('客户端连接成功')
// 监听对方发送的消息
socket.on('message', function message(res) {
console.log(res.toString())
data = JSON.parse(res)
receive.receive(data)
});
socket.on("close", socket => {
SendMessage.SendMessage
console.log("推送服务器断开连接")
})
})
}
发送消息我们可以采用axios请求http://127.0.0.1:5000+api接口(例如私聊消息 http://127.0.0.1:5000/send_private_msg )
2.根据模式来回复
exports.privates = (data) => {
let status = readFileSync("./private/status.txt").toString()
let list = ["f", "img", "chat", "t", "y", "h", "w"]
let model = true
if (status) {
while (model) {
if (list.includes(data.message)) {
writeFileSync("./private/status.txt", data.message)
SendMessage(data.message_type, "模式更改为: " + data.message, data.user_id)
}
if (data.message === "y") {
writeFileSync("./private/status.txt", "")
SendMessage(data.message_type, "模式重置: ", data.user_id)
SendMessage("[CQ:at,qq=" + data.user_id + "]" + "\n" + "请选择:" + "\n" + "重置模式: (y)" + "\n" + "天气模式:(t 例:武汉的天气)" + "\n" + "聊天模式:(chat)" + "\n" + "图片模式: (img)" + "\n" + "今日新闻:(f) " + "\n" + "看抖音视频:(v)" + "\n" + "(y,t,chat,img 全局生效)\n", data.user_id)
}
break
}
status = readFileSync("./private/status.txt").toString()
switch (status) {
case "chat":
if (data.message === status) {
return;
}
send.QQcaht(data.message_type, data.user_id, data.message)
break
case "t":
if (data.message === status) {
return;
}
let city = data.message.slice(0, data.message.indexOf("的"))
send.WeatherMessage(data.message_type, data.user_id, city)
break
case "img":
if (data.message === status) {
return;
}
send.imgIs(data.message_type, data.user_id)
break
case "f":
if (data.message === status) {
return;
}
send.hotmessage(data.message_type, data.user_id)
break
case "h":
if (data.message === status) {
return;
}
setTime(data.message_type, data.message, data.user_id)
break
case "w":
if (data.message === status) {
return;
}
getCookie(data.message_type, data.message, data.user_id)
break
}
} else {
if (!list.includes(data.message)) {
SendMessage(data.message_type, "[CQ:record,file=http://39.98.40.255:3000/img/1.mp3]", data.user_id)
SendMessage(data.message_type, "输入的不对呦,靓仔", data.user_id)
SendMessage(data.message_type, "[CQ:at,qq=" + data.user_id + "]" + "\n" + "请选择:" + "\n" + "重置模式: (y)" + "\n" + "天气模式:(t 例:武汉的天气)" + "\n" + "聊天模式:(chat)" + "\n" + "图片模式: (img)" + "\n" + "今日新闻:(f) " + "\n" + "消息推送:(h 例 12,4,3096407768,早早早) " + "\n" + "看抖音视频:(v)" + "\n" + "(y,t,chat,img 全局生效)\n"
, data.user_id)
writeFileSync("./private/status.txt", "")
return
}
if (data.message === "y") {
SendMessage(data.message_type, "已处于重置模式", data.user_id)
return
}
writeFileSync("./private/status.txt", data.message)
SendMessage(data.message_type, "模式更改为: " + data.message, data.user_id)
}
}
3.因为我们发送消息有群聊消息和私聊消息,所以我们封装一个专门发送消息的模块,根据传进来的消息类型来决定发送什么消息,用来通知消息
//发送qq消息
const axios = require("axios");
exports.SendMessage = async (types, weather, id) => {
if (types === "private") {
console.log(weather)
const {data: res} = await axios({
method: "post",
url: "http://127.0.0.1:5000/send_private_msg",
data: {
user_id: id,
message: weather,
auto_escape: false,
}
})
console.log(res)
} else {
console.log(weather)
const {data: res} = await axios({
method: "post",
url: "http://127.0.0.1:5000/send_group_msg",
data: {
group_id: id,
message: weather,
auto_escape: true,
}
})
console.log(res)
}
}
4查询天气(自己找一个天气接口,我用的是免费API公众号的),这里调用sendMessage来发送天气消息
exports.WeatherMessage = async (types, id, citys) => {
try {
const {data: res} = await axios({
methods: "post",
url: "https://way.jd.com/he/freeweather",
params: {city: citys, appkey: "XXXXXXXXXXX"},
})
console.log(res)
if (res.code === '10000') {
weather = `主人查询时间: ${new Date().toLocaleString()},\n城市:${res.result.HeWeather5[0].basic.city},\n日期:${res.result.HeWeather5[0].hourly_forecast[0].date},\n天气:${res.result.HeWeather5[0].hourly_forecast[0].cond.txt},\n风向:${res.result.HeWeather5[0].hourly_forecast[0].wind.dir},\n风速:${res.result.HeWeather5[0].hourly_forecast[0].wind.spd},\n运动:${res.result.HeWeather5[0].suggestion.sport.txt}\n温度:${res.result.HeWeather5[0].hourly_forecast[0].tmp},\n穿衣:${res.result.HeWeather5[0].suggestion.drsg.txt}\n生活指数:${res.result.HeWeather5[0].suggestion.drsg.brf}\n感冒指数:${res.result.HeWeather5[0].suggestion.flu.brf}\n提示:${res.result.HeWeather5[0].suggestion.flu.txt}`
await sendMessage.SendMessage(types, weather, id)
return
}
weather = "获取今日天气失败,请联系主人"
await sendMessage.SendMessage(types, weather, id)
} catch (e) {
console.log(e)
if (e) {
await sendMessage.SendMessage(types, "输入有误", id)
}
}
}
剩下的功能明日在更,还有实验没写完