物联网服务NodeJs-5天学习第三天实战篇④ ——QQ机器人,实现自动回复重要提醒

Posted 单片机菜鸟哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了物联网服务NodeJs-5天学习第三天实战篇④ ——QQ机器人,实现自动回复重要提醒相关的知识,希望对你有一定的参考价值。

【NodeJs-5天学习】第三天实战篇④ ——QQ群自动回复机器人

面向读者群体

  • ❤️ 电子物联网专业同学,想针对硬件功能构造简单的服务器,不需要学习专业的服务器开发知识 ❤️
  • ❤️ 业余爱好物联网开发者,有简单技术基础,想针对硬件功能构造简单的服务器❤️
  • ❤️ 本篇创建记录 2023-03-12 ❤️
  • ❤️ 本篇更新记录 2023-03-12 ❤️

技术要求

  • HTMLCSSJavaScript基础更好,当然也没事,就直接运行实例代码学习

专栏介绍

  • 通过简短5天时间的渐进式学习NodeJs,可以了解到基本的服务开发概念,同时可以学习到npm、内置核心API(FS文件系统操作、HTTP服务器、Express框架等等),最终能够完成基本的物联网web开发,而且能够部署到公网访问。

🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝

1. 前言

NodeJs能否实现一个QQ机器人,对于一些重复性的信息能够自动回复或者一些重要时刻做一些信息提醒?

比如:

  • 在一个群组里面的时候,当有人@你要物联网学习资料的时候,可以直接回复发送出去,类似于公众号里面的自动回复
  • 对于一些重要的节日,能够给一些特别的朋友发送一些问候
  • 每天固定时间发送天气预报

带着以上这些问题,来进入本篇的知识学习。

学习QQ模块 oicq

2.实现思路

核心实现原理就是:

  • ① 在NodeJs服务器上搭建一个QQ客户端,这里使用OICQ模块来实现。因为是搭建客户端,QQ不允许多个地方同时登陆,所以一般手机上会被踢下线。建议群组机器人可以另外申请一个QQ号。
  • ② 让它实时去监听客户端上收到的所有消息(比如A好友发送过来的私聊消息、B好友发送过来的私聊消息、xxx群发送过来的群组消息)
  • ③ 核心业务处理:根据需求来回复信息,比如通过特定群组ID发送群消息实现群组自动回复,通过给特定用户(UID)发送私聊消息。基于这个模型可以进一步扩展自己的需求。

所以核心学习还是在于了解OICQ模块。

2.1 oicq模块

2.1.1 安装模块

npm install oicq --save

然后我们可以运行一个最简单的代码:

const  createClient  = require("oicq")
const account = 147258369 // 改为自己的qq号码
const client = createClient(account)

client.on("system.online", () => console.log("Logged in!"))
client.on("message", e => 
  console.log(e)
  e.reply("hello world", true) //true表示引用对方的消息
)

client.on("system.login.qrcode", function (e) 
  //扫码后按回车登录
  process.stdin.once("data", () => 
    this.login()
  )
).login()

这时候会触发一个扫描二维码的操作,用手机QQ扫描一下,然后按下回车键即可。

2.1.2 官方说明文档(必须看)

官方文档也没有太多复杂内容,根据具体需求(私聊、群聊、好友等等)去翻阅即可。

大多数情况下我们关注Group、User、Events、消息体这几个,使用频率比较高,知道它们的意思即可(字面意思也很容易理解)。

  • 系统事件

  • 群组相关操作
    群。 notice.group 和 message.group 相关事件中含有此实例 ( e.group 访问)
    或者使用 client.pickGroup() 获得群实例。


  • 私聊相关

2.1.3 常见API文档(重要)

2.2 NodeJs服务器代码


整体代码不多,主要分为几块:

  • qq客户端监听
  • 私聊匹配词
  • 群聊匹配词
  • 提醒用户(暂未实现)

2.2.1 qq客户端监听

// 库说明: https://github.com/takayama-lily/oicq

const createClient = require("oicq");
const uin = xxxxxxx; // qq账号
const bot = createClient(uin)
const remindPrivate = require('./config/remind/remind_private.js')
const responseGroup = require('./config/response/response_group.js')
const responsePrivate = require('./config/response/response_private.js')

bot.on("system.login.captcha", ()=>
  process.stdin.once("data", input=>
    bot.captchaLogin(input);
  );
);

bot.on("system.online", ()=>console.log("服务器:QQ上线"));
// system.offline.kickoff 被其他客户端踢下线, 默认不自动重登(见相关配置 kickoff)
bot.on("system.offline.kickoff", ()=>console.log("服务器踢下线"));
// system.offline.network 网络不通畅或服务器繁忙, 默认自动重登(见相关配置 reconn_interval)
bot.on("system.offline.network", ()=>console.log("网络错误导致下线"));

bot.on("message.group", data=>
    console.log('服务器:收到一条群组消息')
    console.log(data)
    var groupName = data.group_name
    var senderName = data.sender.nickname
    var message = data.raw_message
    console.log(`[$groupName]$senderName: $message`)

    var reply = responseGroup.getReply(message)
    if (reply) 
      bot.sendGroupMsg(data.group_id, reply);
    
);

