内容简介:在我看来,再牛逼的技术不落到实处永远是纸上谈兵,秉承着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!
文 / lastSeries
本文为创宇前端读者投稿,略有增删
编 / 荧声
关注作者
https://juejin.im/user/5987d2b6f265da3e292a63d4
感谢您的阅读
欢迎关注、点赞、留言讨论、分享转发支持我们
期望赞赏作者?
请查看公众号菜单中「关于」-「支持我们」
欢迎读者来稿
创宇前端接受首发或授权转载的原创技术分享
赠送任选技术书籍聊表鼓励
不侵占作者任何权利
经常错过推送?
给创宇前端公众号加上星标吧
以上所述就是小编给大家介绍的《当前端玩起 CoolQ:做个技术文章推送机器人》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 日常收集的精品技术文章
- 技术文章配图指南
- 如何写出高质量的技术文章?
- 分享下写技术文章的思路
- [Laravel] 趣编程之技术文章评论列表 Api 任务的开发心得
- 资源 | 最全的12篇无人驾驶技术系列文章
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。