feat: v1.1.4
This commit is contained in:
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
.env
|
||||
.prettierignore
|
||||
.prettierrc.js
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
.env
|
6
.prettierignore
Normal file
6
.prettierignore
Normal file
@ -0,0 +1,6 @@
|
||||
# Ignore artifacts:
|
||||
build
|
||||
coverage
|
||||
|
||||
# Ignore all HTML files:
|
||||
*.html
|
26
.prettierrc.js
Normal file
26
.prettierrc.js
Normal file
@ -0,0 +1,26 @@
|
||||
//此处的规则供参考,其中多半其实都是默认值,可以根据个人习惯改写
|
||||
module.exports = {
|
||||
printWidth: 80, //单行长度
|
||||
tabWidth: 2, //缩进长度
|
||||
useTabs: false, //使用空格代替tab缩进
|
||||
semi: true, //句末使用分号
|
||||
singleQuote: true, //使用单引号
|
||||
quoteProps: 'as-needed', //仅在必需时为对象的key添加引号
|
||||
jsxSingleQuote: true, // jsx中使用单引号
|
||||
trailingComma: 'all', //多行时尽可能打印尾随逗号
|
||||
bracketSpacing: true, //在对象前后添加空格-eg: { foo: bar }
|
||||
jsxBracketSameLine: true, //多属性html标签的‘>’折行放置
|
||||
arrowParens: 'always', //单参数箭头函数参数周围使用圆括号-eg: (x) => x
|
||||
requirePragma: false, //无需顶部注释即可格式化
|
||||
insertPragma: false, //在已被preitter格式化的文件顶部加上标注
|
||||
proseWrap: 'preserve', //不知道怎么翻译
|
||||
htmlWhitespaceSensitivity: 'ignore', //对HTML全局空白不敏感
|
||||
vueIndentScriptAndStyle: false, //不对vue中的script及style标签缩进
|
||||
endOfLine: 'lf', //结束行形式
|
||||
embeddedLanguageFormatting: 'auto', //对引用代码进行格式化
|
||||
};
|
||||
|
||||
// 作者:星始流年
|
||||
// 链接:https://juejin.cn/post/6938687606687432740
|
||||
// 来源:稀土掘金
|
||||
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@ -0,0 +1,13 @@
|
||||
FROM node:18-bullseye as dep-builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD [ "node", "app.js" ]
|
54
app.js
Normal file
54
app.js
Normal file
@ -0,0 +1,54 @@
|
||||
const fs = require('fs');
|
||||
const { join } = require('path');
|
||||
const CreateBot = require('./bot');
|
||||
const CreateWebhookServer = require('./http');
|
||||
const logger = require('./utils/logger');
|
||||
|
||||
let retryCount = 0;
|
||||
|
||||
(async function start(port) {
|
||||
if (retryCount >= 5) {
|
||||
logger.warning('重试次数已达上限,请联系管理员重新启动本服务');
|
||||
return;
|
||||
}
|
||||
|
||||
logger('start server!!');
|
||||
const bot = new CreateBot();
|
||||
|
||||
logger('bot 连接中...');
|
||||
await bot
|
||||
.open({
|
||||
baseUrl: process.env.MIRAI_HTTP_API_HOST,
|
||||
verifyKey: process.env.MIRAI_HTTP_API_VERIFY_KEY,
|
||||
qq: process.env.QQ,
|
||||
})
|
||||
.catch((e) => {
|
||||
retryCount++;
|
||||
logger.error(`bot 连接失败,${e}。正在重试, 重试次数 ${retryCount}`);
|
||||
|
||||
setTimeout(() => {
|
||||
start();
|
||||
}, 5000);
|
||||
return Promise.reject();
|
||||
});
|
||||
logger('bot 连接成功!!');
|
||||
|
||||
logger('开启 webhook 服务器');
|
||||
const webhook = new CreateWebhookServer();
|
||||
|
||||
logger('开始引入handler函数');
|
||||
const files = fs.readdirSync('./handlers');
|
||||
const handlers = files
|
||||
.filter((it) => /\.js$/.test(it))
|
||||
.map((it) => {
|
||||
let fPath = join(__dirname, './handlers', it);
|
||||
return {
|
||||
event: it.split('.').slice(0, -1).join('.'),
|
||||
handler: require(fPath).bind(this, bot),
|
||||
};
|
||||
});
|
||||
webhook.registerHanlder(handlers);
|
||||
|
||||
webhook.startListen(port);
|
||||
logger(`开始监听端口: ${port}`);
|
||||
})(process.env.WEB_HOOK_PORT);
|
56
bot/index.js
Normal file
56
bot/index.js
Normal file
@ -0,0 +1,56 @@
|
||||
const { Bot } = require('mirai-js');
|
||||
const Queue = require('../utils/queue');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
class CreateBot {
|
||||
constructor() {
|
||||
this.bot = new Bot();
|
||||
this.queue = new Queue();
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
async open(config) {
|
||||
logger(`开始连接 mirai: host: ${config.baseUrl}, qq: ${config.qq}`);
|
||||
await this.bot.open({
|
||||
baseUrl: config.baseUrl,
|
||||
verifyKey: config.verifyKey,
|
||||
qq: config.qq,
|
||||
});
|
||||
}
|
||||
|
||||
async sendMessageToFriend(qq, message) {
|
||||
logger(`发送好友[${qq}]消息进入消息队列`);
|
||||
return this.queue
|
||||
.addMethod(this.bot.sendMessage.bind(this.bot, { friend: qq, message }))
|
||||
.then(
|
||||
(res) => {
|
||||
logger(`发送好友[${qq}]消息成功 ${res}`);
|
||||
return res;
|
||||
},
|
||||
(e) => {
|
||||
logger.warning(`发送好友[${qq}]消息失败,错误信息${e}`);
|
||||
return Promise.reject(e);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async sendMessageToGroup(groupId, message) {
|
||||
logger(`发送群[${groupId}]消息进入消息队列`);
|
||||
return this.queue
|
||||
.addMethod(
|
||||
this.bot.sendMessage.bind(this.bot, { group: groupId, message }),
|
||||
)
|
||||
.then(
|
||||
(res) => {
|
||||
logger(`发送群[${groupId}]消息成功 ${res}`);
|
||||
return res;
|
||||
},
|
||||
(e) => {
|
||||
logger.warning(`发送群[${groupId}]消息失败,错误信息${e}`);
|
||||
return Promise.reject(e);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CreateBot;
|
10
config/index.js
Normal file
10
config/index.js
Normal file
@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
defaultSubs: {
|
||||
groups: process.env.DEFAULT_SUB_GROUPS
|
||||
? process.env.DEFAULT_SUB_GROUPS.split(',')
|
||||
: [],
|
||||
users: process.env.DEFAULT_SUB_USERS
|
||||
? process.env.DEFAULT_SUB_USERS.split(',')
|
||||
: [],
|
||||
},
|
||||
};
|
64
handlers/sendForwardMessage.js
Normal file
64
handlers/sendForwardMessage.js
Normal file
@ -0,0 +1,64 @@
|
||||
const { Message } = require('mirai-js');
|
||||
const { defaultSubs } = require('../config');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
module.exports = function sendForwardMessage(bot, data) {
|
||||
logger('开始执行handler: sendForwardMessage');
|
||||
const { from, messages, subs } = data;
|
||||
const subscriptions = subs || defaultSubs;
|
||||
const { groups, users } = subscriptions;
|
||||
|
||||
// 创建转发信息
|
||||
const forwardMsgContent = Message.createForwardMessage();
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
const { message, imgUrls, originUrl } = messages[i];
|
||||
const msgContent = new Message();
|
||||
// 依次添加文本消息
|
||||
if (message) {
|
||||
Array.isArray(message)
|
||||
? message.forEach((message) => msgContent.addText(`${message}\n`))
|
||||
: msgContent.addText(`${message}\n`);
|
||||
}
|
||||
// 添加图片消息
|
||||
if (imgUrls) {
|
||||
Array.isArray(imgUrls)
|
||||
? imgUrls
|
||||
.slice(0, process.env.IMG_NUMBER_IN_ONE_MESSAGE || 1)
|
||||
.forEach((url) => msgContent.addImageUrl(url))
|
||||
: msgContent.addImageUrl(imgUrls);
|
||||
}
|
||||
// 添加来源地址
|
||||
if (originUrl) {
|
||||
msgContent.addText(`\n点击查看详情:${originUrl}`);
|
||||
}
|
||||
forwardMsgContent.addForwardNode({
|
||||
senderId: process.env.QQ,
|
||||
time: 0,
|
||||
senderName: process.env.FORWARD_SENDER_NAME || '莉娜·模儿',
|
||||
messageChain: msgContent,
|
||||
});
|
||||
}
|
||||
|
||||
Array.isArray(groups) &&
|
||||
groups.forEach((groupId) => {
|
||||
// 添加消息来源
|
||||
if (from) {
|
||||
bot.sendMessageToGroup(
|
||||
groupId,
|
||||
new Message().addText(`${from}更新啦!快来看吧。`),
|
||||
);
|
||||
}
|
||||
bot.sendMessageToGroup(groupId, forwardMsgContent);
|
||||
});
|
||||
Array.isArray(users) &&
|
||||
users.forEach((qq) => {
|
||||
// 添加消息来源
|
||||
if (from) {
|
||||
bot.sendMessageToFriend(
|
||||
qq,
|
||||
new Message().addText(`${from}更新啦!快来看吧。`),
|
||||
);
|
||||
}
|
||||
bot.sendMessageToFriend(qq, forwardMsgContent);
|
||||
});
|
||||
};
|
22
handlers/sendMessage.js
Normal file
22
handlers/sendMessage.js
Normal file
@ -0,0 +1,22 @@
|
||||
const { Message } = require('mirai-js');
|
||||
const { defaultSubs } = require('../config');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
// 方法已废弃
|
||||
module.exports = function sendMessage(bot, data) {
|
||||
logger('开始执行handler: sendMessage');
|
||||
const { message, imgUrl } = data;
|
||||
const subscriptions = defaultSubs;
|
||||
const { groups, users } = subscriptions;
|
||||
const msg = new Message().addText(message);
|
||||
if (imgUrl) {
|
||||
msg.addImageUrl(imgUrl);
|
||||
}
|
||||
|
||||
groups.forEach((groupId) => {
|
||||
bot.sendMessageToGroup(groupId, msg);
|
||||
});
|
||||
users.forEach((qq) => {
|
||||
bot.sendMessageToFriend(qq, msg);
|
||||
});
|
||||
};
|
49
handlers/sendMessage2.js
Normal file
49
handlers/sendMessage2.js
Normal file
@ -0,0 +1,49 @@
|
||||
const { Message } = require('mirai-js');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
module.exports = function sendMessage2(bot, data) {
|
||||
logger('开始执行handler: sendMessage2');
|
||||
const { from, messages, imgUrls, subs, originUrl, at } = data;
|
||||
const subscriptions = subs || defaultSubs;
|
||||
const { groups, users } = subscriptions;
|
||||
const msgContent = new Message();
|
||||
// 添加@信息
|
||||
if (at) {
|
||||
if (at === 'all') {
|
||||
msgContent.addAtAll();
|
||||
} else if (Array.isArray(at)) {
|
||||
at.forEach((qq) => msgContent.addAt(qq));
|
||||
}
|
||||
}
|
||||
// 添加消息来源
|
||||
if (from) {
|
||||
msgContent.addText(`${from}\n`);
|
||||
}
|
||||
// 依次添加文本消息
|
||||
if (messages) {
|
||||
Array.isArray(messages)
|
||||
? messages.forEach((message) => msgContent.addText(`${message}\n`))
|
||||
: msgContent.addText(messages);
|
||||
}
|
||||
// 添加图片消息
|
||||
if (imgUrls) {
|
||||
Array.isArray(imgUrls)
|
||||
? imgUrls
|
||||
.slice(0, process.env.IMG_NUMBER_IN_ONE_MESSAGE || 1)
|
||||
.forEach((url) => msgContent.addImageUrl(url))
|
||||
: msgContent.addImageUrl(imgUrls);
|
||||
}
|
||||
// 添加来源地址
|
||||
if (originUrl) {
|
||||
msgContent.addText(`点击查看详情:${originUrl}`);
|
||||
}
|
||||
|
||||
Array.isArray(groups) &&
|
||||
groups.forEach((groupId) => {
|
||||
bot.sendMessageToGroup(groupId, msgContent);
|
||||
});
|
||||
Array.isArray(users) &&
|
||||
users.forEach((qq) => {
|
||||
bot.sendMessageToFriend(qq, msgContent);
|
||||
});
|
||||
};
|
60
http/index.js
Normal file
60
http/index.js
Normal file
@ -0,0 +1,60 @@
|
||||
const http = require('http');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
class CreateWebhookServer {
|
||||
constructor() {
|
||||
this.http = null;
|
||||
this.handlers = [];
|
||||
}
|
||||
|
||||
startListen(port) {
|
||||
this.http = http
|
||||
.createServer((request, response) => {
|
||||
const { url, method } = request;
|
||||
logger(`监听到请求:${url}, 方法: ${method}`);
|
||||
if (method.toLowerCase() !== 'post') return;
|
||||
let body = '';
|
||||
request
|
||||
.on('error', (err) => {
|
||||
console.error(err);
|
||||
})
|
||||
.on('data', (chunk) => {
|
||||
body += chunk;
|
||||
})
|
||||
.on('end', () => {
|
||||
try {
|
||||
const jsonData = JSON.parse(body);
|
||||
Promise.all(
|
||||
this.handlers.map((val) =>
|
||||
jsonData.event === val.event
|
||||
? val.handler(jsonData)
|
||||
: Promise.resolve(),
|
||||
),
|
||||
)
|
||||
.then(() => {
|
||||
response.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
response.write('Hello World');
|
||||
response.end();
|
||||
})
|
||||
.catch((e) => {
|
||||
response.writeHead(405, { 'Content-Type': 'text/plain' });
|
||||
response.write(e);
|
||||
response.end();
|
||||
});
|
||||
} catch (e) {
|
||||
response.writeHead(405, { 'Content-Type': 'text/plain' });
|
||||
response.write(e);
|
||||
response.end();
|
||||
}
|
||||
});
|
||||
})
|
||||
.listen(port || 8080);
|
||||
}
|
||||
|
||||
registerHanlder(handlers) {
|
||||
logger(`${handlers.map((item) => item.event).join('、')}函数已引入`);
|
||||
this.handlers.push(...handlers);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CreateWebhookServer;
|
149
package-lock.json
generated
Normal file
149
package-lock.json
generated
Normal file
@ -0,0 +1,149 @@
|
||||
{
|
||||
"name": "mirai-middle-server",
|
||||
"version": "1.1.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mirai-middle-server",
|
||||
"version": "1.1.4",
|
||||
"dependencies": {
|
||||
"dayjs": "^1.11.7",
|
||||
"mirai-js": "^2.8.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dotenv": "^16.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.4"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.7",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
|
||||
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.1.tgz",
|
||||
"integrity": "sha512-UGmzIqXU/4b6Vb3R1Vrfd/4vGgVlB+mO+vEixOdfRhLeppkyW2BMhuK7TL8d0el+q9c4lW9qK2wZYhNLFhXYLA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/motdotla/dotenv?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
||||
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mirai-js": {
|
||||
"version": "2.8.11",
|
||||
"resolved": "https://registry.npmjs.org/mirai-js/-/mirai-js-2.8.11.tgz",
|
||||
"integrity": "sha512-oon2wxi3EEFyGG45ss/Zhx24wv+6WcFQJ3Hx0MAQFj8dZTrf+v39Nm4+KCvjDAllogPJmRVmF21laCh/ISdLmw==",
|
||||
"dependencies": {
|
||||
"axios": "^0.24.0",
|
||||
"form-data": "^3.0.1",
|
||||
"ws": "^8.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.13.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
|
||||
"integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "mirai-middle-server",
|
||||
"version": "1.1.4",
|
||||
"description": "使用miraijs开发,用于连接kuginn等外部服务与mirai通信的中转服务器",
|
||||
"author": "mol",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"dev": "node start.js",
|
||||
"start": "node app.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"dayjs": "^1.11.7",
|
||||
"mirai-js": "^2.8.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dotenv": "^16.1.1"
|
||||
}
|
||||
}
|
4
start.js
Normal file
4
start.js
Normal file
@ -0,0 +1,4 @@
|
||||
const dotenv = require('dotenv');
|
||||
dotenv.config();
|
||||
|
||||
require('./app');
|
25
utils/logger.js
Normal file
25
utils/logger.js
Normal file
@ -0,0 +1,25 @@
|
||||
const dayjs = require('dayjs');
|
||||
|
||||
function info(message) {
|
||||
console.log(`${dayjs().format('YYYY-MM-DD hh:mm:ss')}【消息】${message}`);
|
||||
}
|
||||
|
||||
function warning(message) {
|
||||
console.log(`${dayjs().format('YYYY-MM-DD hh:mm:ss')}【警告】${message}`);
|
||||
}
|
||||
|
||||
function error(message) {
|
||||
console.log(`${dayjs().format('YYYY-MM-DD hh:mm:ss')}【错误】${message}`);
|
||||
}
|
||||
|
||||
function logger(message) {
|
||||
info(message);
|
||||
}
|
||||
|
||||
logger.prototype.warning = warning;
|
||||
|
||||
logger.prototype.info = info;
|
||||
|
||||
logger.prototype.error = error;
|
||||
|
||||
module.exports = logger;
|
34
utils/queue.js
Normal file
34
utils/queue.js
Normal file
@ -0,0 +1,34 @@
|
||||
module.exports = class Queue {
|
||||
constructor() {
|
||||
this.queue = [];
|
||||
}
|
||||
|
||||
addMethod(method) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.queue.push({ method, resolve, reject });
|
||||
|
||||
if (this.queue.length === 1) {
|
||||
this.executeNext();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async executeNext() {
|
||||
const { method, resolve, reject } = this.queue[0];
|
||||
|
||||
try {
|
||||
const result = await method();
|
||||
resolve(result);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
|
||||
this.queue.shift();
|
||||
|
||||
if (this.queue.length > 0) {
|
||||
setTimeout(() => {
|
||||
this.executeNext();
|
||||
}, Math.random() * 1000 + 500);
|
||||
}
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user