本教程将指导您安装和认识 Nodejs ,并部署机器人。
让我们从认识 NodeJS 开始,Node.js 是一个免费、开源、跨平台的 JavaScript 运行时环境 它允许开发人员创建服务器、Web 应用程序、命令行工具和脚本。
可以从这里下载 Nodejs: Node.js — Download Node.js®
选择自己的系统配置,然后复制命令并执行
安装我自己写的两个轮子:
- NoHope NodeLoc Session 管理
- Message Bus Client 长轮询客户端
这里是一个完整的项目文件,包括了上面两个轮子以及一个示范代码
nlbot.zip (5.8 KB)
下载后请解压,然后你会看见三个文件
- chat.js 示范文件
- message-bus-client.js 轮子
- nohope_nodeloc.js 轮子 免责声明:这不是内涵 Nodeloc 无望(而是这个项目),我最近的项目命名风格都很独特
然后安装 node-fetch 依赖库 1.5.2 版本
npm i [email protected]
之后我们编辑 chat.js 文件内容,转到第 63 行,设置自己的用户名和密码,然后保存
最后我们打开控制台执行 node chat.js
,你应该会看见下面内容
正在导入库
正在启动 NoHope
正在启动 MsgBus
就绪
这说明你成功启动了服务!试试打开论坛的吹水群,发送 签到
,此时你会发现自己反应了
测试发现正常后,先按 Ctrl + C 终止脚本,然后安装 pm2
npm i pm2
之后我们使用 pm2 start chat
就可以把脚本放到后台运行,之后就可以美美哒关掉 SSH 睡觉去了~
然后隔天就发现bot不工作了
写完才发现跑题了,题目是 【教程】用 Node.js 在 Nodeloc 编写机器人
而不是 【教程】部署一个在吹水群遇到有人发 签到 就自动🈲的机器人
那我随便写点那两轮子的教程吧,其实就算我写了那两轮子,实际上编写机器人还是有点复杂的,而且石山(
NoHope NodeLoc
const NoHope = require('./nohope_nodeloc');
const client = new NoHope({
baseUrl: 'https://nodeloc.cc', // 要登录的论坛
// forceIP: 'xx.xxx.xxx.xx', // SNI直接连接源站用的,你用不到,用于跳cf盾
login: {
username: 'James', // 你的账号
password: 'ilove4n0n4me' // 你的密码
}
});
async function main() {
await client.init(); // 初始化客户端
/* 现在你可以用 client._fetch 愉快的访问 Nodeloc 了,但是注意 url 格式:
* 必须是相对路径
* 使用 : 替代 .
* 使用 . 替代 /
*
* 比如 https://nodeloc.cc/chat/api/me/channels 转换为 chat.api.me.channels
* https://nodeloc.cc/session/passkey/challenge.json 转换为 session.passkey.challenge:json
*/
// 这个时候就有人说了这b东西相当于在 fetch 外面套了路径翻译壳,你说得对 :) (实际上还是会自动处理csrf和cookie,以及自动登录)
}
main();
Message Bus
const MsgBus = require('./message-bus-client');
async function main() {
const bus = new MsgBus('https://nodeloc.cc', {
retryDelay: 0,
pollTimeout: 60000
});
// 获取最新消息id
let reqInfo = await client._fetch('chat.api.me.channels', { // 这里就要求了必须和 Nohope NodeLoc 搭配使用(强耦合了)。被资本 Discourse 做局了,要登录才可以访问这个api
"method": "GET",
});
let infoData = await reqInfo.json();
let chat_id = infoData.public_channels[0].last_message.chat_channel_id; // 获取第一个群的 ID
let msg_id = infoData.public_channels[0].meta.message_bus_last_ids.channel_message_bus_last_id; // 获取第一个群的最后一条消息的 ID
// 你问我为什么这么做?为什么不把这个获取id也封装了?去问 Discourse 的开发者怎么想的去 :(
// 订阅吹水群
bus.subscribe('/chat/' + chat_id, msg_id);
bus.on('/chat/' + chat_id, async (data) => {
let msg = data.chat_message;
if (!msg || data.type !== 'processed') return; // 你问我为什么这么做?问 Discourse 的开发者怎么想的去
console.log(msg); // 打印消息到控制台
}, msg_id);
// 开始轮询
bus.start();
}
main();
关于CSRF令牌刷新问题,是缓存60s就换(主要是这个csrf刷新速度我也拿不定主意),100%不因为csrf无效而失败。
至于 MsgBus 为什么要手动获取 id,这相当于 MsgBus 库是 tcp,然而这里在用 http,非常垃圾对吧 。(实际上是因为这个id的获取方法的格式每个组件不太一样,没法封装【也可能我是傻逼找不到规律】,能用就行)
总结下来被资本 Discourse 做局了很狗屎,技术债多的一批,但是没办法啊,api就这样子,有没有大佬能重构(
都只要一个 node-fetch 依赖了,这么轻量的库还要什么飞机 (笑) 如果真有人用我这东西开发企业级应用那我考虑考虑重构。
粗糙但实用的轮子,如果你觉得不好用宁可自己面对神人Discourse逻辑写轮子,那您nb。
(Discourse的神奇思路真让人想不懂,论坛只支持新版浏览器浏览但死活不用websocket,还在用古老的长轮询,要是Discourse支持旧浏览器来避免使用websocket我不说,但是tm的它不支持旧浏览器啊,我chrome 108 都显示很快将无法参与社区讨论)
补:如果官方有写轮子但是我没发现那我就成小丑了