当前端玩起 CoolQ:做个技术文章推送机器人

栏目: PHP · 发布时间: 6年前

内容简介:在我看来,再牛逼的技术不落到实处永远是纸上谈兵,秉承着2019 年了,如何将前端知识学以致用呢 ️?前段时间 QQ 群里大佬们突然玩起了突然脑子里闪过一道光 :zap:️,卧槽牛哔呀,我也要玩!作为一个每天早上醒来都有新轮子的前端,不如搞个技术文章推送吧!

背景

在我看来,再牛逼的技术不落到实处永远是纸上谈兵,秉承着 学以致用 的校训。一个字 “干” 就完事了:muscle:。

2019 年了,如何将前端知识学以致用呢 ️?前段时间 QQ 群里大佬们突然玩起了 CoolQ 机器人,用机器人进行在线陪聊、在线点歌、在线搜图乃至……(你能想到的一切:smirk:)

突然脑子里闪过一道光 :zap:️,卧槽牛哔呀,我也要玩!作为一个每天早上醒来都有新轮子的前端,不如搞个技术文章推送吧!

啥是 CoolQ

说实话,在 CoolQ 的官网看了半天,愣是不知道它是个什么玩意!难道你都不介绍一下自己是干哈的嘛,差评。

(编者按:这个有一定的历史原因……)

下面的介绍来自百度百科:

酷Q,是一款基于 Smart 协议功能强大的机器人软件,它可以通过安装插件实现自动审核他人申请入群、自动踢人、自动管理群等自动化操作,还能实现自动群聊、自动聊天,起到活跃群组气氛的重要作用,节省您的宝贵时间。

好牛哔,接下来我只是使用了 CoolQ 消息推送的功能:flushed:。

技术文章来源

如果让你来搞,你会怎么办呢?你可能会想到爬虫。可以爬页面,也可以爬接口……这里我用 RSS 来实现。

一部分年轻的朋友可能已经没有听说过 RSS 了,时代的眼泪……你可以在这里读到相关介绍:http://www.runoob.com/rss/rss-intro.html

然而,并不是所有的网站都提供 RSS 服务,比如说 掘金 。在这里安利 RSSHub,它替我们获取页面内容并生成 RSS 源,为我们懒人提供了福利。如果里面没有找到你想要的内容,那么很抱歉只能自己手撕代码了。

实操

1. 安装 CoolQ

CoolQ 官网只提供 Windows 版本,因此,如果想要装在 Linux 或 macOS 上,官方推荐通过 Docker 安装对应的镜像文件。(9102 年了,如果你还不会 Docker 你就 out 了,有些知识不深可以,但是广一点是没有任何毛病的 )

一般我们安装普通版(https://cqp.cc/t/34558)。

如果默认的功能不能满足你的需求,想要自己开发一些好玩新奇的功能,则可以安装开发版(https://github.com/richardchien/cqhttp-docker)。

接下来我们分别介绍这两个版本的安装方式。

普通版安装

1.1. 获取镜像

docker pull coolq/wine-coolq

1.2. 创建文件夹,用于存放 CoolQ 持久化数据

# 任意路径均可
mkdir /root/coolq-data

1.3. 运行镜像

docker run --name=coolq --rm -p 9000:9000 -v /root/coolq-data:/home/user/coolq coolq/wine-coolq
  • --name 创建一个容器
  • --rm 这个参数是说容器退出之后随之将其删除。默认情况下,为了排障需求,退出的容器不会立即删除,除非手动 docker rm
  • -p <宿主端口>:<容器端口> -p ,是用来映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问
  • -v 指定挂载一个本地主机的目录到容器中去

1.4. 启动 CoolQ

打开浏览器 输入 localhost:9000

点击 connect 输入 默认密码 MAX8char

输入QQ号及密码(推荐注册小号,以防风险)登录 CoolQ

开发版安装

1.1. 获取镜像

docker pull richardchien/cqhttp:latest

1.2. 创建文件夹,用于存放 CoolQ 持久化数据

1.3. 运行镜像

docker run -ti --rm --name cqhttp -p 9000:9000 -p 5700:5700 -v /root/coolq-data:/home/user/coolq richardchien/cqhttp

1.4. 启动 CoolQ

2. 安装MongoDB

略(相信这一定不会难道小天才的你 :wink:)

  • 官方文档:https://docs.mongodb.com/manual/installation/

  • 菜鸟文档:http://www.runoob.com/mongodb/mongodb-intro.html

3. 撸代码

爬文章

async function crawl(url) {try {   const feed = await parser.parseURL(url);   const items = feed.items.map(({ title, link, guid = link }) => {
     title = title.trim();
     link = link.trim();
     guid = guid.trim();     console.log(title, link);     return { title, link, guid };
   });   return items;
 } catch (err) {   console.log(err);
 }
}

数据库插入数据

async function insert(db, { title, link, guid }) {const collection = db.collection(collectionName);// Insert some documentstry {
   await collection.updateOne(
     {
       guid
     },
     {
       $set: { title, link, guid },
       $setOnInsert: { status: 0 }
     },
     {
       upsert: true
     }
   );
 } catch (err) {   console.log(err);
 }
}

数据库查找数据

status 0: 未推送 1: 已推送

async function find(db) {const collection = db.collection(collectionName);// Find some documentstry {   return await collection
     .find({
       status: 0
     })
     .toArray();
 } catch (err) {   console.log(err);
 }
}