bot.on("message.private", data=>
    console.log('服务器:收到一条私聊消息')
    // console.log(data);
    var senderName = data.sender.nickname
    var message = data.raw_message
    console.log(`[私聊]$senderName: $message`)
    var reply = responsePrivate.getReply(message)
    if (reply) 
      bot.sendPrivateMsg(data.user_id, reply)
    
);

bot.on("message.discuss", data=>
    console.log('服务器:收到一条讨论组消息')
    console.log(`[$data.group_name]$data.sender.nickname: $data.raw_message`)
);

// bot.on("message", data=>
//   console.log(data);
// //   if (data.group_id > 0)
// //     bot.sendGroupMsg(data.group_id, "谁说只能回复hello");
// //   else
// //     bot.sendPrivateMsg(data.user_id, "hello");
// );

const psd = "xxxxxx";  // 填上密码
bot.login(psd);

这里需要改一下自己的qq账号和密码。

在这里插入代码片

同时它主要是:

  • 监听私聊消息(message.private
  • 监听群聊消息(message.group

注意:这里登陆会把自己客户端的账号踢下线

2.2.2 私聊匹配词

就是当收到的私聊消息满足这些匹配词的时候自动回复给对方。

  • response_private.json 配置文件(这里可以继续添加新的)
[
	"match": "你好",
	"reply": "你好"
, 
	"match": "鸟哥",
	"reply": "怎么了?"
, 
	"match": "博哥",
	"reply": "怎么了?"
, 
	"match": "菜鸟哥",
	"reply": "怎么了?"
, 
	"match": "菜鸟哥你好",
	"reply": "你好"
, 
	"match": "博哥你好",
	"reply": "你好"
, 
	"match": "博哥你做什么工作",
	"reply": "偏软件方向工作"
]
  • response_private.js 匹配判断
const fs = require('fs')

// 设备配置信息,需要通过配置校验才会通过
var fileName = `$__dirname/response_private.json`;
var config = JSON.parse(fs.readFileSync(fileName));
var matchToReplyMap = new Map()
config.forEach(element => 
  var match = element.match
  var reply = element.reply
  if (matchToReplyMap.has(match)) 
    throw console.error('response_private 配置文件出现重复ID,请检查!' + uid);
  
  matchToReplyMap.set(match, reply)
)

console.log("response_private 配置信息:")
console.log(matchToReplyMap)

function getReply(content) 
  var result = null
  matchToReplyMap.forEach((reply,match)=>
    if(content.indexOf(match) > -1) 
      result = reply
    
  )

   return result


module.exports = 
  getReply

现在的匹配逻辑比较简单,有兴趣的同学可以进一步优化。

2.2.3 群聊匹配词


就是当收到的群聊消息满足这些匹配词的时候自动回复给到对应群。

  • response_group.json 配置文件(这里可以继续添加新的)
[
	"match": "博哥你好",
	"reply": "你好"
,
	"match": "鸟哥",
	"reply": "怎么了?"
,
	"match": "博哥",
	"reply": "怎么了?"
,
	"match": "菜鸟哥",
	"reply": "怎么了?"
,
	"match": "博哥你做什么工作",
	"reply": "偏软件方向工作"
,
	"match": "@8266学习请Csdn搜单片机菜鸟哥",
	"reply": "博哥有点忙,有事先留言"
,
	"match": "@单片机菜鸟",
	"reply": "博哥有点忙,有事先留言"
]
  • response_group.js 匹配判断
const fs = require('fs')

// 设备配置信息,需要通过配置校验才会通过
var fileName = `$__dirname/response_group.json`;
var config = JSON.parse(fs.readFileSync(fileName));
var matchToReplyMap = new Map()
config.forEach(element => 
  var match = element.match
  var reply = element.reply
  if (matchToReplyMap.has(match)) 
    throw console.error('response_group 配置文件出现重复ID,请检查!' + uid);
  
  matchToReplyMap.set(match, reply)
)

console.log("response_group 配置信息:")
console.log(matchToReplyMap)

function getReply(content) 
  var result = null
  if (content.indexOf('来自群管理员') > -1 || content.indexOf('Q群管家') > -1) 
    return result
  
  matchToReplyMap.forEach((reply,match)=>
    if(content.indexOf(match) > -1) 
      result = reply
    
  )

   return result


module.exports = 
  getReply

现在的匹配逻辑比较简单,有兴趣的同学可以进一步优化。

2.3 测试效果

  • 测试1:私聊,测试以上的关键字

  • 测试2:群聊,测试以上的关键字

3.总结

篇④结合ESP8266来开发qq机器人应用——自动回复某些特定匹配信息。麻雀虽小五脏俱全,初学者需要理解oicq并加以实际应用。

以上是关于物联网服务NodeJs-5天学习第三天实战篇④ ——QQ机器人,实现自动回复重要提醒的主要内容,如果未能解决你的问题,请参考以下文章

物联网服务NodeJs-5天学习第三天实战篇③ ——基于MQTT的环境温度检测

物联网服务NodeJs-5天学习第三天实战篇① ——10行代码给她造个熬夜提醒睡觉机器人

物联网服务NodeJs-5天学习第二天篇④ ——项目模块化

物联网服务NodeJs-5天学习第四天存储篇④ ——基于MQTT的环境温度检测,升级存储为mysql

物联网服务NodeJs-5天学习第一天篇④ ——了解NodeJs回调函数和事件驱动机制

基于物联网的NodeJs-5天学习入门指引