2019 前端自嗨 coolq 篇 -- 技术文章推送

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

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

突然脑子里闪过一道光 :zap:️,卧槽牛逼呀,我也要玩

coolq what fuck

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

以下是 百度百科coolq 的定义

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

突然发现 coolq 好牛逼,讲道理 我只是使用了 cooql 消息推送的功能 :flushed:

技术文章来源

如果让你来搞,你会怎么办呢?你可能会想到 爬虫,可以爬页面,也可以爬接口。。。我这里选用的是 rss 。你在说什么? rss 什么鬼,我怎么没听说过,难道是一门新的技术?NORSS 简介

问题来了,不是所有的网站都提供 rss 服务,比如说 掘金 ,那么问题来了,那我怎么使用呢?在这里给大家安利一波RSSHub,它为我这种懒人提供了福利,如果里面没有找到你想要的内容,那么很抱歉只能自己手撕代码了

在继续阅读之前,你最好能够 了解一点 Mongodb 的相关知识,了解一点 Docker 的相关知识。如果你和和我一样是个菜鸡,问题也不是很大

实操 (Practical operation)

1. 安装 coolq

这里有一点不得不提,由于 coolq 官网 只提供 windows 版本的,因此 如果想要在 Linux / MacOS 系统上安装 官方 推荐的是通过 Docker 安装对应的镜像文件。(2019 年了,如果你还不会 Docker 你就 out 了,有些知识不深可以,但是广一点是没有任何毛病的 )

如果默认的功能不能满足你的需求,想要自己开发一些好玩新奇的功能,则需要安装 开发版

  1. 获取镜像
docker pull coolq/wine-coolq
复制代码
  1. 创建文件夹,用于存放 coolq 持久化数据
# 任意路径均可
mkdir /root/coolq-data
复制代码
  1. 运行镜像
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. 启动 coolq

打开浏览器 输入localhost:9000

点击 connect 输入 默认密码 MAX8char

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

  1. 获取镜像
docker pull richardchien/cqhttp:latest
复制代码
  1. 创建文件夹,用于存放 coolq 持久化数据

  2. 运行镜像

docker run -ti --rm --name cqhttp -p 9000:9000 -p 5700:5700 -v /root/coolq-data:/home/user/coolq richardchien/cqhttp
复制代码
  1. 启动 coolq

2. 安装 mongodb

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

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 }) // 记得修改哟:blush:
    .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);
  }
})();
复制代码
我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章