編者按:好久不見,今天的文章來自創宇前端讀者投稿。創宇前端接受讀者首發或授權轉載的原創技術分享,我們會充分尊重讀者的所有權益,並對選用文章作者贈送任選技術書籍聊表心意 :)
背景
在我看來,再牛逼的技術不落到實處永遠是紙上談兵,秉承著 學以致用
的校訓。一個字 “幹” 就完事了?。
2019 年了,如何將前端知識學以致用呢?️?前段時間 QQ 群裡大佬們突然玩起了 CoolQ
機器人,用機器人進行線上陪聊、線上點歌、線上搜圖乃至……(你能想到的一切?)
突然腦子裡閃過一道光 ⚡️,臥槽牛嗶呀,我也要玩!作為一個每天早上醒來都有新輪子的前端,不如搞個技術文章推送吧!
啥是 CoolQ
說實話,在 CoolQ
的官網看了半天,愣是不知道它是個什麼玩意!難道你都不介紹一下自己是幹哈的嘛,差評。
(編者按:這個有一定的歷史原因……)
下面的介紹來自百度百科:
酷Q,是一款基於 Smart 協議功能強大的機器人軟體,它可以通過安裝外掛實現自動稽核他人申請入群、自動踢人、自動管理群等自動化操作,還能實現自動群聊、自動聊天,起到活躍群組氣氛的重要作用,節省您的寶貴時間。
好牛嗶,接下來我只是使用了 CoolQ
訊息推送的功能?。
技術文章來源
如果讓你來搞,你會怎麼辦呢?你可能會想到爬蟲。可以爬頁面,也可以爬介面……這裡我用 RSS 來實現。
一部分年輕的朋友可能已經沒有聽說過 RSS 了,時代的眼淚……你可以在這裡讀到相關介紹::www.runoob.com/rss/rss-int…
然而,並不是所有的網站都提供 RSS 服務,比如說 掘金
。在這裡安利 RSSHub,它替我們獲取頁面內容並生成 RSS 源,為我們懶人提供了福利。如果裡面沒有找到你想要的內容,那麼很抱歉只能自己手撕程式碼了
實操
1. 安裝 CoolQ
CoolQ
官網只提供 Windows 版本,因此,如果想要裝在 Linux 或 macOS 上,官方推薦通過 Docker
安裝對應的映象檔案。(9102 年了,如果你還不會 Docker 你就 out 了,有些知識不深可以,但是廣一點是沒有任何毛病的 ?)
一般我們安裝普通版。
如果預設的功能不能滿足你的需求,想要自己開發一些好玩新奇的功能,則可以安裝開發版。
接下來我們分別介紹這兩個版本的安裝方式。
普通版安裝
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
略(相信這一定不會難道小天才的你 ?)
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 documents
try {
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 documents
try {
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 documents
try {
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 MongoClient
const 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 documents
try {
return await collection
.find({
status: 0
})
.toArray();
} catch (err) {
console.log(err);
}
}
// 更新
async function update(db, { guid }) {
const collection = db.collection(collectionName);
// Update some documents
try {
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 }) // 記得修改喲?
.set('Accept', 'application/json');
}
(async () => {
// Create a new MongoClient
const 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
的簡單應用,最近還有一個 餓了麼外賣推送
的想法,就是根據商家的滿減優惠計算出 最優套餐
,但是礙於演算法的問題,暫時卡在了這一塊。如果你還有什麼其他想法歡迎一起交流~
最後,送諸位一句 大膽假設,小心求證,人人都是科學家?
,歡迎曬出你的 idea!
文 / lastSeries
作者也在掘金哦,快關注他吧!
編 / 熒聲
本文由創宇前端作者授權釋出,版權屬於作者,創宇前端出品。 歡迎註明出處轉載本文。文章連結:原文連結
想要訂閱更多來自知道創宇開發一線的分享,請搜尋關注我們的微信公眾號:創宇前端(KnownsecFED)。歡迎留言討論,我們會盡可能回覆。
感謝您的閱讀。