推送消息

group_id 群号

const request = require('superagent');

async function send(message) {return await request
   .post('http://0.0.0.0:5700/send_group_msg')
   .send({ group_id: XXX, message })
   .set('Accept', 'application/json');
}

数据爬取及存储代码整合

const MongoClient = require('mongodb').MongoClient;const Parser = require('rss-parser');const parser = new Parser();const url = 'mongodb://localhost:27017';const dbName = 'robot'; // 数据库名const collectionName = 'juejin'; // 集合名(表名)const pullList = ['https://rsshub.app/juejin/category/frontend'];// 插入async function insert(db, { title, link, guid }) {const collection = db.collection(collectionName);// Insert some documentstry {
   await collection.updateOne(
     {
       guid
     },
     {
       $set: { title, link, guid },
       $setOnInsert: { status: 0 }
     },
     {
       upsert: true
     }
   );
 } catch (err) {   console.log(err);
 }
}// 爬虫async function crawl(url) {try {   const feed = await parser.parseURL(url);   const items = feed.items.map(({ title, link, guid = link }) => {
     title = title.trim();
     link = link.trim();
     guid = guid.trim();     console.log(title, link);     return { title, link, guid };
   });   return items;
 } catch (err) {   console.log(err);
 }
}

(async () => {// Create a new MongoClientconst client = new MongoClient(url);try {   // Use connect method to connect to the Server
   await client.connect();   console.log('Connected successfully to server');   const db = client.db(dbName);   const promises = pullList.map((value) => {     return (async () => {       const items = await crawl(value);       const insertPromises = items.map((item) => {         return insert(db, item);
       });

       await Promise.all(insertPromises);
     })();
   });

   await Promise.all(promises).then(() => {
     client.close();
   });
 } catch (err) {   console.log(err.stack);
 }
})();

数据推送及查找代码整合

为了保障代码的运行记得修的修改为自己的 QQ 群号(以下仅以发送群组消息为例,具体的也可以是发送私信,讨论组消息)

const MongoClient = require('mongodb').MongoClient;const request = require('superagent');const url = 'mongodb://localhost:27017';const dbName = 'robot'; // 数据库名const collectionName = 'juejin'; // 集合名(表名)// 查找async function find(db) {const collection = db.collection(collectionName);// Find some documentstry {   return await collection
     .find({
       status: 0
     })
     .toArray();
 } catch (err) {   console.log(err);
 }
}// 更新async function update(db, { guid }) {const collection = db.collection(collectionName);// Update some documentstry {
   await collection.updateOne(
     {
       guid
     },
     {
       $set: { status: 1 }
     }
   );
 } catch (err) {   console.log(err);
 }
}// 推送 群组async function send(message) {return await request
   .post('http://0.0.0.0:5700/send_group_msg')
   .send({ group_id: XXX, message }) // 记得修改哟:blush:
   .set('Accept', 'application/json');
}

(async () => {// Create a new MongoClientconst client = new MongoClient(url);try {   // Use connect method to connect to the Server
   await client.connect();   console.log('Connected successfully to server');   const db = client.db(dbName);   const docs = await find(db);   console.log(docs);   let message = '';
   message = docs.reduce((acu, { title, link }, index) => {     return `${acu}${title} ${link}${index === docs.length - 1 ? '' : '\n'}`;
   }, message);   const { text } = await send(message);   const { status, retcode } = JSON.parse(text);   if (status === 'ok' && retcode === 0) {     const promises = docs.map((value) => {       return update(db, value);
     });

     await Promise.all(promises);
   } else {     console.log(status, retcode);
   }

   client.close();
 } catch (err) {   console.log(err.stack);
 }
})();

展望

以上只是对于 CoolQ 的简单应用,最近还有一个 饿了么外卖推送 的想法,就是根据商家的满减优惠计算出 最优套餐 ,但是碍于算法的问题,暂时卡在了这一块。如果你还有什么其他想法欢迎一起交流~

最后,送诸位一句 大胆假设,小心求证,人人都是科学家:joy: ,欢迎晒出你的 idea!

当前端玩起 CoolQ:做个技术文章推送机器人

文 / lastSeries

本文为创宇前端读者投稿,略有增删

编 / 荧声

关注作者

https://juejin.im/user/5987d2b6f265da3e292a63d4

感谢您的阅读

欢迎关注、点赞、留言讨论、分享转发支持我们

期望赞赏作者?

请查看公众号菜单中「关于」-「支持我们」

欢迎读者来稿

创宇前端接受首发或授权转载的原创技术分享

赠送任选技术书籍聊表鼓励

不侵占作者任何权利

经常错过推送?

给创宇前端公众号加上星标吧

当前端玩起 CoolQ:做个技术文章推送机器人


以上所述就是小编给大家介绍的《当前端玩起 CoolQ:做个技术文章推送机器人》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Effective JavaScript

Effective JavaScript

David Herman / Addison-Wesley Professional / 2012-12-6 / USD 39.99

"It's uncommon to have a programming language wonk who can speak in such comfortable and friendly language as David does. His walk through the syntax and semantics of JavaScript is both charming and h......一起来看看 《Effective JavaScript》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具